lambda x : 1
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('File', data=Binary('lambda x: 1'), data_format=u'text/x-python',
+ data_encoding=u'ascii', data_name=u'toto.py')
+ from cubicweb import mttransforms
+ if mttransforms.HAS_PYGMENTS_TRANSFORMS:
+ import pygments
+ if tuple(int(i) for i in pygments.__version__.split('.')[:2]) >= (1, 3):
+ self.assertEqual(e.printable_value('data'),
+ '''''')
+ else:
+ self.assertEqual(e.printable_value('data'),
+ '''''')
else:
self.assertEqual(e.printable_value('data'),
- '''''')
- else:
- self.assertEqual(e.printable_value('data'),
- '''
-lambda x : 1
+ '''
+ lambda x : 1
''')
- e = req.create_entity('File', data=Binary('*héhéhé*'), data_format=u'text/rest',
- data_encoding=u'utf-8', data_name=u'toto.txt')
- self.assertEqual(e.printable_value('data'),
- u'héhéhé
')
+ e = req.create_entity('File', data=Binary('*héhéhé*'), data_format=u'text/rest',
+ data_encoding=u'utf-8', data_name=u'toto.txt')
+ self.assertEqual(e.printable_value('data'),
+ u'héhéhé
')
def test_printable_value_bad_html(self):
"""make sure we don't crash if we try to render invalid XHTML strings"""
- req = self.request()
- e = req.create_entity('Card', title=u'bad html', content=u'R&D
',
- content_format=u'text/html')
- tidy = lambda x: x.replace('\n', '')
- self.assertEqual(tidy(e.printable_value('content')),
- '
R&D
')
- e.cw_attr_cache['content'] = u'yo !! R&D
pas fermé'
- self.assertEqual(tidy(e.printable_value('content')),
- u'yo !! R&D
pas fermé
')
- e.cw_attr_cache['content'] = u'R&D'
- self.assertEqual(tidy(e.printable_value('content')), u'R&D')
- e.cw_attr_cache['content'] = u'R&D;'
- self.assertEqual(tidy(e.printable_value('content')), u'R&D;')
- e.cw_attr_cache['content'] = u'yo !! R&D
pas fermé'
- self.assertEqual(tidy(e.printable_value('content')),
- u'yo !! R&D
pas fermé
')
- e.cw_attr_cache['content'] = u'été
été'
- self.assertEqual(tidy(e.printable_value('content')),
- u'été
été
')
- e.cw_attr_cache['content'] = u'C'est un exemple sérieux'
- self.assertEqual(tidy(e.printable_value('content')),
- u"C'est un exemple sérieux")
- # make sure valid xhtml is left untouched
- e.cw_attr_cache['content'] = u'
R&D
'
- self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
- e.cw_attr_cache['content'] = u'
été
'
- self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
- e.cw_attr_cache['content'] = u'été'
- self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
- e.cw_attr_cache['content'] = u'hop\r\nhop\nhip\rmomo'
- self.assertEqual(e.printable_value('content'), u'hop\nhop\nhip\nmomo')
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Card', title=u'bad html', content=u'
R&D
',
+ content_format=u'text/html')
+ tidy = lambda x: x.replace('\n', '')
+ self.assertEqual(tidy(e.printable_value('content')),
+ '
R&D
')
+ e.cw_attr_cache['content'] = u'yo !! R&D
pas fermé'
+ self.assertEqual(tidy(e.printable_value('content')),
+ u'yo !! R&D
pas fermé
')
+ e.cw_attr_cache['content'] = u'R&D'
+ self.assertEqual(tidy(e.printable_value('content')), u'R&D')
+ e.cw_attr_cache['content'] = u'R&D;'
+ self.assertEqual(tidy(e.printable_value('content')), u'R&D;')
+ e.cw_attr_cache['content'] = u'yo !! R&D
pas fermé'
+ self.assertEqual(tidy(e.printable_value('content')),
+ u'yo !! R&D
pas fermé
')
+ e.cw_attr_cache['content'] = u'été
été'
+ self.assertEqual(tidy(e.printable_value('content')),
+ u'été
été
')
+ e.cw_attr_cache['content'] = u'C'est un exemple sérieux'
+ self.assertEqual(tidy(e.printable_value('content')),
+ u"C'est un exemple sérieux")
+ # make sure valid xhtml is left untouched
+ e.cw_attr_cache['content'] = u'
R&D
'
+ self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
+ e.cw_attr_cache['content'] = u'
été
'
+ self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
+ e.cw_attr_cache['content'] = u'été'
+ self.assertEqual(e.printable_value('content'), e.cw_attr_cache['content'])
+ e.cw_attr_cache['content'] = u'hop\r\nhop\nhip\rmomo'
+ self.assertEqual(e.printable_value('content'), u'hop\nhop\nhip\nmomo')
def test_printable_value_bad_html_ms(self):
- req = self.request()
- e = req.create_entity('Card', title=u'bad html', content=u'
R&D
',
- content_format=u'text/html')
- tidy = lambda x: x.replace('\n', '')
- e.cw_attr_cache['content'] = u'
ms orifice produces weird html
'
- # Caution! current implementation of soup2xhtml strips first div element
- content = soup2xhtml(e.printable_value('content'), 'utf-8')
- self.assertMultiLineEqual(content, u'
ms orifice produces weird html
')
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Card', title=u'bad html', content=u'
R&D
',
+ content_format=u'text/html')
+ tidy = lambda x: x.replace('\n', '')
+ e.cw_attr_cache['content'] = u'
ms orifice produces weird html
'
+ # Caution! current implementation of soup2xhtml strips first div element
+ content = soup2xhtml(e.printable_value('content'), 'utf-8')
+ self.assertMultiLineEqual(content, u'
ms orifice produces weird html
')
def test_fulltextindex(self):
- e = self.vreg['etypes'].etype_class('File')(self.request())
- e.cw_attr_cache['description'] = 'du
html '
- e.cw_attr_cache['description_format'] = 'text/html'
- e.cw_attr_cache['data'] = Binary('some
data ')
- e.cw_attr_cache['data_name'] = 'an html file'
- e.cw_attr_cache['data_format'] = 'text/html'
- e.cw_attr_cache['data_encoding'] = 'ascii'
- e._cw.transaction_data = {} # XXX req should be a session
- words = e.cw_adapt_to('IFTIndexable').get_words()
- words['C'].sort()
- self.assertEqual({'C': sorted(['an', 'html', 'file', 'du', 'html', 'some', 'data'])},
- words)
+ with self.admin_access.web_request() as req:
+ e = self.vreg['etypes'].etype_class('File')(req)
+ e.cw_attr_cache['description'] = 'du
html '
+ e.cw_attr_cache['description_format'] = 'text/html'
+ e.cw_attr_cache['data'] = Binary('some
data ')
+ e.cw_attr_cache['data_name'] = 'an html file'
+ e.cw_attr_cache['data_format'] = 'text/html'
+ e.cw_attr_cache['data_encoding'] = 'ascii'
+ e._cw.transaction_data.clear()
+ words = e.cw_adapt_to('IFTIndexable').get_words()
+ words['C'].sort()
+ self.assertEqual({'C': sorted(['an', 'html', 'file', 'du', 'html', 'some', 'data'])},
+ words)
def test_nonregr_relation_cache(self):
- req = self.request()
- p1 = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
- p2 = req.create_entity('Personne', nom=u'toto')
- self.execute('SET X evaluee Y WHERE X nom "di mascio", Y nom "toto"')
- self.assertEqual(p1.evaluee[0].nom, "toto")
- self.assertTrue(not p1.reverse_evaluee)
+ with self.admin_access.web_request() as req:
+ p1 = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
+ p2 = req.create_entity('Personne', nom=u'toto')
+ req.execute('SET X evaluee Y WHERE X nom "di mascio", Y nom "toto"')
+ self.assertEqual(p1.evaluee[0].nom, "toto")
+ self.assertFalse(p1.reverse_evaluee)
def test_complete_relation(self):
- session = self.session
- eid = session.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 = self.execute('Any X WHERE X eid %(x)s', {'x': eid}).get_entity(0, 0)
- trinfo.complete()
- self.assertTrue(isinstance(trinfo.cw_attr_cache['creation_date'], datetime))
- self.assertTrue(trinfo.cw_relation_cached('from_state', 'subject'))
- self.assertTrue(trinfo.cw_relation_cached('to_state', 'subject'))
- self.assertTrue(trinfo.cw_relation_cached('wf_info_for', 'subject'))
- self.assertEqual(trinfo.by_transition, ())
+ 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 = 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'))
+ self.assertTrue(trinfo.cw_relation_cached('to_state', 'subject'))
+ self.assertTrue(trinfo.cw_relation_cached('wf_info_for', 'subject'))
+ self.assertEqual(trinfo.by_transition, ())
def test_request_cache(self):
- req = self.request()
- user = self.execute('CWUser X WHERE X login "admin"', req=req).get_entity(0, 0)
- state = user.in_state[0]
- samestate = self.execute('State X WHERE X name "activated"', req=req).get_entity(0, 0)
- self.assertTrue(state is samestate)
+ with self.admin_access.web_request() as req:
+ user = req.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
+ state = user.in_state[0]
+ samestate = req.execute('State X WHERE X name "activated"').get_entity(0, 0)
+ self.assertIs(state, samestate)
def test_rest_path(self):
- req = self.request()
- note = req.create_entity('Note', type=u'z')
- self.assertEqual(note.rest_path(), 'note/%s' % note.eid)
- # unique attr
- tag = req.create_entity('Tag', name=u'x')
- self.assertEqual(tag.rest_path(), 'tag/x')
- # test explicit rest_attr
- person = req.create_entity('Personne', prenom=u'john', nom=u'doe')
- self.assertEqual(person.rest_path(), 'personne/doe')
- # ambiguity test
- person2 = req.create_entity('Personne', prenom=u'remi', nom=u'doe')
- person.cw_clear_all_caches()
- self.assertEqual(person.rest_path(), unicode(person.eid))
- self.assertEqual(person2.rest_path(), unicode(person2.eid))
- # unique attr with None value (nom in this case)
- friend = req.create_entity('Ami', prenom=u'bob')
- self.assertEqual(friend.rest_path(), unicode(friend.eid))
+ with self.admin_access.web_request() as req:
+ note = req.create_entity('Note', type=u'z')
+ self.assertEqual(note.rest_path(), 'note/%s' % note.eid)
+ # unique attr
+ tag = req.create_entity('Tag', name=u'x')
+ self.assertEqual(tag.rest_path(), 'tag/x')
+ # test explicit rest_attr
+ person = req.create_entity('Personne', prenom=u'john', nom=u'doe')
+ self.assertEqual(person.rest_path(), 'personne/doe')
+ # ambiguity test
+ person2 = req.create_entity('Personne', prenom=u'remi', nom=u'doe')
+ person.cw_clear_all_caches()
+ self.assertEqual(person.rest_path(), unicode(person.eid))
+ self.assertEqual(person2.rest_path(), unicode(person2.eid))
+ # unique attr with None value (nom in this case)
+ friend = req.create_entity('Ami', prenom=u'bob')
+ self.assertEqual(friend.rest_path(), unicode(friend.eid))
+ # 'ref' below is created without the unique but not required
+ # attribute, make sur that the unique _and_ required 'ean' is used
+ # as the rest attribute
+ ref = req.create_entity('Reference', ean=u'42-1337-42')
+ self.assertEqual(ref.rest_path(), 'reference/42-1337-42')
def test_can_use_rest_path(self):
self.assertTrue(can_use_rest_path(u'zobi'))
@@ -732,66 +768,66 @@
self.assertFalse(can_use_rest_path(u'zo?bi'))
def test_cw_set_attributes(self):
- req = self.request()
- person = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
- self.assertEqual(person.prenom, u'adrien')
- self.assertEqual(person.nom, u'di mascio')
- person.cw_set(prenom=u'sylvain', nom=u'thénault')
- person = self.execute('Personne P').get_entity(0, 0) # XXX retreival needed ?
- self.assertEqual(person.prenom, u'sylvain')
- self.assertEqual(person.nom, u'thénault')
+ with self.admin_access.web_request() as req:
+ person = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien')
+ self.assertEqual(person.prenom, u'adrien')
+ self.assertEqual(person.nom, u'di mascio')
+ person.cw_set(prenom=u'sylvain', nom=u'thénault')
+ person = req.execute('Personne P').get_entity(0, 0) # XXX retreival needed ?
+ self.assertEqual(person.prenom, u'sylvain')
+ self.assertEqual(person.nom, u'thénault')
def test_cw_set_relations(self):
- req = self.request()
- person = req.create_entity('Personne', nom=u'chauvat', prenom=u'nicolas')
- note = req.create_entity('Note', type=u'x')
- note.cw_set(ecrit_par=person)
- note = req.create_entity('Note', type=u'y')
- note.cw_set(ecrit_par=person.eid)
- self.assertEqual(len(person.reverse_ecrit_par), 2)
+ with self.admin_access.web_request() as req:
+ person = req.create_entity('Personne', nom=u'chauvat', prenom=u'nicolas')
+ note = req.create_entity('Note', type=u'x')
+ note.cw_set(ecrit_par=person)
+ note = req.create_entity('Note', type=u'y')
+ note.cw_set(ecrit_par=person.eid)
+ self.assertEqual(len(person.reverse_ecrit_par), 2)
def test_metainformation_and_external_absolute_url(self):
- req = self.request()
- note = req.create_entity('Note', type=u'z')
- metainf = note.cw_metainformation()
- self.assertEqual(metainf, {'source': {'type': 'native', 'uri': 'system',
- 'use-cwuri-as-url': False},
- 'type': u'Note', 'extid': None})
- self.assertEqual(note.absolute_url(), 'http://testing.fr/cubicweb/note/%s' % note.eid)
- metainf['source'] = metainf['source'].copy()
- metainf['source']['base-url'] = 'http://cubicweb2.com/'
- metainf['extid'] = 1234
- self.assertEqual(note.absolute_url(), 'http://cubicweb2.com/note/1234')
+ with self.admin_access.web_request() as req:
+ note = req.create_entity('Note', type=u'z')
+ metainf = note.cw_metainformation()
+ self.assertEqual(metainf, {'source': {'type': 'native', 'uri': 'system',
+ 'use-cwuri-as-url': False},
+ 'type': u'Note', 'extid': None})
+ self.assertEqual(note.absolute_url(), 'http://testing.fr/cubicweb/note/%s' % note.eid)
+ metainf['source'] = metainf['source'].copy()
+ metainf['source']['base-url'] = 'http://cubicweb2.com/'
+ metainf['extid'] = 1234
+ self.assertEqual(note.absolute_url(), 'http://cubicweb2.com/note/1234')
def test_absolute_url_empty_field(self):
- req = self.request()
- card = req.create_entity('Card', wikiid=u'', title=u'test')
- self.assertEqual(card.absolute_url(),
- 'http://testing.fr/cubicweb/%s' % card.eid)
+ with self.admin_access.web_request() as req:
+ card = req.create_entity('Card', wikiid=u'', title=u'test')
+ self.assertEqual(card.absolute_url(),
+ 'http://testing.fr/cubicweb/%s' % card.eid)
def test_create_and_compare_entity(self):
- req = self.request()
- p1 = req.create_entity('Personne', nom=u'fayolle', prenom=u'alexandre')
- p2 = req.create_entity('Personne', nom=u'campeas', prenom=u'aurelien')
- note = req.create_entity('Note', type=u'z')
- req = self.request()
- p = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien',
- connait=p1, evaluee=[p1, p2],
- reverse_ecrit_par=note)
- self.assertEqual(p.nom, 'di mascio')
- self.assertEqual([c.nom for c in p.connait], ['fayolle'])
- self.assertEqual(sorted([c.nom for c in p.evaluee]), ['campeas', 'fayolle'])
- self.assertEqual([c.type for c in p.reverse_ecrit_par], ['z'])
-
- req = self.request()
- auc = req.execute('Personne P WHERE P prenom "aurelien"').get_entity(0,0)
- persons = set()
- persons.add(p1)
- persons.add(p2)
- persons.add(auc)
- self.assertEqual(2, len(persons))
- self.assertNotEqual(p1, p2)
- self.assertEqual(p2, auc)
+ access = self.admin_access
+ with access.web_request() as req:
+ p1 = req.create_entity('Personne', nom=u'fayolle', prenom=u'alexandre')
+ p2 = req.create_entity('Personne', nom=u'campeas', prenom=u'aurelien')
+ note = req.create_entity('Note', type=u'z')
+ p = req.create_entity('Personne', nom=u'di mascio', prenom=u'adrien',
+ connait=p1, evaluee=[p1, p2],
+ reverse_ecrit_par=note)
+ self.assertEqual(p.nom, 'di mascio')
+ self.assertEqual([c.nom for c in p.connait], ['fayolle'])
+ self.assertEqual(sorted([c.nom for c in p.evaluee]), ['campeas', 'fayolle'])
+ self.assertEqual([c.type for c in p.reverse_ecrit_par], ['z'])
+ req.cnx.commit()
+ with access.web_request() as req:
+ auc = req.execute('Personne P WHERE P prenom "aurelien"').get_entity(0,0)
+ persons = set()
+ persons.add(p1)
+ persons.add(p2)
+ persons.add(auc)
+ self.assertEqual(2, len(persons))
+ self.assertNotEqual(p1, p2)
+ self.assertEqual(p2, auc)
if __name__ == '__main__':
diff -r 84738d495ffd -r 793377697c81 test/unittest_migration.py
--- a/test/unittest_migration.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_migration.py Wed Sep 24 18:04:30 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -76,7 +76,7 @@
def test_filter_scripts_for_mode(self):
config = CubicWebConfiguration('data')
config.verbosity = 0
- self.assert_(not isinstance(config.migration_handler(), ServerMigrationHelper))
+ self.assertNotIsInstance(config.migration_handler(), ServerMigrationHelper)
self.assertIsInstance(config.migration_handler(), MigrationHelper)
config = self.config
config.__class__.name = 'repository'
@@ -99,16 +99,15 @@
def test_db_creation(self):
"""make sure database can be created"""
config = ApptestConfiguration('data', apphome=self.datadir)
- source = config.sources()['system']
+ source = config.system_source_config
self.assertEqual(source['db-driver'], 'sqlite')
handler = get_test_db_handler(config)
handler.init_test_database()
handler.build_db_cache()
repo, cnx = handler.get_repo_and_cnx()
- cu = cnx.cursor()
- self.assertEqual(cu.execute('Any SN WHERE X is CWUser, X login "admin", X in_state S, S name SN').rows,
- [['activated']])
- cnx.close()
+ with cnx:
+ self.assertEqual(cnx.execute('Any SN WHERE X is CWUser, X login "admin", X in_state S, S name SN').rows,
+ [['activated']])
repo.shutdown()
if __name__ == '__main__':
diff -r 84738d495ffd -r 793377697c81 test/unittest_predicates.py
--- a/test/unittest_predicates.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_predicates.py Wed Sep 24 18:04:30 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.
@@ -18,7 +18,10 @@
"""unit tests for selectors mechanism"""
from operator import eq, lt, le, gt
+from contextlib import contextmanager
+
from logilab.common.testlib import TestCase, unittest_main
+from logilab.common.decorators import clear_cache
from cubicweb import Binary
from cubicweb.devtools.testlib import CubicWebTC
@@ -31,54 +34,39 @@
-class ImplementsSelectorTC(CubicWebTC):
+class ImplementsTC(CubicWebTC):
def test_etype_priority(self):
- req = self.request()
- f = req.create_entity('File', data_name=u'hop.txt', data=Binary('hop'))
- rset = f.as_rset()
- anyscore = is_instance('Any')(f.__class__, req, rset=rset)
- idownscore = adaptable('IDownloadable')(f.__class__, req, rset=rset)
- self.assertTrue(idownscore > anyscore, (idownscore, anyscore))
- filescore = is_instance('File')(f.__class__, req, rset=rset)
- self.assertTrue(filescore > idownscore, (filescore, idownscore))
+ with self.admin_access.web_request() as req:
+ f = req.create_entity('File', data_name=u'hop.txt', data=Binary('hop'))
+ rset = f.as_rset()
+ anyscore = is_instance('Any')(f.__class__, req, rset=rset)
+ idownscore = adaptable('IDownloadable')(f.__class__, req, rset=rset)
+ self.assertTrue(idownscore > anyscore, (idownscore, anyscore))
+ filescore = is_instance('File')(f.__class__, req, rset=rset)
+ self.assertTrue(filescore > idownscore, (filescore, idownscore))
def test_etype_inheritance_no_yams_inheritance(self):
cls = self.vreg['etypes'].etype_class('Personne')
- self.assertFalse(is_instance('Societe').score_class(cls, self.request()))
+ with self.admin_access.web_request() as req:
+ self.assertFalse(is_instance('Societe').score_class(cls, req))
def test_yams_inheritance(self):
cls = self.vreg['etypes'].etype_class('Transition')
- self.assertEqual(is_instance('BaseTransition').score_class(cls, self.request()),
- 3)
+ with self.admin_access.web_request() as req:
+ self.assertEqual(is_instance('BaseTransition').score_class(cls, req),
+ 3)
def test_outer_join(self):
- req = self.request()
- rset = req.execute('Any U,B WHERE B? bookmarked_by U, U login "anon"')
- self.assertEqual(is_instance('Bookmark')(None, req, rset=rset, row=0, col=1),
- 0)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any U,B WHERE B? bookmarked_by U, U login "anon"')
+ self.assertEqual(is_instance('Bookmark')(None, req, rset=rset, row=0, col=1),
+ 0)
class WorkflowSelectorTC(CubicWebTC):
- def _commit(self):
- self.commit()
- self.wf_entity.cw_clear_all_caches()
-
- def setup_database(self):
- wf = self.shell().add_workflow("wf_test", 'StateFull', default=True)
- created = wf.add_state('created', initial=True)
- validated = wf.add_state('validated')
- abandoned = wf.add_state('abandoned')
- wf.add_transition('validate', created, validated, ('managers',))
- wf.add_transition('forsake', (created, validated,), abandoned, ('managers',))
def setUp(self):
super(WorkflowSelectorTC, self).setUp()
- self.req = self.request()
- self.wf_entity = self.req.create_entity('StateFull', name=u'')
- self.rset = self.wf_entity.as_rset()
- self.adapter = self.wf_entity.cw_adapt_to('IWorkflowable')
- self._commit()
- self.assertEqual(self.adapter.state, 'created')
# enable debug mode to state/transition validation on the fly
self.vreg.config.debugmode = True
@@ -86,122 +74,154 @@
self.vreg.config.debugmode = False
super(WorkflowSelectorTC, self).tearDown()
+ def setup_database(self):
+ with self.admin_access.shell() as shell:
+ wf = shell.add_workflow("wf_test", 'StateFull', default=True)
+ created = wf.add_state('created', initial=True)
+ validated = wf.add_state('validated')
+ abandoned = wf.add_state('abandoned')
+ wf.add_transition('validate', created, validated, ('managers',))
+ wf.add_transition('forsake', (created, validated,), abandoned, ('managers',))
+
+ @contextmanager
+ def statefull_stuff(self):
+ with self.admin_access.web_request() as req:
+ wf_entity = req.create_entity('StateFull', name=u'')
+ rset = wf_entity.as_rset()
+ adapter = wf_entity.cw_adapt_to('IWorkflowable')
+ req.cnx.commit()
+ self.assertEqual(adapter.state, 'created')
+ yield req, wf_entity, rset, adapter
+
def test_is_in_state(self):
- for state in ('created', 'validated', 'abandoned'):
- selector = is_in_state(state)
- self.assertEqual(selector(None, self.req, rset=self.rset),
- state=="created")
-
- self.adapter.fire_transition('validate')
- self._commit()
- self.assertEqual(self.adapter.state, 'validated')
+ with self.statefull_stuff() as (req, wf_entity, rset, adapter):
+ for state in ('created', 'validated', 'abandoned'):
+ selector = is_in_state(state)
+ self.assertEqual(selector(None, req, rset=rset),
+ state=="created")
- selector = is_in_state('created')
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- selector = is_in_state('validated')
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
- selector = is_in_state('validated', 'abandoned')
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
- selector = is_in_state('abandoned')
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
+ adapter.fire_transition('validate')
+ req.cnx.commit(); wf_entity.cw_clear_all_caches()
+ self.assertEqual(adapter.state, 'validated')
+
+ clear_cache(rset, 'get_entity')
+
+ selector = is_in_state('created')
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ selector = is_in_state('validated')
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ selector = is_in_state('validated', 'abandoned')
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ selector = is_in_state('abandoned')
+ self.assertEqual(selector(None, req, rset=rset), 0)
- self.adapter.fire_transition('forsake')
- self._commit()
- self.assertEqual(self.adapter.state, 'abandoned')
+ adapter.fire_transition('forsake')
+ req.cnx.commit(); wf_entity.cw_clear_all_caches()
+ self.assertEqual(adapter.state, 'abandoned')
+
+ clear_cache(rset, 'get_entity')
- selector = is_in_state('created')
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- selector = is_in_state('validated')
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- selector = is_in_state('validated', 'abandoned')
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
- self.assertEqual(self.adapter.state, 'abandoned')
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
+ selector = is_in_state('created')
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ selector = is_in_state('validated')
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ selector = is_in_state('validated', 'abandoned')
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ self.assertEqual(adapter.state, 'abandoned')
+ self.assertEqual(selector(None, req, rset=rset), 1)
def test_is_in_state_unvalid_names(self):
- selector = is_in_state("unknown")
- with self.assertRaises(ValueError) as cm:
- selector(None, self.req, rset=self.rset)
- self.assertEqual(str(cm.exception),
- "wf_test: unknown state(s): unknown")
- selector = is_in_state("weird", "unknown", "created", "weird")
- with self.assertRaises(ValueError) as cm:
- selector(None, self.req, rset=self.rset)
- self.assertEqual(str(cm.exception),
- "wf_test: unknown state(s): unknown,weird")
+ with self.statefull_stuff() as (req, wf_entity, rset, adapter):
+ selector = is_in_state("unknown")
+ with self.assertRaises(ValueError) as cm:
+ selector(None, req, rset=rset)
+ self.assertEqual(str(cm.exception),
+ "wf_test: unknown state(s): unknown")
+ selector = is_in_state("weird", "unknown", "created", "weird")
+ with self.assertRaises(ValueError) as cm:
+ selector(None, req, rset=rset)
+ self.assertEqual(str(cm.exception),
+ "wf_test: unknown state(s): unknown,weird")
def test_on_transition(self):
- for transition in ('validate', 'forsake'):
- selector = on_transition(transition)
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
+ with self.statefull_stuff() as (req, wf_entity, rset, adapter):
+ for transition in ('validate', 'forsake'):
+ selector = on_transition(transition)
+ self.assertEqual(selector(None, req, rset=rset), 0)
- self.adapter.fire_transition('validate')
- self._commit()
- self.assertEqual(self.adapter.state, 'validated')
+ adapter.fire_transition('validate')
+ req.cnx.commit(); wf_entity.cw_clear_all_caches()
+ self.assertEqual(adapter.state, 'validated')
+
+ clear_cache(rset, 'get_entity')
- selector = on_transition("validate")
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
- selector = on_transition("validate", "forsake")
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
- selector = on_transition("forsake")
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
+ selector = on_transition("validate")
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ selector = on_transition("validate", "forsake")
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ selector = on_transition("forsake")
+ self.assertEqual(selector(None, req, rset=rset), 0)
- self.adapter.fire_transition('forsake')
- self._commit()
- self.assertEqual(self.adapter.state, 'abandoned')
+ adapter.fire_transition('forsake')
+ req.cnx.commit(); wf_entity.cw_clear_all_caches()
+ self.assertEqual(adapter.state, 'abandoned')
+
+ clear_cache(rset, 'get_entity')
- selector = on_transition("validate")
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- selector = on_transition("validate", "forsake")
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
- selector = on_transition("forsake")
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
+ selector = on_transition("validate")
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ selector = on_transition("validate", "forsake")
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ selector = on_transition("forsake")
+ self.assertEqual(selector(None, req, rset=rset), 1)
def test_on_transition_unvalid_names(self):
- selector = on_transition("unknown")
- with self.assertRaises(ValueError) as cm:
- selector(None, self.req, rset=self.rset)
- self.assertEqual(str(cm.exception),
- "wf_test: unknown transition(s): unknown")
- selector = on_transition("weird", "unknown", "validate", "weird")
- with self.assertRaises(ValueError) as cm:
- selector(None, self.req, rset=self.rset)
- self.assertEqual(str(cm.exception),
- "wf_test: unknown transition(s): unknown,weird")
+ with self.statefull_stuff() as (req, wf_entity, rset, adapter):
+ selector = on_transition("unknown")
+ with self.assertRaises(ValueError) as cm:
+ selector(None, req, rset=rset)
+ self.assertEqual(str(cm.exception),
+ "wf_test: unknown transition(s): unknown")
+ selector = on_transition("weird", "unknown", "validate", "weird")
+ with self.assertRaises(ValueError) as cm:
+ selector(None, req, rset=rset)
+ self.assertEqual(str(cm.exception),
+ "wf_test: unknown transition(s): unknown,weird")
def test_on_transition_with_no_effect(self):
"""selector will not be triggered with `change_state()`"""
- self.adapter.change_state('validated')
- self._commit()
- self.assertEqual(self.adapter.state, 'validated')
+ with self.statefull_stuff() as (req, wf_entity, rset, adapter):
+ adapter.change_state('validated')
+ req.cnx.commit(); wf_entity.cw_clear_all_caches()
+ self.assertEqual(adapter.state, 'validated')
- selector = on_transition("validate")
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- selector = on_transition("validate", "forsake")
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- selector = on_transition("forsake")
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
+ selector = on_transition("validate")
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ selector = on_transition("validate", "forsake")
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ selector = on_transition("forsake")
+ self.assertEqual(selector(None, req, rset=rset), 0)
class RelationPossibleTC(CubicWebTC):
def test_rqlst_1(self):
- req = self.request()
- selector = relation_possible('in_group')
- select = self.vreg.parse(req, 'Any X WHERE X is CWUser').children[0]
- score = selector(None, req, rset=1,
- select=select, filtered_variable=select.defined_vars['X'])
- self.assertEqual(score, 1)
+ with self.admin_access.web_request() as req:
+ selector = relation_possible('in_group')
+ select = self.vreg.parse(req, 'Any X WHERE X is CWUser').children[0]
+ score = selector(None, req, rset=1,
+ select=select, filtered_variable=select.defined_vars['X'])
+ self.assertEqual(score, 1)
def test_rqlst_2(self):
- req = self.request()
- selector = relation_possible('in_group')
- select = self.vreg.parse(req, 'Any 1, COUNT(X) WHERE X is CWUser, X creation_date XD, '
- 'Y creation_date YD, Y is CWGroup '
- 'HAVING DAY(XD)=DAY(YD)').children[0]
- score = selector(None, req, rset=1,
- select=select, filtered_variable=select.defined_vars['X'])
- self.assertEqual(score, 1)
+ with self.admin_access.web_request() as req:
+ selector = relation_possible('in_group')
+ select = self.vreg.parse(req, 'Any 1, COUNT(X) WHERE X is CWUser, X creation_date XD, '
+ 'Y creation_date YD, Y is CWGroup '
+ 'HAVING DAY(XD)=DAY(YD)').children[0]
+ score = selector(None, req, rset=1,
+ select=select, filtered_variable=select.defined_vars['X'])
+ self.assertEqual(score, 1)
def test_ambiguous(self):
# Ambiguous relations are :
@@ -210,10 +230,11 @@
# checking case.
selector = relation_possible('fabrique_par', role='object',
target_etype='Personne', strict=True)
- req = self.request()
- usine = req.create_entity('Usine', lieu=u'here')
- score = selector(None, req, rset=usine.as_rset())
- self.assertEqual(0, score)
+ with self.admin_access.web_request() as req:
+ usine = req.create_entity('Usine', lieu=u'here')
+ score = selector(None, req, rset=usine.as_rset())
+ self.assertEqual(0, score)
+
class MatchUserGroupsTC(CubicWebTC):
def test_owners_group(self):
@@ -227,79 +248,85 @@
SomeAction.__registered__(self.vreg['actions'])
self.assertTrue(SomeAction in self.vreg['actions']['yo'], self.vreg['actions'])
try:
+ with self.admin_access.web_request() as req:
+ self.create_user(req, 'john')
# login as a simple user
- req = self.request()
- self.create_user(req, 'john')
- self.login('john')
- # it should not be possible to use SomeAction not owned objects
- req = self.request()
- rset = req.execute('Any G WHERE G is CWGroup, G name "managers"')
- self.assertFalse('yo' in dict(self.pactions(req, rset)))
- # insert a new card, and check that we can use SomeAction on our object
- self.execute('INSERT Card C: C title "zoubidou"')
- self.commit()
- req = self.request()
- rset = req.execute('Card C WHERE C title "zoubidou"')
- self.assertTrue('yo' in dict(self.pactions(req, rset)), self.pactions(req, rset))
+ john_access = self.new_access('john')
+ with john_access.web_request() as req:
+ # it should not be possible to use SomeAction not owned objects
+ rset = req.execute('Any G WHERE G is CWGroup, G name "managers"')
+ self.assertFalse('yo' in dict(self.pactions(req, rset)))
+ # insert a new card, and check that we can use SomeAction on our object
+ req.execute('INSERT Card C: C title "zoubidou"')
+ req.cnx.commit()
+ with john_access.web_request() as req:
+ rset = req.execute('Card C WHERE C title "zoubidou"')
+ self.assertTrue('yo' in dict(self.pactions(req, rset)), self.pactions(req, rset))
# make sure even managers can't use the action
- self.restore_connection()
- req = self.request()
- rset = req.execute('Card C WHERE C title "zoubidou"')
- self.assertFalse('yo' in dict(self.pactions(req, rset)))
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Card C WHERE C title "zoubidou"')
+ self.assertFalse('yo' in dict(self.pactions(req, rset)))
finally:
del self.vreg[SomeAction.__registry__][SomeAction.__regid__]
-class MultiLinesRsetSelectorTC(CubicWebTC):
- def setUp(self):
- super(MultiLinesRsetSelectorTC, self).setUp()
- self.req = self.request()
- self.req.execute('INSERT CWGroup G: G name "group1"')
- self.req.execute('INSERT CWGroup G: G name "group2"')
- self.commit()
- self.rset = self.req.execute('Any G WHERE G is CWGroup')
+class MultiLinesRsetTC(CubicWebTC):
+ def setup_database(self):
+ with self.admin_access.web_request() as req:
+ req.execute('INSERT CWGroup G: G name "group1"')
+ req.execute('INSERT CWGroup G: G name "group2"')
+ req.cnx.commit()
def test_default_op_in_selector(self):
- expected = len(self.rset)
- selector = multi_lines_rset(expected)
- self.assertEqual(selector(None, self.req, rset=self.rset), 1)
- self.assertEqual(selector(None, self.req, None), 0)
- selector = multi_lines_rset(expected + 1)
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- self.assertEqual(selector(None, self.req, None), 0)
- selector = multi_lines_rset(expected - 1)
- self.assertEqual(selector(None, self.req, rset=self.rset), 0)
- self.assertEqual(selector(None, self.req, None), 0)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any G WHERE G is CWGroup')
+ expected = len(rset)
+ selector = multi_lines_rset(expected)
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ self.assertEqual(selector(None, req, None), 0)
+ selector = multi_lines_rset(expected + 1)
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ self.assertEqual(selector(None, req, None), 0)
+ selector = multi_lines_rset(expected - 1)
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ self.assertEqual(selector(None, req, None), 0)
def test_without_rset(self):
- expected = len(self.rset)
- selector = multi_lines_rset(expected)
- self.assertEqual(selector(None, self.req, None), 0)
- selector = multi_lines_rset(expected + 1)
- self.assertEqual(selector(None, self.req, None), 0)
- selector = multi_lines_rset(expected - 1)
- self.assertEqual(selector(None, self.req, None), 0)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any G WHERE G is CWGroup')
+ expected = len(rset)
+ selector = multi_lines_rset(expected)
+ self.assertEqual(selector(None, req, None), 0)
+ selector = multi_lines_rset(expected + 1)
+ self.assertEqual(selector(None, req, None), 0)
+ selector = multi_lines_rset(expected - 1)
+ self.assertEqual(selector(None, req, None), 0)
def test_with_operators(self):
- expected = len(self.rset)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any G WHERE G is CWGroup')
+ expected = len(rset)
- # Format 'expected', 'operator', 'assert'
- testdata = (( expected, eq, 1),
- ( expected+1, eq, 0),
- ( expected-1, eq, 0),
- ( expected, le, 1),
- ( expected+1, le, 1),
- ( expected-1, le, 0),
- ( expected-1, gt, 1),
- ( expected, gt, 0),
- ( expected+1, gt, 0),
- ( expected+1, lt, 1),
- ( expected, lt, 0),
- ( expected-1, lt, 0))
+ # Format 'expected', 'operator', 'assert'
+ testdata = (( expected, eq, 1),
+ ( expected+1, eq, 0),
+ ( expected-1, eq, 0),
+ ( expected, le, 1),
+ ( expected+1, le, 1),
+ ( expected-1, le, 0),
+ ( expected-1, gt, 1),
+ ( expected, gt, 0),
+ ( expected+1, gt, 0),
+ ( expected+1, lt, 1),
+ ( expected, lt, 0),
+ ( expected-1, lt, 0))
- for (expected, operator, assertion) in testdata:
- selector = multi_lines_rset(expected, operator)
- yield self.assertEqual, selector(None, self.req, rset=self.rset), assertion
+ for (expected, operator, assertion) in testdata:
+ selector = multi_lines_rset(expected, operator)
+ yield self.assertEqual, selector(None, req, rset=rset), assertion
+
+
+class MatchKwargsTC(TestCase):
def test_match_kwargs_default(self):
selector = match_kwargs( set( ('a', 'b') ) )
@@ -316,37 +343,37 @@
self.assertEqual(selector(None, None, a=1, c=1), 1)
-class ScoreEntitySelectorTC(CubicWebTC):
+class ScoreEntityTC(CubicWebTC):
def test_intscore_entity_selector(self):
- req = self.request()
- rset = req.execute('Any E WHERE E eid 1')
- selector = score_entity(lambda x: None)
- self.assertEqual(selector(None, req, rset=rset), 0)
- selector = score_entity(lambda x: "something")
- self.assertEqual(selector(None, req, rset=rset), 1)
- selector = score_entity(lambda x: object)
- self.assertEqual(selector(None, req, rset=rset), 1)
- rset = req.execute('Any G LIMIT 2 WHERE G is CWGroup')
- selector = score_entity(lambda x: 10)
- self.assertEqual(selector(None, req, rset=rset), 20)
- selector = score_entity(lambda x: 10, mode='any')
- self.assertEqual(selector(None, req, rset=rset), 10)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any E WHERE E eid 1')
+ selector = score_entity(lambda x: None)
+ self.assertEqual(selector(None, req, rset=rset), 0)
+ selector = score_entity(lambda x: "something")
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ selector = score_entity(lambda x: object)
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ rset = req.execute('Any G LIMIT 2 WHERE G is CWGroup')
+ selector = score_entity(lambda x: 10)
+ self.assertEqual(selector(None, req, rset=rset), 20)
+ selector = score_entity(lambda x: 10, mode='any')
+ self.assertEqual(selector(None, req, rset=rset), 10)
def test_rql_condition_entity(self):
- req = self.request()
- selector = rql_condition('X identity U')
- rset = req.user.as_rset()
- self.assertEqual(selector(None, req, rset=rset), 1)
- self.assertEqual(selector(None, req, entity=req.user), 1)
- self.assertEqual(selector(None, req), 0)
+ with self.admin_access.web_request() as req:
+ selector = rql_condition('X identity U')
+ rset = req.user.as_rset()
+ self.assertEqual(selector(None, req, rset=rset), 1)
+ self.assertEqual(selector(None, req, entity=req.user), 1)
+ self.assertEqual(selector(None, req), 0)
def test_rql_condition_user(self):
- req = self.request()
- selector = rql_condition('U login "admin"', user_condition=True)
- self.assertEqual(selector(None, req), 1)
- selector = rql_condition('U login "toto"', user_condition=True)
- self.assertEqual(selector(None, req), 0)
+ with self.admin_access.web_request() as req:
+ selector = rql_condition('U login "admin"', user_condition=True)
+ self.assertEqual(selector(None, req), 1)
+ selector = rql_condition('U login "toto"', user_condition=True)
+ self.assertEqual(selector(None, req), 0)
class AdaptablePredicateTC(CubicWebTC):
@@ -359,10 +386,10 @@
__regid__ = 'IWhatever'
__select__ = is_instance('CWGroup')
with self.temporary_appobjects(CWUserIWhatever, CWGroupIWhatever):
- req = self.request()
- selector = adaptable('IWhatever')
- rset = req.execute('Any X WHERE X is IN(CWGroup, CWUser)')
- self.assertTrue(selector(None, req, rset=rset))
+ with self.admin_access.web_request() as req:
+ selector = adaptable('IWhatever')
+ rset = req.execute('Any X WHERE X is IN(CWGroup, CWUser)')
+ self.assertTrue(selector(None, req, rset=rset))
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 test/unittest_repoapi.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/unittest_repoapi.py Wed Sep 24 18:04:30 2014 +0200
@@ -0,0 +1,89 @@
+# copyright 2013-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb. If not, see
.
+"""unittest for cubicweb.dbapi"""
+
+
+from cubicweb.devtools.testlib import CubicWebTC
+
+from cubicweb import ProgrammingError
+from cubicweb.repoapi import ClientConnection, connect, anonymous_cnx
+
+
+class REPOAPITC(CubicWebTC):
+
+ def test_clt_cnx_basic_usage(self):
+ """Test that a client connection can be used to access the database"""
+ with self.admin_access.client_cnx() as cltcnx:
+ # (1) some RQL request
+ rset = cltcnx.execute('Any X WHERE X is CWUser')
+ self.assertTrue(rset)
+ # (2) ORM usage
+ random_user = rset.get_entity(0, 0)
+ # (3) Write operation
+ random_user.cw_set(surname=u'babar')
+ # (4) commit
+ cltcnx.commit()
+ rset = cltcnx.execute('''Any X WHERE X is CWUser,
+ X surname "babar"
+ ''')
+ self.assertTrue(rset)
+ # prepare test for implicit rollback
+ random_user = rset.get_entity(0, 0)
+ random_user.cw_set(surname=u'celestine')
+ # implicit rollback on exit
+ with self.admin_access.client_cnx() as cltcnx:
+ rset = cltcnx.execute('''Any X WHERE X is CWUser,
+ X surname "babar"
+ ''')
+ self.assertTrue(rset)
+
+ def test_clt_cnx_life_cycle(self):
+ """Check that ClientConnection requires explicit open and close
+ """
+ access = self.admin_access
+ cltcnx = ClientConnection(access._session)
+ # connection not open yet
+ with self.assertRaises(ProgrammingError):
+ cltcnx.execute('Any X WHERE X is CWUser')
+ # connection open and working
+ with cltcnx:
+ cltcnx.execute('Any X WHERE X is CWUser')
+ # connection closed
+ with self.assertRaises(ProgrammingError):
+ cltcnx.execute('Any X WHERE X is CWUser')
+
+ def test_connect(self):
+ """check that repoapi.connect works and returns a usable connection"""
+ clt_cnx = connect(self.repo, login='admin', password='gingkow')
+ self.assertEqual('admin', clt_cnx.user.login)
+ with clt_cnx:
+ rset = clt_cnx.execute('Any X WHERE X is CWUser')
+ self.assertTrue(rset)
+
+ def test_anonymous_connect(self):
+ """check that you can get anonymous connection when the data exist"""
+ clt_cnx = anonymous_cnx(self.repo)
+ self.assertEqual('anon', clt_cnx.user.login)
+ with clt_cnx:
+ rset = clt_cnx.execute('Any X WHERE X is CWUser')
+ self.assertTrue(rset)
+
+
+if __name__ == '__main__':
+ from logilab.common.testlib import unittest_main
+ unittest_main()
diff -r 84738d495ffd -r 793377697c81 test/unittest_req.py
--- a/test/unittest_req.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_req.py Wed Sep 24 18:04:30 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.
@@ -56,94 +56,98 @@
def test_base_url(self):
base_url = self.config['base-url']
- self.assertEqual(self.session.base_url(), base_url)
- assert 'https-url' not in self.config
- self.assertEqual(self.session.base_url(secure=True), base_url)
- secure_base_url = base_url.replace('http', 'https')
- self.config.global_set_option('https-url', secure_base_url)
- self.assertEqual(self.session.base_url(secure=True), secure_base_url)
+ with self.admin_access.repo_cnx() as session:
+ self.assertEqual(session.base_url(), base_url)
+ assert 'https-url' not in self.config
+ self.assertEqual(session.base_url(secure=True), base_url)
+ secure_base_url = base_url.replace('http', 'https')
+ self.config.global_set_option('https-url', secure_base_url)
+ self.assertEqual(session.base_url(secure=True), secure_base_url)
def test_view_catch_ex(self):
- req = self.request()
- rset = self.execute('CWUser X WHERE X login "hop"')
- self.assertEqual(req.view('oneline', rset, 'null'), '')
- self.assertRaises(ObjectNotFound, req.view, 'onelinee', rset, 'null')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X WHERE X login "hop"')
+ self.assertEqual(req.view('oneline', rset, 'null'), '')
+ self.assertRaises(ObjectNotFound, req.view, 'onelinee', rset, 'null')
def test_find_one_entity(self):
- self.request().create_entity(
- 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
- surname=u'de Vienne', firstname=u'Christophe',
- in_group=self.request().find('CWGroup', name=u'users').one())
+ with self.admin_access.web_request() as req:
+ req.create_entity(
+ 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
+ surname=u'de Vienne', firstname=u'Christophe',
+ in_group=req.find('CWGroup', name=u'users').one())
- self.request().create_entity(
- 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
- firstname=u'adrien',
- in_group=self.request().find('CWGroup', name=u'users').one())
+ req.create_entity(
+ 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
+ firstname=u'adrien',
+ in_group=req.find('CWGroup', name=u'users').one())
- u = self.request().find_one_entity('CWUser', login=u'cdevienne')
- self.assertEqual(u.firstname, u"Christophe")
+ u = req.find_one_entity('CWUser', login=u'cdevienne')
+ self.assertEqual(u.firstname, u"Christophe")
- with self.assertRaises(FindEntityError):
- self.request().find_one_entity('CWUser', login=u'patanok')
+ with self.assertRaises(FindEntityError):
+ req.find_one_entity('CWUser', login=u'patanok')
- with self.assertRaises(FindEntityError):
- self.request().find_one_entity('CWUser')
+ with self.assertRaises(FindEntityError):
+ req.find_one_entity('CWUser')
def test_find_entities(self):
- self.request().create_entity(
- 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
- surname=u'de Vienne', firstname=u'Christophe',
- in_group=self.request().find('CWGroup', name=u'users').one())
-
- self.request().create_entity(
- 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
- firstname=u'adrien',
- in_group=self.request().find('CWGroup', name=u'users').one())
+ with self.admin_access.web_request() as req:
+ req.create_entity(
+ 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
+ surname=u'de Vienne', firstname=u'Christophe',
+ in_group=req.find('CWGroup', name=u'users').one())
- l = list(self.request().find_entities('CWUser', login=u'cdevienne'))
- self.assertEqual(1, len(l))
- self.assertEqual(l[0].firstname, u"Christophe")
+ req.create_entity(
+ 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
+ firstname=u'adrien',
+ in_group=req.find('CWGroup', name=u'users').one())
- l = list(self.request().find_entities('CWUser', login=u'patanok'))
- self.assertEqual(0, len(l))
+ l = list(req.find_entities('CWUser', login=u'cdevienne'))
+ self.assertEqual(1, len(l))
+ self.assertEqual(l[0].firstname, u"Christophe")
- l = list(self.request().find_entities('CWUser'))
- self.assertEqual(4, len(l))
+ l = list(req.find_entities('CWUser', login=u'patanok'))
+ self.assertEqual(0, len(l))
+
+ l = list(req.find_entities('CWUser'))
+ self.assertEqual(4, len(l))
def test_find(self):
- self.request().create_entity(
- 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
- surname=u'de Vienne', firstname=u'Christophe',
- in_group=self.request().find('CWGroup', name=u'users').one())
+ with self.admin_access.web_request() as req:
+ req.create_entity(
+ 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
+ surname=u'de Vienne', firstname=u'Christophe',
+ in_group=req.find('CWGroup', name=u'users').one())
- self.request().create_entity(
- 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
- firstname=u'adrien',
- in_group=self.request().find('CWGroup', name=u'users').one())
+ req.create_entity(
+ 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
+ firstname=u'adrien',
+ in_group=req.find('CWGroup', name=u'users').one())
- u = self.request().find('CWUser', login=u'cdevienne').one()
- self.assertEqual(u.firstname, u"Christophe")
+ u = req.find('CWUser', login=u'cdevienne').one()
+ self.assertEqual(u.firstname, u"Christophe")
- users = list(self.request().find('CWUser').entities())
- self.assertEqual(len(users), 4)
+ users = list(req.find('CWUser').entities())
+ self.assertEqual(len(users), 4)
- groups = list(
- self.request().find('CWGroup', reverse_in_group=u).entities())
- self.assertEqual(len(groups), 1)
- self.assertEqual(groups[0].name, u'users')
+ groups = list(
+ req.find('CWGroup', reverse_in_group=u).entities())
+ self.assertEqual(len(groups), 1)
+ self.assertEqual(groups[0].name, u'users')
- users = self.request().find('CWUser', in_group=groups[0]).entities()
- users = list(users)
- self.assertEqual(len(users), 2)
+ users = req.find('CWUser', in_group=groups[0]).entities()
+ users = list(users)
+ self.assertEqual(len(users), 2)
- with self.assertRaises(AssertionError):
- self.request().find('CWUser', chapeau=u"melon")
+ with self.assertRaises(AssertionError):
+ req.find('CWUser', chapeau=u"melon")
- with self.assertRaises(AssertionError):
- self.request().find('CWUser', reverse_buddy=users[0])
+ with self.assertRaises(AssertionError):
+ req.find('CWUser', reverse_buddy=users[0])
- with self.assertRaises(NotImplementedError):
- self.request().find('CWUser', in_group=[1, 2])
+ with self.assertRaises(NotImplementedError):
+ req.find('CWUser', in_group=[1, 2])
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 test/unittest_rqlrewrite.py
--- a/test/unittest_rqlrewrite.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_rqlrewrite.py Wed Sep 24 18:04:30 2014 +0200
@@ -129,7 +129,7 @@
"F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), "
"(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is CWGroup)), "
"S is Affaire")
- self.assertTrue('D' in kwargs)
+ self.assertIn('D', kwargs)
def test_or(self):
constraint = '(X identity U) OR (X in_state ST, CL identity U, CL in_state ST, ST name "subscribed")'
@@ -507,11 +507,12 @@
args = {}
querier = self.repo.querier
union = querier.parse(rql)
- querier.solutions(self.session, union, args)
- querier._annotate(union)
- plan = querier.plan_factory(union, args, self.session)
- plan.preprocess(union)
- return union
+ with self.admin_access.repo_cnx() as cnx:
+ querier.solutions(cnx, union, args)
+ querier._annotate(union)
+ plan = querier.plan_factory(union, args, cnx)
+ plan.preprocess(union)
+ return union
def test_ambiguous_optional_same_exprs(self):
"""See #3013535"""
diff -r 84738d495ffd -r 793377697c81 test/unittest_rset.py
--- a/test/unittest_rset.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_rset.py Wed Sep 24 18:04:30 2014 +0200
@@ -1,5 +1,5 @@
# coding: utf-8
-# 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.
@@ -27,7 +27,6 @@
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.rset import NotAnEntity, ResultSet, attr_desc_iterator
-
from cubicweb import NoResultError, MultipleResultsError
@@ -104,27 +103,27 @@
self.assertEqual(len(pickle.dumps(self.rset)), 392)
def test_build_url(self):
- req = self.request()
- baseurl = req.base_url()
- self.compare_urls(req.build_url('view', vid='foo', rql='yo'),
- '%sview?vid=foo&rql=yo' % baseurl)
- self.compare_urls(req.build_url('view', _restpath='task/title/go'),
- '%stask/title/go' % baseurl)
- #self.compare_urls(req.build_url('view', _restpath='/task/title/go'),
- # '%stask/title/go' % baseurl)
- # empty _restpath should not crash
- self.compare_urls(req.build_url('view', _restpath=''), baseurl)
- self.assertNotIn('https', req.build_url('view', vid='foo', rql='yo',
- __secure__=True))
- try:
- self.config.global_set_option('https-url', 'https://testing.fr/')
- self.assertTrue('https', req.build_url('view', vid='foo', rql='yo',
- __secure__=True))
- self.compare_urls(req.build_url('view', vid='foo', rql='yo',
- __secure__=True),
- '%sview?vid=foo&rql=yo' % req.base_url(secure=True))
- finally:
- self.config.global_set_option('https-url', None)
+ with self.admin_access.web_request() as req:
+ baseurl = req.base_url()
+ self.compare_urls(req.build_url('view', vid='foo', rql='yo'),
+ '%sview?vid=foo&rql=yo' % baseurl)
+ self.compare_urls(req.build_url('view', _restpath='task/title/go'),
+ '%stask/title/go' % baseurl)
+ #self.compare_urls(req.build_url('view', _restpath='/task/title/go'),
+ # '%stask/title/go' % baseurl)
+ # empty _restpath should not crash
+ self.compare_urls(req.build_url('view', _restpath=''), baseurl)
+ self.assertNotIn('https', req.build_url('view', vid='foo', rql='yo',
+ __secure__=True))
+ try:
+ self.config.global_set_option('https-url', 'https://testing.fr/')
+ self.assertTrue('https', req.build_url('view', vid='foo', rql='yo',
+ __secure__=True))
+ self.compare_urls(req.build_url('view', vid='foo', rql='yo',
+ __secure__=True),
+ '%sview?vid=foo&rql=yo' % req.base_url(secure=True))
+ finally:
+ self.config.global_set_option('https-url', None)
def test_build(self):
@@ -139,88 +138,92 @@
rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']],
'Any U,L where U is CWUser, U login L',
description=[['CWUser', 'String']] * 3)
- rs.req = self.request()
- rs.vreg = self.vreg
- self.assertEqual(rs.limit(2).rows, [[12000, 'adim'], [13000, 'syt']])
- rs2 = rs.limit(2, offset=1)
- self.assertEqual(rs2.rows, [[13000, 'syt'], [14000, 'nico']])
- self.assertEqual(rs2.get_entity(0, 0).cw_row, 0)
- self.assertEqual(rs.limit(2, offset=2).rows, [[14000, 'nico']])
- self.assertEqual(rs.limit(2, offset=3).rows, [])
+ with self.admin_access.web_request() as req:
+ rs.req = req
+ rs.vreg = self.vreg
+ self.assertEqual(rs.limit(2).rows, [[12000, 'adim'], [13000, 'syt']])
+ rs2 = rs.limit(2, offset=1)
+ self.assertEqual(rs2.rows, [[13000, 'syt'], [14000, 'nico']])
+ self.assertEqual(rs2.get_entity(0, 0).cw_row, 0)
+ self.assertEqual(rs.limit(2, offset=2).rows, [[14000, 'nico']])
+ self.assertEqual(rs.limit(2, offset=3).rows, [])
def test_limit_2(self):
- req = self.request()
- # drop user from cache for the sake of this test
- req.drop_entity_cache(req.user.eid)
- rs = req.execute('Any E,U WHERE E is CWEType, E created_by U')
- # get entity on row 9. This will fill its created_by relation cache,
- # with cwuser on row 9 as well
- e1 = rs.get_entity(9, 0)
- # get entity on row 10. This will fill its created_by relation cache,
- # with cwuser built on row 9
- e2 = rs.get_entity(10, 0)
- # limit result set from row 10
- rs.limit(1, 10, inplace=True)
- # get back eid
- e = rs.get_entity(0, 0)
- self.assertTrue(e2 is e)
- # rs.limit has properly removed cwuser for request cache, but it's
- # still referenced by e/e2 relation cache
- u = e.created_by[0]
- # now ensure this doesn't trigger IndexError because cwuser.cw_row is 9
- # while now rset has only one row
- u.cw_rset[u.cw_row]
+ with self.admin_access.web_request() as req:
+ # drop user from cache for the sake of this test
+ req.drop_entity_cache(req.user.eid)
+ rs = req.execute('Any E,U WHERE E is CWEType, E created_by U')
+ # get entity on row 9. This will fill its created_by relation cache,
+ # with cwuser on row 9 as well
+ e1 = rs.get_entity(9, 0)
+ # get entity on row 10. This will fill its created_by relation cache,
+ # with cwuser built on row 9
+ e2 = rs.get_entity(10, 0)
+ # limit result set from row 10
+ rs.limit(1, 10, inplace=True)
+ # get back eid
+ e = rs.get_entity(0, 0)
+ self.assertTrue(e2 is e)
+ # rs.limit has properly removed cwuser for request cache, but it's
+ # still referenced by e/e2 relation cache
+ u = e.created_by[0]
+ # now ensure this doesn't trigger IndexError because cwuser.cw_row is 9
+ # while now rset has only one row
+ u.cw_rset[u.cw_row]
def test_filter(self):
rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']],
'Any U,L where U is CWUser, U login L',
description=[['CWUser', 'String']] * 3)
- rs.req = self.request()
- rs.vreg = self.vreg
- def test_filter(entity):
- return entity.login != 'nico'
+ with self.admin_access.web_request() as req:
+ rs.req = req
+ rs.vreg = self.vreg
+ def test_filter(entity):
+ return entity.login != 'nico'
- rs2 = rs.filtered_rset(test_filter)
- self.assertEqual(len(rs2), 2)
- self.assertEqual([login for _, login in rs2], ['adim', 'syt'])
- self.assertEqual(rs2.description, rs.description[1:])
+ rs2 = rs.filtered_rset(test_filter)
+ self.assertEqual(len(rs2), 2)
+ self.assertEqual([login for _, login in rs2], ['adim', 'syt'])
+ self.assertEqual(rs2.description, rs.description[1:])
def test_transform(self):
rs = ResultSet([[12, 'adim'], [13, 'syt'], [14, 'nico']],
'Any U,L where U is CWUser, U login L',
description=[['CWUser', 'String']] * 3)
- rs.req = self.request()
- def test_transform(row, desc):
- return row[1:], desc[1:]
- rs2 = rs.transformed_rset(test_transform)
+ with self.admin_access.web_request() as req:
+ rs.req = req
+ def test_transform(row, desc):
+ return row[1:], desc[1:]
+ rs2 = rs.transformed_rset(test_transform)
- self.assertEqual(len(rs2), 3)
- self.assertEqual(list(rs2), [['adim'],['syt'],['nico']])
+ self.assertEqual(len(rs2), 3)
+ self.assertEqual(list(rs2), [['adim'],['syt'],['nico']])
def test_sort(self):
rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']],
'Any U,L where U is CWUser, U login L',
description=[['CWUser', 'String']] * 3)
- rs.req = self.request()
- rs.vreg = self.vreg
+ with self.admin_access.web_request() as req:
+ rs.req = req
+ rs.vreg = self.vreg
- rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'])
- self.assertEqual(len(rs2), 3)
- self.assertEqual([login for _, login in rs2], ['adim', 'nico', 'syt'])
- # make sure rs is unchanged
- self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
+ rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'])
+ self.assertEqual(len(rs2), 3)
+ self.assertEqual([login for _, login in rs2], ['adim', 'nico', 'syt'])
+ # make sure rs is unchanged
+ self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
- rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'], reverse=True)
- self.assertEqual(len(rs2), 3)
- self.assertEqual([login for _, login in rs2], ['syt', 'nico', 'adim'])
- # make sure rs is unchanged
- self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
+ rs2 = rs.sorted_rset(lambda e:e.cw_attr_cache['login'], reverse=True)
+ self.assertEqual(len(rs2), 3)
+ self.assertEqual([login for _, login in rs2], ['syt', 'nico', 'adim'])
+ # make sure rs is unchanged
+ self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
- rs3 = rs.sorted_rset(lambda row: row[1], col=-1)
- self.assertEqual(len(rs3), 3)
- self.assertEqual([login for _, login in rs3], ['adim', 'nico', 'syt'])
- # make sure rs is unchanged
- self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
+ rs3 = rs.sorted_rset(lambda row: row[1], col=-1)
+ self.assertEqual(len(rs3), 3)
+ self.assertEqual([login for _, login in rs3], ['adim', 'nico', 'syt'])
+ # make sure rs is unchanged
+ self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico'])
def test_split(self):
rs = ResultSet([[12000, 'adim', u'Adim chez les pinguins'],
@@ -231,40 +234,41 @@
'Any U, L, T WHERE U is CWUser, U login L,'\
'D created_by U, D title T',
description=[['CWUser', 'String', 'String']] * 5)
- rs.req = self.request()
- rs.vreg = self.vreg
- rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'])
- self.assertEqual(len(rsets), 3)
- self.assertEqual([login for _, login,_ in rsets[0]], ['adim', 'adim'])
- self.assertEqual([login for _, login,_ in rsets[1]], ['syt'])
- self.assertEqual([login for _, login,_ in rsets[2]], ['nico', 'nico'])
- # make sure rs is unchanged
- self.assertEqual([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
+ with self.admin_access.web_request() as req:
+ rs.req = req
+ rs.vreg = self.vreg
+ rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'])
+ self.assertEqual(len(rsets), 3)
+ self.assertEqual([login for _, login,_ in rsets[0]], ['adim', 'adim'])
+ self.assertEqual([login for _, login,_ in rsets[1]], ['syt'])
+ self.assertEqual([login for _, login,_ in rsets[2]], ['nico', 'nico'])
+ # make sure rs is unchanged
+ self.assertEqual([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
- rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'], return_dict=True)
- self.assertEqual(len(rsets), 3)
- self.assertEqual([login for _, login,_ in rsets['nico']], ['nico', 'nico'])
- self.assertEqual([login for _, login,_ in rsets['adim']], ['adim', 'adim'])
- self.assertEqual([login for _, login,_ in rsets['syt']], ['syt'])
- # make sure rs is unchanged
- self.assertEqual([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
+ rsets = rs.split_rset(lambda e:e.cw_attr_cache['login'], return_dict=True)
+ self.assertEqual(len(rsets), 3)
+ self.assertEqual([login for _, login,_ in rsets['nico']], ['nico', 'nico'])
+ self.assertEqual([login for _, login,_ in rsets['adim']], ['adim', 'adim'])
+ self.assertEqual([login for _, login,_ in rsets['syt']], ['syt'])
+ # make sure rs is unchanged
+ self.assertEqual([login for _, login,_ in rs], ['adim', 'adim', 'syt', 'nico', 'nico'])
- rsets = rs.split_rset(lambda s: s.count('d'), col=2)
- self.assertEqual(len(rsets), 2)
- self.assertEqual([title for _, _, title in rsets[0]],
- [u"Adim chez les pinguins",
- u"Jardiner facile",
- u"L'épluchage du castor commun",])
- self.assertEqual([title for _, _, title in rsets[1]],
- [u"Le carrelage en 42 leçons",
- u"La tarte tatin en 15 minutes",])
- # make sure rs is unchanged
- self.assertEqual([title for _, _, title in rs],
- [u'Adim chez les pinguins',
- u'Jardiner facile',
- u'Le carrelage en 42 leçons',
- u'La tarte tatin en 15 minutes',
- u"L'épluchage du castor commun"])
+ rsets = rs.split_rset(lambda s: s.count('d'), col=2)
+ self.assertEqual(len(rsets), 2)
+ self.assertEqual([title for _, _, title in rsets[0]],
+ [u"Adim chez les pinguins",
+ u"Jardiner facile",
+ u"L'épluchage du castor commun",])
+ self.assertEqual([title for _, _, title in rsets[1]],
+ [u"Le carrelage en 42 leçons",
+ u"La tarte tatin en 15 minutes",])
+ # make sure rs is unchanged
+ self.assertEqual([title for _, _, title in rs],
+ [u'Adim chez les pinguins',
+ u'Jardiner facile',
+ u'Le carrelage en 42 leçons',
+ u'La tarte tatin en 15 minutes',
+ u"L'épluchage du castor commun"])
def test_cached_syntax_tree(self):
"""make sure syntax tree is cached"""
@@ -273,265 +277,291 @@
self.assert_(rqlst1 is rqlst2)
def test_get_entity_simple(self):
- self.request().create_entity('CWUser', login=u'adim', upassword='adim',
- surname=u'di mascio', firstname=u'adrien')
- e = self.execute('Any X,T WHERE X login "adim", X surname T').get_entity(0, 0)
- self.assertEqual(e.cw_attr_cache['surname'], 'di mascio')
- self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
- self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'creation_date')
- self.assertEqual(pprelcachedict(e._cw_related_cache), [])
- e.complete()
- self.assertEqual(e.cw_attr_cache['firstname'], 'adrien')
- self.assertEqual(pprelcachedict(e._cw_related_cache), [])
+ with self.admin_access.web_request() as req:
+ req.create_entity('CWUser', login=u'adim', upassword='adim',
+ surname=u'di mascio', firstname=u'adrien')
+ req.cnx.drop_entity_cache()
+ e = req.execute('Any X,T WHERE X login "adim", X surname T').get_entity(0, 0)
+ self.assertEqual(e.cw_attr_cache['surname'], 'di mascio')
+ self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
+ self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'creation_date')
+ self.assertEqual(pprelcachedict(e._cw_related_cache), [])
+ e.complete()
+ self.assertEqual(e.cw_attr_cache['firstname'], 'adrien')
+ self.assertEqual(pprelcachedict(e._cw_related_cache), [])
def test_get_entity_advanced(self):
- self.request().create_entity('Bookmark', title=u'zou', path=u'/view')
- self.execute('SET X bookmarked_by Y WHERE X is Bookmark, Y login "anon"')
- rset = self.execute('Any X,Y,XT,YN WHERE X bookmarked_by Y, X title XT, Y login YN')
+ with self.admin_access.web_request() as req:
+ req.create_entity('Bookmark', title=u'zou', path=u'/view')
+ req.cnx.drop_entity_cache()
+ req.execute('SET X bookmarked_by Y WHERE X is Bookmark, Y login "anon"')
+ rset = req.execute('Any X,Y,XT,YN WHERE X bookmarked_by Y, X title XT, Y login YN')
- e = rset.get_entity(0, 0)
- self.assertEqual(e.cw_row, 0)
- self.assertEqual(e.cw_col, 0)
- self.assertEqual(e.cw_attr_cache['title'], 'zou')
- self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'path')
- self.assertEqual(e.view('text'), 'zou')
- self.assertEqual(pprelcachedict(e._cw_related_cache), [])
+ e = rset.get_entity(0, 0)
+ self.assertEqual(e.cw_row, 0)
+ self.assertEqual(e.cw_col, 0)
+ self.assertEqual(e.cw_attr_cache['title'], 'zou')
+ self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'path')
+ self.assertEqual(e.view('text'), 'zou')
+ self.assertEqual(pprelcachedict(e._cw_related_cache), [])
- e = rset.get_entity(0, 1)
- self.assertEqual(e.cw_row, 0)
- self.assertEqual(e.cw_col, 1)
- self.assertEqual(e.cw_attr_cache['login'], 'anon')
- self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
- self.assertEqual(pprelcachedict(e._cw_related_cache),
- [])
- e.complete()
- self.assertEqual(e.cw_attr_cache['firstname'], None)
- self.assertEqual(e.view('text'), 'anon')
- self.assertEqual(pprelcachedict(e._cw_related_cache),
- [])
+ e = rset.get_entity(0, 1)
+ self.assertEqual(e.cw_row, 0)
+ self.assertEqual(e.cw_col, 1)
+ self.assertEqual(e.cw_attr_cache['login'], 'anon')
+ self.assertRaises(KeyError, e.cw_attr_cache.__getitem__, 'firstname')
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
+ [])
+ e.complete()
+ self.assertEqual(e.cw_attr_cache['firstname'], None)
+ self.assertEqual(e.view('text'), 'anon')
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
+ [])
- self.assertRaises(NotAnEntity, rset.get_entity, 0, 2)
- self.assertRaises(NotAnEntity, rset.get_entity, 0, 3)
+ self.assertRaises(NotAnEntity, rset.get_entity, 0, 2)
+ self.assertRaises(NotAnEntity, rset.get_entity, 0, 3)
def test_get_entity_relation_cache_compt(self):
- rset = self.execute('Any X,S WHERE X in_state S, X login "anon"')
- e = rset.get_entity(0, 0)
- seid = self.execute('State X WHERE X name "activated"')[0][0]
- # for_user / in_group are prefetched in CWUser __init__, in_state should
- # be filed from our query rset
- self.assertEqual(pprelcachedict(e._cw_related_cache),
- [('in_state_subject', [seid])])
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X,S WHERE X in_state S, X login "anon"')
+ e = rset.get_entity(0, 0)
+ seid = req.execute('State X WHERE X name "activated"')[0][0]
+ # for_user / in_group are prefetched in CWUser __init__, in_state should
+ # be filed from our query rset
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
+ [('in_state_subject', [seid])])
def test_get_entity_advanced_prefilled_cache(self):
- e = self.request().create_entity('Bookmark', title=u'zou', path=u'path')
- self.commit()
- rset = self.execute('Any X,U,S,XT,UL,SN WHERE X created_by U, U in_state S, '
- 'X title XT, S name SN, U login UL, X eid %s' % e.eid)
- e = rset.get_entity(0, 0)
- self.assertEqual(e.cw_attr_cache['title'], 'zou')
- self.assertEqual(pprelcachedict(e._cw_related_cache),
- [('created_by_subject', [self.user().eid])])
- # first level of recursion
- u = e.created_by[0]
- self.assertEqual(u.cw_attr_cache['login'], 'admin')
- self.assertRaises(KeyError, u.cw_attr_cache.__getitem__, 'firstname')
- # second level of recursion
- s = u.in_state[0]
- self.assertEqual(s.cw_attr_cache['name'], 'activated')
- self.assertRaises(KeyError, s.cw_attr_cache.__getitem__, 'description')
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Bookmark', title=u'zou', path=u'path')
+ req.cnx.commit()
+ rset = req.execute('Any X,U,S,XT,UL,SN WHERE X created_by U, U in_state S, '
+ 'X title XT, S name SN, U login UL, X eid %s' % e.eid)
+ e = rset.get_entity(0, 0)
+ self.assertEqual(e.cw_attr_cache['title'], 'zou')
+ self.assertEqual(pprelcachedict(e._cw_related_cache),
+ [('created_by_subject', [req.user.eid])])
+ # first level of recursion
+ u = e.created_by[0]
+ self.assertEqual(u.cw_attr_cache['login'], 'admin')
+ self.assertRaises(KeyError, u.cw_attr_cache.__getitem__, 'firstname')
+ # second level of recursion
+ s = u.in_state[0]
+ self.assertEqual(s.cw_attr_cache['name'], 'activated')
+ self.assertRaises(KeyError, s.cw_attr_cache.__getitem__, 'description')
def test_get_entity_cache_with_left_outer_join(self):
- eid = self.execute('INSERT CWUser E: E login "joe", E upassword "joe", E in_group G '
- 'WHERE G name "users"')[0][0]
- rset = self.execute('Any X,E WHERE X eid %(x)s, X primary_email E?', {'x': eid})
- e = rset.get_entity(0, 0)
- # if any of the assertion below fails with a KeyError, the relation is not cached
- # related entities should be an empty list
- self.assertEqual(e._cw_related_cache['primary_email_subject'][True], ())
- # related rset should be an empty rset
- cached = e._cw_related_cache['primary_email_subject'][False]
- self.assertIsInstance(cached, ResultSet)
- self.assertEqual(cached.rowcount, 0)
+ with self.admin_access.web_request() as req:
+ eid = req.execute('INSERT CWUser E: E login "joe", E upassword "joe", E in_group G '
+ 'WHERE G name "users"')[0][0]
+ rset = req.execute('Any X,E WHERE X eid %(x)s, X primary_email E?', {'x': eid})
+ e = rset.get_entity(0, 0)
+ # if any of the assertion below fails with a KeyError, the relation is not cached
+ # related entities should be an empty list
+ self.assertEqual(e._cw_related_cache['primary_email_subject'][True], ())
+ # related rset should be an empty rset
+ cached = e._cw_related_cache['primary_email_subject'][False]
+ self.assertIsInstance(cached, ResultSet)
+ self.assertEqual(cached.rowcount, 0)
def test_get_entity_union(self):
- e = self.request().create_entity('Bookmark', title=u'manger', path=u'path')
- rset = self.execute('Any X,N ORDERBY N WITH X,N BEING '
- '((Any X,N WHERE X is Bookmark, X title N)'
- ' UNION '
- ' (Any X,N WHERE X is CWGroup, X name N))')
- expected = (('CWGroup', 'guests'), ('CWGroup', 'managers'),
- ('Bookmark', 'manger'), ('CWGroup', 'owners'),
- ('CWGroup', 'users'))
- for entity in rset.entities(): # test get_entity for each row actually
- etype, n = expected[entity.cw_row]
- self.assertEqual(entity.cw_etype, etype)
- attr = etype == 'Bookmark' and 'title' or 'name'
- self.assertEqual(entity.cw_attr_cache[attr], n)
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Bookmark', title=u'manger', path=u'path')
+ req.cnx.drop_entity_cache()
+ rset = req.execute('Any X,N ORDERBY N WITH X,N BEING '
+ '((Any X,N WHERE X is Bookmark, X title N)'
+ ' UNION '
+ ' (Any X,N WHERE X is CWGroup, X name N))')
+ expected = (('CWGroup', 'guests'), ('CWGroup', 'managers'),
+ ('Bookmark', 'manger'), ('CWGroup', 'owners'),
+ ('CWGroup', 'users'))
+ for entity in rset.entities(): # test get_entity for each row actually
+ etype, n = expected[entity.cw_row]
+ self.assertEqual(entity.cw_etype, etype)
+ attr = etype == 'Bookmark' and 'title' or 'name'
+ self.assertEqual(entity.cw_attr_cache[attr], n)
def test_one(self):
- self.request().create_entity('CWUser', login=u'cdevienne',
- upassword=u'cdevienne',
- surname=u'de Vienne',
- firstname=u'Christophe')
- e = self.execute('Any X WHERE X login "cdevienne"').one()
-
- self.assertEqual(e.surname, u'de Vienne')
+ with self.admin_access.web_request() as req:
+ req.create_entity('CWUser', login=u'cdevienne',
+ upassword=u'cdevienne',
+ surname=u'de Vienne',
+ firstname=u'Christophe')
+ e = req.execute('Any X WHERE X login "cdevienne"').one()
- e = self.execute(
- 'Any X, N WHERE X login "cdevienne", X surname N').one()
- self.assertEqual(e.surname, u'de Vienne')
+ self.assertEqual(e.surname, u'de Vienne')
- e = self.execute(
- 'Any N, X WHERE X login "cdevienne", X surname N').one(col=1)
- self.assertEqual(e.surname, u'de Vienne')
+ e = req.execute(
+ 'Any X, N WHERE X login "cdevienne", X surname N').one()
+ self.assertEqual(e.surname, u'de Vienne')
+
+ e = req.execute(
+ 'Any N, X WHERE X login "cdevienne", X surname N').one(col=1)
+ self.assertEqual(e.surname, u'de Vienne')
def test_one_no_rows(self):
- with self.assertRaises(NoResultError):
- self.execute('Any X WHERE X login "patanok"').one()
+ with self.admin_access.web_request() as req:
+ with self.assertRaises(NoResultError):
+ req.execute('Any X WHERE X login "patanok"').one()
def test_one_multiple_rows(self):
- self.request().create_entity(
- 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
- surname=u'de Vienne', firstname=u'Christophe')
+ with self.admin_access.web_request() as req:
+ req.create_entity(
+ 'CWUser', login=u'cdevienne', upassword=u'cdevienne',
+ surname=u'de Vienne', firstname=u'Christophe')
- self.request().create_entity(
- 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
- firstname=u'adrien')
+ req.create_entity(
+ 'CWUser', login=u'adim', upassword='adim', surname=u'di mascio',
+ firstname=u'adrien')
- with self.assertRaises(MultipleResultsError):
- self.execute('Any X WHERE X is CWUser').one()
+ with self.assertRaises(MultipleResultsError):
+ req.execute('Any X WHERE X is CWUser').one()
def test_related_entity_optional(self):
- e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
- rset = self.execute('Any B,U,L WHERE B bookmarked_by U?, U login L')
- entity, rtype = rset.related_entity(0, 2)
- self.assertEqual(entity, None)
- self.assertEqual(rtype, None)
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Bookmark', title=u'aaaa', path=u'path')
+ rset = req.execute('Any B,U,L WHERE B bookmarked_by U?, U login L')
+ entity, rtype = rset.related_entity(0, 2)
+ self.assertEqual(entity, None)
+ self.assertEqual(rtype, None)
def test_related_entity_union_subquery_1(self):
- e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
- rset = self.execute('Any X,N ORDERBY N WITH X,N BEING '
- '((Any X,N WHERE X is CWGroup, X name N)'
- ' UNION '
- ' (Any X,N WHERE X is Bookmark, X title N))')
- entity, rtype = rset.related_entity(0, 1)
- self.assertEqual(entity.eid, e.eid)
- self.assertEqual(rtype, 'title')
- self.assertEqual(entity.title, 'aaaa')
- entity, rtype = rset.related_entity(1, 1)
- self.assertEqual(entity.cw_etype, 'CWGroup')
- self.assertEqual(rtype, 'name')
- self.assertEqual(entity.name, 'guests')
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Bookmark', title=u'aaaa', path=u'path')
+ rset = req.execute('Any X,N ORDERBY N WITH X,N BEING '
+ '((Any X,N WHERE X is CWGroup, X name N)'
+ ' UNION '
+ ' (Any X,N WHERE X is Bookmark, X title N))')
+ entity, rtype = rset.related_entity(0, 1)
+ self.assertEqual(entity.eid, e.eid)
+ self.assertEqual(rtype, 'title')
+ self.assertEqual(entity.title, 'aaaa')
+ entity, rtype = rset.related_entity(1, 1)
+ self.assertEqual(entity.cw_etype, 'CWGroup')
+ self.assertEqual(rtype, 'name')
+ self.assertEqual(entity.name, 'guests')
def test_related_entity_union_subquery_2(self):
- e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
- rset = self.execute('Any X,N ORDERBY N WHERE X is Bookmark WITH X,N BEING '
- '((Any X,N WHERE X is CWGroup, X name N)'
- ' UNION '
- ' (Any X,N WHERE X is Bookmark, X title N))')
- entity, rtype = rset.related_entity(0, 1)
- self.assertEqual(entity.eid, e.eid)
- self.assertEqual(rtype, 'title')
- self.assertEqual(entity.title, 'aaaa')
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Bookmark', title=u'aaaa', path=u'path')
+ rset = req.execute('Any X,N ORDERBY N WHERE X is Bookmark WITH X,N BEING '
+ '((Any X,N WHERE X is CWGroup, X name N)'
+ ' UNION '
+ ' (Any X,N WHERE X is Bookmark, X title N))')
+ entity, rtype = rset.related_entity(0, 1)
+ self.assertEqual(entity.eid, e.eid)
+ self.assertEqual(rtype, 'title')
+ self.assertEqual(entity.title, 'aaaa')
def test_related_entity_union_subquery_3(self):
- e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
- rset = self.execute('Any X,N ORDERBY N WITH N,X BEING '
- '((Any N,X WHERE X is CWGroup, X name N)'
- ' UNION '
- ' (Any N,X WHERE X is Bookmark, X title N))')
- entity, rtype = rset.related_entity(0, 1)
- self.assertEqual(entity.eid, e.eid)
- self.assertEqual(rtype, 'title')
- self.assertEqual(entity.title, 'aaaa')
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Bookmark', title=u'aaaa', path=u'path')
+ rset = req.execute('Any X,N ORDERBY N WITH N,X BEING '
+ '((Any N,X WHERE X is CWGroup, X name N)'
+ ' UNION '
+ ' (Any N,X WHERE X is Bookmark, X title N))')
+ entity, rtype = rset.related_entity(0, 1)
+ self.assertEqual(entity.eid, e.eid)
+ self.assertEqual(rtype, 'title')
+ self.assertEqual(entity.title, 'aaaa')
def test_related_entity_union_subquery_4(self):
- e = self.request().create_entity('Bookmark', title=u'aaaa', path=u'path')
- rset = self.execute('Any X,X, N ORDERBY N WITH X,N BEING '
- '((Any X,N WHERE X is CWGroup, X name N)'
- ' UNION '
- ' (Any X,N WHERE X is Bookmark, X title N))')
- entity, rtype = rset.related_entity(0, 2)
- self.assertEqual(entity.eid, e.eid)
- self.assertEqual(rtype, 'title')
- self.assertEqual(entity.title, 'aaaa')
+ with self.admin_access.web_request() as req:
+ e = req.create_entity('Bookmark', title=u'aaaa', path=u'path')
+ rset = req.execute('Any X,X, N ORDERBY N WITH X,N BEING '
+ '((Any X,N WHERE X is CWGroup, X name N)'
+ ' UNION '
+ ' (Any X,N WHERE X is Bookmark, X title N))')
+ entity, rtype = rset.related_entity(0, 2)
+ self.assertEqual(entity.eid, e.eid)
+ self.assertEqual(rtype, 'title')
+ self.assertEqual(entity.title, 'aaaa')
def test_related_entity_trap_subquery(self):
- req = self.request()
- req.create_entity('Bookmark', title=u'test bookmark', path=u'')
- self.execute('SET B bookmarked_by U WHERE U login "admin"')
- rset = self.execute('Any B,T,L WHERE B bookmarked_by U, U login L '
- 'WITH B,T BEING (Any B,T WHERE B is Bookmark, B title T)')
- rset.related_entity(0, 2)
+ with self.admin_access.web_request() as req:
+ req.create_entity('Bookmark', title=u'test bookmark', path=u'')
+ req.execute('SET B bookmarked_by U WHERE U login "admin"')
+ rset = req.execute('Any B,T,L WHERE B bookmarked_by U, U login L '
+ 'WITH B,T BEING (Any B,T WHERE B is Bookmark, B title T)')
+ rset.related_entity(0, 2)
def test_related_entity_subquery_outerjoin(self):
- rset = self.execute('Any X,S,L WHERE X in_state S '
- 'WITH X, L BEING (Any X,MAX(L) GROUPBY X '
- 'WHERE X is CWUser, T? wf_info_for X, T creation_date L)')
- self.assertEqual(len(rset), 2)
- rset.related_entity(0, 1)
- rset.related_entity(0, 2)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X,S,L WHERE X in_state S '
+ 'WITH X, L BEING (Any X,MAX(L) GROUPBY X '
+ 'WHERE X is CWUser, T? wf_info_for X, T creation_date L)')
+ self.assertEqual(len(rset), 2)
+ rset.related_entity(0, 1)
+ rset.related_entity(0, 2)
def test_entities(self):
- rset = self.execute('Any U,G WHERE U in_group G')
- # make sure we have at least one element
- self.assertTrue(rset)
- self.assertEqual(set(e.e_schema.type for e in rset.entities(0)),
- set(['CWUser',]))
- self.assertEqual(set(e.e_schema.type for e in rset.entities(1)),
- set(['CWGroup',]))
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any U,G WHERE U in_group G')
+ # make sure we have at least one element
+ self.assertTrue(rset)
+ self.assertEqual(set(e.e_schema.type for e in rset.entities(0)),
+ set(['CWUser',]))
+ self.assertEqual(set(e.e_schema.type for e in rset.entities(1)),
+ set(['CWGroup',]))
def test_iter_rows_with_entities(self):
- rset = self.execute('Any U,UN,G,GN WHERE U in_group G, U login UN, G name GN')
- # make sure we have at least one element
- self.assertTrue(rset)
- out = list(rset.iter_rows_with_entities())[0]
- self.assertEqual( out[0].login, out[1] )
- self.assertEqual( out[2].name, out[3] )
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any U,UN,G,GN WHERE U in_group G, U login UN, G name GN')
+ # make sure we have at least one element
+ self.assertTrue(rset)
+ out = list(rset.iter_rows_with_entities())[0]
+ self.assertEqual( out[0].login, out[1] )
+ self.assertEqual( out[2].name, out[3] )
def test_printable_rql(self):
- rset = self.execute(u'CWEType X WHERE X final FALSE')
- self.assertEqual(rset.printable_rql(),
- 'Any X WHERE X final FALSE, X is CWEType')
+ with self.admin_access.web_request() as req:
+ rset = req.execute(u'CWEType X WHERE X final FALSE')
+ self.assertEqual(rset.printable_rql(),
+ 'Any X WHERE X final FALSE, X is CWEType')
def test_searched_text(self):
- rset = self.execute(u'Any X WHERE X has_text "foobar"')
- self.assertEqual(rset.searched_text(), 'foobar')
- rset = self.execute(u'Any X WHERE X has_text %(text)s', {'text' : 'foo'})
- self.assertEqual(rset.searched_text(), 'foo')
+ with self.admin_access.web_request() as req:
+ rset = req.execute(u'Any X WHERE X has_text "foobar"')
+ self.assertEqual(rset.searched_text(), 'foobar')
+ rset = req.execute(u'Any X WHERE X has_text %(text)s', {'text' : 'foo'})
+ self.assertEqual(rset.searched_text(), 'foo')
def test_union_limited_rql(self):
- rset = self.execute('(Any X,N WHERE X is Bookmark, X title N)'
- ' UNION '
- '(Any X,N WHERE X is CWGroup, X name N)')
- rset.limit(2, 10, inplace=True)
- self.assertEqual(rset.limited_rql(),
- 'Any A,B LIMIT 2 OFFSET 10 '
- 'WITH A,B BEING ('
- '(Any X,N WHERE X is Bookmark, X title N) '
- 'UNION '
- '(Any X,N WHERE X is CWGroup, X name N)'
- ')')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('(Any X,N WHERE X is Bookmark, X title N)'
+ ' UNION '
+ '(Any X,N WHERE X is CWGroup, X name N)')
+ rset.limit(2, 10, inplace=True)
+ self.assertEqual(rset.limited_rql(),
+ 'Any A,B LIMIT 2 OFFSET 10 '
+ 'WITH A,B BEING ('
+ '(Any X,N WHERE X is Bookmark, X title N) '
+ 'UNION '
+ '(Any X,N WHERE X is CWGroup, X name N)'
+ ')')
def test_count_users_by_date(self):
- rset = self.execute('Any D, COUNT(U) GROUPBY D WHERE U is CWUser, U creation_date D')
- self.assertEqual(rset.related_entity(0,0), (None, None))
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any D, COUNT(U) GROUPBY D WHERE U is CWUser, U creation_date D')
+ self.assertEqual(rset.related_entity(0,0), (None, None))
def test_str(self):
- rset = self.execute('(Any X,N WHERE X is CWGroup, X name N)')
- self.assertIsInstance(str(rset), basestring)
- self.assertEqual(len(str(rset).splitlines()), 1)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('(Any X,N WHERE X is CWGroup, X name N)')
+ self.assertIsInstance(str(rset), basestring)
+ self.assertEqual(len(str(rset).splitlines()), 1)
def test_repr(self):
- rset = self.execute('(Any X,N WHERE X is CWGroup, X name N)')
- self.assertIsInstance(repr(rset), basestring)
- self.assertTrue(len(repr(rset).splitlines()) > 1)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('(Any X,N WHERE X is CWGroup, X name N)')
+ self.assertIsInstance(repr(rset), basestring)
+ self.assertTrue(len(repr(rset).splitlines()) > 1)
- rset = self.execute('(Any X WHERE X is CWGroup, X name "managers")')
- self.assertIsInstance(str(rset), basestring)
- self.assertEqual(len(str(rset).splitlines()), 1)
+ rset = req.execute('(Any X WHERE X is CWGroup, X name "managers")')
+ self.assertIsInstance(str(rset), basestring)
+ self.assertEqual(len(str(rset).splitlines()), 1)
if __name__ == '__main__':
diff -r 84738d495ffd -r 793377697c81 test/unittest_schema.py
--- a/test/unittest_schema.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_schema.py Wed Sep 24 18:04:30 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.
@@ -168,7 +168,7 @@
'CWUniqueTogetherConstraint', 'CWUser',
'ExternalUri', 'File', 'Float', 'Int', 'Interval', 'Note',
'Password', 'Personne', 'Produit',
- 'RQLExpression',
+ 'RQLExpression', 'Reference',
'Service', 'Societe', 'State', 'StateFull', 'String', 'SubNote', 'SubWorkflowExitPoint',
'Tag', 'TZDatetime', 'TZTime', 'Time', 'Transition', 'TrInfo',
'Usine',
@@ -188,7 +188,7 @@
'data', 'data_encoding', 'data_format', 'data_name', 'default_workflow', 'defaultval', 'delete_permission',
'description', 'description_format', 'destination_state', 'dirige',
- 'ecrit_par', 'eid', 'end_timestamp', 'evaluee', 'expression', 'exprtype', 'extra_props',
+ 'ean', 'ecrit_par', 'eid', 'end_timestamp', 'evaluee', 'expression', 'exprtype', 'extra_props',
'fabrique_par', 'final', 'firstname', 'for_user', 'fournit',
'from_entity', 'from_state', 'fulltext_container', 'fulltextindexed',
@@ -248,8 +248,8 @@
def test_fulltext_container(self):
schema = loader.load(config)
- self.assertTrue('has_text' in schema['CWUser'].subject_relations())
- self.assertFalse('has_text' in schema['EmailAddress'].subject_relations())
+ self.assertIn('has_text', schema['CWUser'].subject_relations())
+ self.assertNotIn('has_text', schema['EmailAddress'].subject_relations())
def test_permission_settings(self):
schema = loader.load(config)
@@ -329,6 +329,7 @@
self.assertEqual(normalize_expression('X bla Y,Y blur Z , Z zigoulou X '),
'X bla Y, Y blur Z, Z zigoulou X')
+
class RQLExpressionTC(TestCase):
def test_comparison(self):
self.assertEqual(ERQLExpression('X is CWUser', 'X', 0),
@@ -336,6 +337,7 @@
self.assertNotEqual(ERQLExpression('X is CWUser', 'X', 0),
ERQLExpression('X is CWGroup', 'X', 0))
+
class GuessRrqlExprMainVarsTC(TestCase):
def test_exists(self):
mainvars = guess_rrqlexpr_mainvars(normalize_expression('NOT EXISTS(O team_competition C, C level < 3, C concerns S)'))
@@ -345,15 +347,112 @@
class RQLConstraintTC(CubicWebTC):
def test_user_constraint(self):
cstr = RQLConstraint('U identity O')
- anoneid = self.execute('Any X WHERE X login "anon"')[0][0]
- self.assertRaises(ValidationError, cstr.repo_check, self.session, 1, 'rel', anoneid)
- self.assertEqual(cstr.repo_check(self.session, 1, self.session.user.eid),
- None) # no validation error, constraint checked
+ with self.admin_access.repo_cnx() as cnx:
+ anoneid = cnx.execute('Any X WHERE X login "anon"')[0][0]
+ self.assertRaises(ValidationError,
+ cstr.repo_check, cnx, 1, 'rel', anoneid)
+ self.assertEqual(cstr.repo_check(cnx, 1, cnx.user.eid),
+ None) # no validation error, constraint checked
+
class WorkflowShemaTC(CubicWebTC):
def test_trinfo_default_format(self):
- tr = self.request().user.cw_adapt_to('IWorkflowable').fire_transition('deactivate')
- self.assertEqual(tr.comment_format, 'text/plain')
+ with self.admin_access.web_request() as req:
+ tr = req.user.cw_adapt_to('IWorkflowable').fire_transition('deactivate')
+ self.assertEqual(tr.comment_format, 'text/plain')
+
+
+class CompositeSchemaTC(CubicWebTC):
+ composites = {
+ 'BaseTransition': [('condition', 'BaseTransition', 'RQLExpression', 'subject')],
+ 'CWAttribute': [('add_permission', 'CWAttribute', 'RQLExpression', 'subject'),
+ ('constrained_by', 'CWAttribute', 'CWConstraint', 'subject'),
+ ('read_permission', 'CWAttribute', 'RQLExpression', 'subject'),
+ ('update_permission', 'CWAttribute', 'RQLExpression', 'subject')],
+ 'CWEType': [('add_permission', 'CWEType', 'RQLExpression', 'subject'),
+ ('constraint_of', 'CWUniqueTogetherConstraint', 'CWEType', 'object'),
+ ('cw_schema', 'CWSourceSchemaConfig', 'CWEType', 'object'),
+ ('delete_permission', 'CWEType', 'RQLExpression', 'subject'),
+ ('from_entity', 'CWAttribute', 'CWEType', 'object'),
+ ('from_entity', 'CWRelation', 'CWEType', 'object'),
+ ('read_permission', 'CWEType', 'RQLExpression', 'subject'),
+ ('to_entity', 'CWAttribute', 'CWEType', 'object'),
+ ('to_entity', 'CWRelation', 'CWEType', 'object'),
+ ('update_permission', 'CWEType', 'RQLExpression', 'subject')],
+ 'CWRType': [('cw_schema', 'CWSourceSchemaConfig', 'CWRType', 'object'),
+ ('relation_type', 'CWAttribute', 'CWRType', 'object'),
+ ('relation_type', 'CWRelation', 'CWRType', 'object')],
+ 'CWRelation': [('add_permission', 'CWRelation', 'RQLExpression', 'subject'),
+ ('constrained_by', 'CWRelation', 'CWConstraint', 'subject'),
+ ('cw_schema', 'CWSourceSchemaConfig', 'CWRelation', 'object'),
+ ('delete_permission', 'CWRelation', 'RQLExpression', 'subject'),
+ ('read_permission', 'CWRelation', 'RQLExpression', 'subject')],
+ 'CWSource': [('cw_for_source', 'CWSourceSchemaConfig', 'CWSource', 'object'),
+ ('cw_host_config_of', 'CWSourceHostConfig', 'CWSource', 'object'),
+ ('cw_import_of', 'CWDataImport', 'CWSource', 'object'),
+ ('cw_source', 'Ami', 'CWSource', 'object'),
+ ('cw_source', 'BaseTransition', 'CWSource', 'object'),
+ ('cw_source', 'Bookmark', 'CWSource', 'object'),
+ ('cw_source', 'CWAttribute', 'CWSource', 'object'),
+ ('cw_source', 'CWCache', 'CWSource', 'object'),
+ ('cw_source', 'CWConstraint', 'CWSource', 'object'),
+ ('cw_source', 'CWConstraintType', 'CWSource', 'object'),
+ ('cw_source', 'CWDataImport', 'CWSource', 'object'),
+ ('cw_source', 'CWEType', 'CWSource', 'object'),
+ ('cw_source', 'CWGroup', 'CWSource', 'object'),
+ ('cw_source', 'CWPermission', 'CWSource', 'object'),
+ ('cw_source', 'CWProperty', 'CWSource', 'object'),
+ ('cw_source', 'CWRType', 'CWSource', 'object'),
+ ('cw_source', 'CWRelation', 'CWSource', 'object'),
+ ('cw_source', 'CWSource', 'CWSource', 'object'),
+ ('cw_source', 'CWSourceHostConfig', 'CWSource', 'object'),
+ ('cw_source', 'CWSourceSchemaConfig', 'CWSource', 'object'),
+ ('cw_source', 'CWUniqueTogetherConstraint', 'CWSource', 'object'),
+ ('cw_source', 'CWUser', 'CWSource', 'object'),
+ ('cw_source', 'Card', 'CWSource', 'object'),
+ ('cw_source', 'EmailAddress', 'CWSource', 'object'),
+ ('cw_source', 'ExternalUri', 'CWSource', 'object'),
+ ('cw_source', 'File', 'CWSource', 'object'),
+ ('cw_source', 'Note', 'CWSource', 'object'),
+ ('cw_source', 'Personne', 'CWSource', 'object'),
+ ('cw_source', 'Produit', 'CWSource', 'object'),
+ ('cw_source', 'RQLExpression', 'CWSource', 'object'),
+ ('cw_source', 'Reference', 'CWSource', 'object'),
+ ('cw_source', 'Service', 'CWSource', 'object'),
+ ('cw_source', 'Societe', 'CWSource', 'object'),
+ ('cw_source', 'State', 'CWSource', 'object'),
+ ('cw_source', 'StateFull', 'CWSource', 'object'),
+ ('cw_source', 'SubNote', 'CWSource', 'object'),
+ ('cw_source', 'SubWorkflowExitPoint', 'CWSource', 'object'),
+ ('cw_source', 'Tag', 'CWSource', 'object'),
+ ('cw_source', 'TrInfo', 'CWSource', 'object'),
+ ('cw_source', 'Transition', 'CWSource', 'object'),
+ ('cw_source', 'Usine', 'CWSource', 'object'),
+ ('cw_source', 'Workflow', 'CWSource', 'object'),
+ ('cw_source', 'WorkflowTransition', 'CWSource', 'object')],
+ 'CWUser': [('for_user', 'CWProperty', 'CWUser', 'object'),
+ ('use_email', 'CWUser', 'EmailAddress', 'subject'),
+ ('wf_info_for', 'TrInfo', 'CWUser', 'object')],
+ 'StateFull': [('wf_info_for', 'TrInfo', 'StateFull', 'object')],
+ 'Transition': [('condition', 'Transition', 'RQLExpression', 'subject')],
+ 'Workflow': [('state_of', 'State', 'Workflow', 'object'),
+ ('transition_of', 'BaseTransition', 'Workflow', 'object'),
+ ('transition_of', 'Transition', 'Workflow', 'object'),
+ ('transition_of', 'WorkflowTransition', 'Workflow', 'object')],
+ 'WorkflowTransition': [('condition', 'WorkflowTransition', 'RQLExpression', 'subject'),
+ ('subworkflow_exit', 'WorkflowTransition', 'SubWorkflowExitPoint', 'subject')]
+ }
+
+ def test_composite_entities(self):
+ schema = self.vreg.schema
+ self.assertEqual(sorted(self.composites),
+ [eschema.type for eschema in sorted(schema.entities())
+ if eschema.is_composite])
+ for etype in self.composites:
+ self.set_description('composite rdefs for %s' % etype)
+ yield self.assertEqual, self.composites[etype], \
+ sorted([(r.rtype.type, r.subject.type, r.object.type, role)
+ for r, role in sorted(schema[etype].composite_rdef_roles)])
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 test/unittest_utils.py
--- a/test/unittest_utils.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_utils.py Wed Sep 24 18:04:30 2014 +0200
@@ -229,11 +229,11 @@
class HTMLHeadTC(CubicWebTC):
def htmlhead(self, datadir_url):
- req = self.request()
- base_url = u'http://test.fr/data/'
- req.datadir_url = base_url
- head = HTMLHead(req)
- return head
+ with self.admin_access.web_request() as req:
+ base_url = u'http://test.fr/data/'
+ req.datadir_url = base_url
+ head = HTMLHead(req)
+ return head
def test_concat_urls(self):
base_url = u'http://test.fr/data/'
diff -r 84738d495ffd -r 793377697c81 test/unittest_vregistry.py
--- a/test/unittest_vregistry.py Wed Sep 24 17:35:59 2014 +0200
+++ b/test/unittest_vregistry.py Wed Sep 24 18:04:30 2014 +0200
@@ -74,7 +74,7 @@
def test_properties(self):
self.vreg.reset()
- self.assertFalse('system.version.cubicweb' in self.vreg['propertydefs'])
+ self.assertNotIn('system.version.cubicweb', self.vreg['propertydefs'])
self.assertTrue(self.vreg.property_info('system.version.cubicweb'))
self.assertRaises(UnknownProperty, self.vreg.property_info, 'a.non.existent.key')
diff -r 84738d495ffd -r 793377697c81 transaction.py
--- a/transaction.py Wed Sep 24 17:35:59 2014 +0200
+++ b/transaction.py Wed Sep 24 18:04:30 2014 +0200
@@ -53,7 +53,17 @@
self.datetime = time
self.user_eid = ueid
# should be set by the dbapi connection
- self.req = None
+ self.req = None # old style
+ self.cnx = None # new style
+
+ def _execute(self, *args, **kwargs):
+ """execute a query using either the req or the cnx"""
+ if self.req is None:
+ execute = self.cnx.execute
+ else:
+ execute = self.req
+ return execute(*args, **kwargs)
+
def __repr__(self):
return '
' % (
@@ -63,8 +73,8 @@
"""return the user entity which has done the transaction,
none if not found.
"""
- return self.req.execute('Any X WHERE X eid %(x)s',
- {'x': self.user_eid}).get_entity(0, 0)
+ return self._execute('Any X WHERE X eid %(x)s',
+ {'x': self.user_eid}).get_entity(0, 0)
def actions_list(self, public=True):
"""return an ordered list of action effectued during that transaction
@@ -72,7 +82,11 @@
if public is true, return only 'public' action, eg not ones triggered
under the cover by hooks.
"""
- return self.req.cnx.transaction_actions(self.uuid, public)
+ if self.req is not None:
+ cnx = self.req.cnx
+ else:
+ cnx = self.cnx
+ return cnx.transaction_actions(self.uuid, public)
class AbstractAction(object):
diff -r 84738d495ffd -r 793377697c81 utils.py
--- a/utils.py Wed Sep 24 17:35:59 2014 +0200
+++ b/utils.py Wed Sep 24 18:04:30 2014 +0200
@@ -26,6 +26,7 @@
import datetime
import random
import re
+import json
from operator import itemgetter
from inspect import getargspec
@@ -39,6 +40,7 @@
from logilab.mtconverter import xml_escape
from logilab.common.deprecation import deprecated
+from logilab.common.date import ustrftime
_MARKER = object()
@@ -167,8 +169,6 @@
id(self), self._item, self._size)
def __len__(self):
return self._size
- def __nonzero__(self):
- return self._size
def __iter__(self):
return repeat(self._item, self._size)
def __getitem__(self, index):
@@ -465,77 +465,66 @@
self.head.getvalue(),
self.body.getvalue())
-try:
- # may not be there if cubicweb-web not installed
- if sys.version_info < (2, 6):
- import simplejson as json
- else:
- import json
-except ImportError:
- json_dumps = JSString = None
-else:
- from logilab.common.date import ustrftime
-
- class CubicWebJsonEncoder(json.JSONEncoder):
- """define a json encoder to be able to encode yams std types"""
+class CubicWebJsonEncoder(json.JSONEncoder):
+ """define a json encoder to be able to encode yams std types"""
- def default(self, obj):
- if hasattr(obj, '__json_encode__'):
- return obj.__json_encode__()
- if isinstance(obj, datetime.datetime):
- return ustrftime(obj, '%Y/%m/%d %H:%M:%S')
- elif isinstance(obj, datetime.date):
- return ustrftime(obj, '%Y/%m/%d')
- elif isinstance(obj, datetime.time):
- return obj.strftime('%H:%M:%S')
- elif isinstance(obj, datetime.timedelta):
- return (obj.days * 24 * 60 * 60) + obj.seconds
- elif isinstance(obj, decimal.Decimal):
- return float(obj)
- try:
- return json.JSONEncoder.default(self, obj)
- except TypeError:
- # we never ever want to fail because of an unknown type,
- # just return None in those cases.
- return None
+ def default(self, obj):
+ if hasattr(obj, '__json_encode__'):
+ return obj.__json_encode__()
+ if isinstance(obj, datetime.datetime):
+ return ustrftime(obj, '%Y/%m/%d %H:%M:%S')
+ elif isinstance(obj, datetime.date):
+ return ustrftime(obj, '%Y/%m/%d')
+ elif isinstance(obj, datetime.time):
+ return obj.strftime('%H:%M:%S')
+ elif isinstance(obj, datetime.timedelta):
+ return (obj.days * 24 * 60 * 60) + obj.seconds
+ elif isinstance(obj, decimal.Decimal):
+ return float(obj)
+ try:
+ return json.JSONEncoder.default(self, obj)
+ except TypeError:
+ # we never ever want to fail because of an unknown type,
+ # just return None in those cases.
+ return None
- def json_dumps(value, **kwargs):
- return json.dumps(value, cls=CubicWebJsonEncoder, **kwargs)
+def json_dumps(value, **kwargs):
+ return json.dumps(value, cls=CubicWebJsonEncoder, **kwargs)
- class JSString(str):
- """use this string sub class in values given to :func:`js_dumps` to
- insert raw javascript chain in some JSON string
- """
+class JSString(str):
+ """use this string sub class in values given to :func:`js_dumps` to
+ insert raw javascript chain in some JSON string
+ """
- def _dict2js(d, predictable=False):
- res = [key + ': ' + js_dumps(val, predictable)
- for key, val in d.iteritems()]
- return '{%s}' % ', '.join(res)
+def _dict2js(d, predictable=False):
+ res = [key + ': ' + js_dumps(val, predictable)
+ for key, val in d.iteritems()]
+ return '{%s}' % ', '.join(res)
- def _list2js(l, predictable=False):
- return '[%s]' % ', '.join([js_dumps(val, predictable) for val in l])
+def _list2js(l, predictable=False):
+ return '[%s]' % ', '.join([js_dumps(val, predictable) for val in l])
- def js_dumps(something, predictable=False):
- """similar as :func:`json_dumps`, except values which are instances of
- :class:`JSString` are expected to be valid javascript and will be output
- as is
+def js_dumps(something, predictable=False):
+ """similar as :func:`json_dumps`, except values which are instances of
+ :class:`JSString` are expected to be valid javascript and will be output
+ as is
- >>> js_dumps({'hop': JSString('$.hop'), 'bar': None}, predictable=True)
- '{bar: null, hop: $.hop}'
- >>> js_dumps({'hop': '$.hop'})
- '{hop: "$.hop"}'
- >>> js_dumps({'hip': {'hop': JSString('momo')}})
- '{hip: {hop: momo}}'
- """
- if isinstance(something, dict):
- return _dict2js(something, predictable)
- if isinstance(something, list):
- return _list2js(something, predictable)
- if isinstance(something, JSString):
- return something
- return json_dumps(something)
+ >>> js_dumps({'hop': JSString('$.hop'), 'bar': None}, predictable=True)
+ '{bar: null, hop: $.hop}'
+ >>> js_dumps({'hop': '$.hop'})
+ '{hop: "$.hop"}'
+ >>> js_dumps({'hip': {'hop': JSString('momo')}})
+ '{hip: {hop: momo}}'
+ """
+ if isinstance(something, dict):
+ return _dict2js(something, predictable)
+ if isinstance(something, list):
+ return _list2js(something, predictable)
+ if isinstance(something, JSString):
+ return something
+ return json_dumps(something)
PERCENT_IN_URLQUOTE_RE = re.compile(r'%(?=[0-9a-fA-F]{2})')
def js_href(javascript_code):
diff -r 84738d495ffd -r 793377697c81 view.py
--- a/view.py Wed Sep 24 17:35:59 2014 +0200
+++ b/view.py Wed Sep 24 18:04:30 2014 +0200
@@ -558,14 +558,6 @@
__registry__ = 'adapters'
-class auto_unwrap_bw_compat(type):
- def __new__(mcs, name, bases, classdict):
- cls = type.__new__(mcs, name, bases, classdict)
- if not classdict.get('__needs_bw_compat__'):
- unwrap_adapter_compat(cls)
- return cls
-
-
class EntityAdapter(Adapter):
"""base class for entity adapters (eg adapt an entity to an interface)"""
def __init__(self, _cw, **kwargs):
diff -r 84738d495ffd -r 793377697c81 web/_exceptions.py
--- a/web/_exceptions.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/_exceptions.py Wed Sep 24 18:04:30 2014 +0200
@@ -64,7 +64,6 @@
def __repr__(self):
return '%s(%r, %r)' % (self.__class__.__name__, self.status, self.content)
- self.url = url
# Publish related error
diff -r 84738d495ffd -r 793377697c81 web/action.py
--- a/web/action.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/action.py Wed Sep 24 18:04:30 2014 +0200
@@ -25,43 +25,11 @@
The most important method from a developper point of view in the
:meth:'Action.url' method, which returns a URL on which the navigation
-should directed to perform the action. There are two common ways of
-writing that method:
-
-* do nothing special and simply return a URL to the current rset with
- a special view (with `self._cw.build_url(...)` for instance)
-
-* define an inner function `callback_func(req, *args)` which will do
- the work and call it through `self._cw.user_callback(callback_func,
- args, msg)`: this method will return a URL which calls the inner
- function, and displays the message in the web interface when the
- callback has completed (and report any exception occuring in the
- callback too)
-
-Many examples of the first approach are available in :mod:`cubicweb.web.views.actions`.
-
-Here is an example of the second approach:
-
-.. sourcecode:: python
+should be directed to perform the action. The common way of
+writing that method is to simply return a URL to the current rset with a
+special view (with `self._cw.build_url(...)` for instance)
- from cubicweb.web import action
- class SomeAction(action.Action):
- __regid__ = 'mycube_some_action'
- title = _(some action)
- __select__ = action.Action.__select__ & is_instance('TargetEntity')
-
- def url(self):
- if self.cw_row is None:
- eids = [row[0] for row in self.cw_rset]
- else:
- eids = (self.cw_rset[self.cw_row][self.cw_col or 0],)
- def do_action(req, eids):
- for eid in eids:
- entity = req.entity_from_eid(eid, 'TargetEntity')
- entity.perform_action()
- msg = self._cw._('some_action performed')
- return self._cw.user_callback(do_action, (eids,), msg)
-
+Many examples are available in :mod:`cubicweb.web.views.actions`.
"""
__docformat__ = "restructuredtext en"
diff -r 84738d495ffd -r 793377697c81 web/application.py
--- a/web/application.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/application.py Wed Sep 24 18:04:30 2014 +0200
@@ -34,9 +34,9 @@
from cubicweb import (
ValidationError, Unauthorized, Forbidden,
AuthenticationError, NoSelectableObject,
- BadConnectionId, CW_EVENT_MANAGER)
-from cubicweb.dbapi import DBAPISession, anonymous_session
-from cubicweb.web import LOGGER, component
+ CW_EVENT_MANAGER)
+from cubicweb.repoapi import anonymous_cnx
+from cubicweb.web import LOGGER, component, cors
from cubicweb.web import (
StatusResponse, DirectResponse, Redirect, NotFound, LogOut,
RemoteCallFailed, InvalidSession, RequestError, PublishException)
@@ -50,20 +50,23 @@
@contextmanager
def anonymized_request(req):
- orig_session = req.session
- req.set_session(anonymous_session(req.vreg))
+ orig_cnx = req.cnx
+ anon_clt_cnx = anonymous_cnx(orig_cnx._session.repo)
+ req.set_cnx(anon_clt_cnx)
try:
- yield req
+ with anon_clt_cnx:
+ yield req
finally:
- req.set_session(orig_session)
+ req.set_cnx(orig_cnx)
class AbstractSessionManager(component.Component):
"""manage session data associated to a session identifier"""
__regid__ = 'sessionmanager'
- def __init__(self, vreg):
+ def __init__(self, repo):
+ vreg = repo.vreg
self.session_time = vreg.config['http-session-time'] or None
- self.authmanager = vreg['components'].select('authmanager', vreg=vreg)
+ self.authmanager = vreg['components'].select('authmanager', repo=repo)
interval = (self.session_time or 0) / 2.
if vreg.config.anonymous_user()[0] is not None:
self.cleanup_anon_session_time = vreg.config['cleanup-anonymous-session-time'] or 5 * 60
@@ -84,22 +87,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):
@@ -111,8 +107,7 @@
raise NotImplementedError()
def open_session(self, req):
- """open and return a new session for the given request. The session is
- also bound to the request.
+ """open and return a new session for the given request.
raise :exc:`cubicweb.AuthenticationError` if authentication failed
(no authentication info found or wrong user/password)
@@ -130,8 +125,8 @@
"""authenticate user associated to a request and check session validity"""
__regid__ = 'authmanager'
- def __init__(self, vreg):
- self.vreg = vreg
+ def __init__(self, repo):
+ self.vreg = repo.vreg
def validate_session(self, req, session):
"""check session validity, reconnecting it to the repository if the
@@ -159,9 +154,10 @@
"""a session handler using a cookie to store the session identifier"""
def __init__(self, appli):
+ self.repo = appli.repo
self.vreg = appli.vreg
self.session_manager = self.vreg['components'].select('sessionmanager',
- vreg=self.vreg)
+ repo=self.repo)
global SESSION_MANAGER
SESSION_MANAGER = self.session_manager
if self.vreg.config.mode != 'test':
@@ -173,7 +169,7 @@
def reset_session_manager(self):
data = self.session_manager.dump_data()
self.session_manager = self.vreg['components'].select('sessionmanager',
- vreg=self.vreg)
+ repo=self.repo)
self.session_manager.restore_data(data)
global SESSION_MANAGER
SESSION_MANAGER = self.session_manager
@@ -196,66 +192,40 @@
return '__%s_https_session' % self.vreg.config.appid
return '__%s_session' % self.vreg.config.appid
- def set_session(self, req):
- """associate a session to the request
+ def get_session(self, req):
+ """Return a session object corresponding to credentials held by the req
Session id is searched from :
- # form variable
- cookie
- if no session id is found, open a new session for the connected user
- or request authentification as needed
+ If no session id is found, try opening a new session with credentials
+ found in the request.
- :raise Redirect: if authentication has occurred and succeed
+ Raises AuthenticationError if no session can be found or created.
"""
cookie = req.get_cookie()
sessioncookie = self.session_cookie(req)
try:
sessionid = str(cookie[sessioncookie].value)
- except KeyError: # no session cookie
+ session = self.get_session_by_id(req, sessionid)
+ except (KeyError, InvalidSession): # no valid session cookie
session = self.open_session(req)
- else:
- try:
- session = self.get_session(req, sessionid)
- except InvalidSession:
- # try to open a new session, so we get an anonymous session if
- # allowed
- session = self.open_session(req)
- else:
- if not session.cnx:
- # session exists but is not bound to a connection. We should
- # try to authenticate
- loginsucceed = False
- try:
- if self.open_session(req, allow_no_cnx=False):
- loginsucceed = True
- except Redirect:
- # may be raised in open_session (by postlogin mechanism)
- # on successful connection
- loginsucceed = True
- raise
- except AuthenticationError:
- # authentication failed, continue to use this session
- req.set_session(session)
- finally:
- if loginsucceed:
- # session should be replaced by new session created
- # in open_session
- self.session_manager.close_session(session)
+ return session
- def get_session(self, req, sessionid):
+ def get_session_by_id(self, req, sessionid):
session = self.session_manager.get_session(req, sessionid)
session.mtime = time()
return session
- def open_session(self, req, allow_no_cnx=True):
- session = self.session_manager.open_session(req, allow_no_cnx=allow_no_cnx)
+ def open_session(self, req):
+ session = self.session_manager.open_session(req)
sessioncookie = self.session_cookie(req)
secure = req.https and req.base_url().startswith('https://')
req.set_cookie(sessioncookie, session.sessionid,
maxage=None, secure=secure)
if not session.anonymous_session:
- self.session_manager.postlogin(req)
+ self.session_manager.postlogin(req, session)
return session
def logout(self, req, goto_url):
@@ -277,21 +247,20 @@
The http server will call its main entry point ``application.handle_request``.
.. automethod:: cubicweb.web.application.CubicWebPublisher.main_handle_request
+
+ You have to provide both a repository and web-server config at
+ initialization. In all in one instance both config will be the same.
"""
- def __init__(self, config,
- session_handler_fact=CookieSessionHandler,
- vreg=None):
+ def __init__(self, repo, config, session_handler_fact=CookieSessionHandler):
self.info('starting web instance from %s', config.apphome)
- if vreg is None:
- vreg = cwvreg.CWRegistryStore(config)
- self.vreg = vreg
- # connect to the repository and get instance's schema
- self.repo = config.repository(vreg)
- if not vreg.initialized:
+ self.repo = repo
+ self.vreg = repo.vreg
+ # get instance's schema
+ if not self.vreg.initialized:
config.init_cubes(self.repo.get_cubes())
- vreg.init_properties(self.repo.properties())
- vreg.set_schema(self.repo.get_schema())
+ self.vreg.init_properties(self.repo.properties())
+ self.vreg.set_schema(self.repo.get_schema())
# set the correct publish method
if config['query-log-file']:
from threading import Lock
@@ -310,12 +279,12 @@
self.url_resolver = self.vreg['components'].select('urlpublisher',
vreg=self.vreg)
- def connect(self, req):
- """return a connection for a logged user object according to existing
- sessions (i.e. a new connection may be created or an already existing
- one may be reused
+ def get_session(self, req):
+ """Return a session object corresponding to credentials held by the req
+
+ May raise AuthenticationError.
"""
- self.session_handler.set_session(req)
+ return self.session_handler.get_session(req)
# publish methods #########################################################
@@ -323,6 +292,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:
@@ -362,7 +346,24 @@
req.set_header('WWW-Authenticate', [('Basic', {'realm' : realm })], raw=False)
content = ''
try:
- self.connect(req)
+ try:
+ session = self.get_session(req)
+ from cubicweb import repoapi
+ cnx = repoapi.ClientConnection(session)
+ req.set_cnx(cnx)
+ except AuthenticationError:
+ # Keep the dummy session set at initialisation.
+ # such session with work to an some extend but raise an
+ # AuthenticationError on any database access.
+ import contextlib
+ @contextlib.contextmanager
+ def dummy():
+ yield
+ cnx = dummy()
+ # XXX We want to clean up this approach in the future. But
+ # several cubes like registration or forgotten password rely on
+ # this principle.
+
# DENY https acces for anonymous_user
if (req.https
and req.session.anonymous_session
@@ -373,7 +374,8 @@
# handler
try:
### Try to generate the actual request content
- content = self.core_handle(req, path)
+ with cnx:
+ content = self.core_handle(req, path)
# Handle user log-out
except LogOut as ex:
# When authentification is handled by cookie the code that
@@ -421,6 +423,7 @@
content = self.need_login_content(req)
return content
+
def core_handle(self, req, path):
"""method called by the main publisher to process
@@ -446,6 +449,8 @@
try:
### standard processing of the request
try:
+ # apply CORS sanity checks
+ cors.process_request(req, self.vreg.config)
ctrlid, rset = self.url_resolver.process(req, path)
try:
controller = self.vreg['controllers'].select(ctrlid, req,
@@ -454,6 +459,10 @@
raise Unauthorized(req._('not authorized'))
req.update_search_state()
result = controller.publish(rset=rset)
+ except cors.CORSPreflight:
+ # Return directly an empty 200
+ req.status_out = 200
+ result = ''
except StatusResponse as ex:
warn('[3.16] StatusResponse is deprecated use req.status_out',
DeprecationWarning, stacklevel=2)
@@ -479,7 +488,7 @@
except Unauthorized as ex:
req.data['errmsg'] = req._('You\'re not authorized to access this page. '
'If you think you should, please contact the site administrator.')
- req.status_out = httplib.UNAUTHORIZED
+ req.status_out = httplib.FORBIDDEN
result = self.error_handler(req, ex, tb=False)
except Forbidden as ex:
req.data['errmsg'] = req._('This action is forbidden. '
@@ -506,9 +515,6 @@
req.cnx.rollback()
except Exception:
pass # ignore rollback error at this point
- # request may be referenced by "onetime callback", so clear its entity
- # cache to avoid memory usage
- req.drop_entity_cache()
self.add_undo_link_to_msg(req)
self.debug('query %s executed in %s sec', req.relative_path(), clock() - tstart)
return result
diff -r 84738d495ffd -r 793377697c81 web/captcha.py
--- a/web/captcha.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/captcha.py Wed Sep 24 18:04:30 2014 +0200
@@ -24,7 +24,7 @@
from random import randint, choice
from cStringIO import StringIO
-import Image, ImageFont, ImageDraw, ImageFilter
+from PIL import Image, ImageFont, ImageDraw, ImageFilter
from time import time
diff -r 84738d495ffd -r 793377697c81 web/component.py
--- a/web/component.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/component.py Wed Sep 24 18:04:30 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.
@@ -508,25 +508,27 @@
class EditRelationMixIn(ReloadableMixIn):
- def box_item(self, entity, etarget, rql, label):
+
+ def box_item(self, entity, etarget, fname, label):
"""builds HTML link to edit relation between `entity` and `etarget`"""
- args = {role(self)[0] : entity.eid, target(self)[0] : etarget.eid}
- url = self._cw.user_rql_callback((rql, args))
+ args = {role(self) : entity.eid, target(self): etarget.eid}
# for each target, provide a link to edit the relation
- return u'[%s ] %s' % (
- xml_escape(url), label, etarget.view('incontext'))
+ jscall = js.cw.utils.callAjaxFuncThenReload(fname,
+ self.rtype,
+ args['subject'],
+ args['object'])
+ return u'[%s ] %s' % (
+ xml_escape(unicode(jscall)), label, etarget.view('incontext'))
def related_boxitems(self, entity):
- rql = 'DELETE S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
- return [self.box_item(entity, etarget, rql, u'-')
+ return [self.box_item(entity, etarget, 'delete_relation', u'-')
for etarget in self.related_entities(entity)]
def related_entities(self, entity):
return entity.related(self.rtype, role(self), entities=True)
def unrelated_boxitems(self, entity):
- rql = 'SET S %s O WHERE S eid %%(s)s, O eid %%(o)s' % self.rtype
- return [self.box_item(entity, etarget, rql, u'+')
+ return [self.box_item(entity, etarget, 'add_relation', u'+')
for etarget in self.unrelated_entities(entity)]
def unrelated_entities(self, entity):
diff -r 84738d495ffd -r 793377697c81 web/cors.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/cors.py Wed Sep 24 18:04:30 2014 +0200
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+# copyright 2014 Logilab, PARIS
+
+"""A set of utility functions to handle CORS requests
+
+Unless specified, all references in this file are related to:
+ http://www.w3.org/TR/cors
+
+The provided implementation roughly follows:
+ http://www.html5rocks.com/static/images/cors_server_flowchart.png
+
+See also:
+ https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
+
+"""
+
+import urlparse
+
+from cubicweb.web import LOGGER
+info = LOGGER.info
+
+class CORSFailed(Exception):
+ """Raised when cross origin resource sharing checks failed"""
+
+
+class CORSPreflight(Exception):
+ """Raised when cross origin resource sharing checks detects the
+ request as a valid preflight request"""
+
+
+def process_request(req, config):
+ """
+ Process a request to apply CORS specification algorithms
+
+ Check whether the CORS specification is respected and set corresponding
+ headers to ensure response complies with the specification.
+
+ In case of non-compliance, no CORS-related header is set.
+ """
+ base_url = urlparse.urlsplit(req.base_url())
+ expected_host = '://'.join((base_url.scheme, base_url.netloc))
+ if not req.get_header('Origin') or req.get_header('Origin') == expected_host:
+ # not a CORS request, nothing to do
+ return
+ try:
+ # handle cross origin resource sharing (CORS)
+ if req.http_method() == 'OPTIONS':
+ if req.get_header('Access-Control-Request-Method'):
+ # preflight CORS request
+ process_preflight(req, config)
+ else: # Simple CORS or actual request
+ process_simple(req, config)
+ except CORSFailed, exc:
+ info('Cross origin resource sharing failed: %s' % exc)
+ except CORSPreflight:
+ info('Cross origin resource sharing: valid Preflight request %s')
+ raise
+
+def process_preflight(req, config):
+ """cross origin resource sharing (preflight)
+ Cf http://www.w3.org/TR/cors/#resource-preflight-requests
+ """
+ origin = check_origin(req, config)
+ allowed_methods = set(config['access-control-allow-methods'])
+ allowed_headers = set(config['access-control-allow-headers'])
+ try:
+ method = req.get_header('Access-Control-Request-Method')
+ except ValueError:
+ raise CORSFailed('Access-Control-Request-Method is incorrect')
+ if method not in allowed_methods:
+ raise CORSFailed('Method is not allowed')
+ try:
+ req.get_header('Access-Control-Request-Headers', ())
+ except ValueError:
+ raise CORSFailed('Access-Control-Request-Headers is incorrect')
+ req.set_header('Access-Control-Allow-Methods', allowed_methods, raw=False)
+ req.set_header('Access-Control-Allow-Headers', allowed_headers, raw=False)
+
+ process_common(req, config, origin)
+ raise CORSPreflight()
+
+def process_simple(req, config):
+ """Handle the Simple Cross-Origin Request case
+ """
+ origin = check_origin(req, config)
+ exposed_headers = config['access-control-expose-headers']
+ if exposed_headers:
+ req.set_header('Access-Control-Expose-Headers', exposed_headers, raw=False)
+ process_common(req, config, origin)
+
+def process_common(req, config, origin):
+ req.set_header('Access-Control-Allow-Origin', origin)
+ # in CW, we always support credential/authentication
+ req.set_header('Access-Control-Allow-Credentials', 'true')
+
+def check_origin(req, config):
+ origin = req.get_header('Origin').lower()
+ allowed_origins = config.get('access-control-allow-origin')
+ if not allowed_origins:
+ raise CORSFailed('access-control-allow-origin is not configured')
+ if '*' not in allowed_origins and origin not in allowed_origins:
+ raise CORSFailed('Origin is not allowed')
+ # bit of sanity check; see "6.3 Security"
+ myhost = urlparse.urlsplit(req.base_url()).netloc
+ host = req.get_header('Host')
+ if host != myhost:
+ info('cross origin resource sharing detected possible '
+ 'DNS rebinding attack Host header != host of base_url: '
+ '%s != %s' % (host, myhost))
+ raise CORSFailed('Host header and hostname do not match')
+ # include "Vary: Origin" header (see 6.4)
+ req.set_header('Vary', 'Origin')
+ return origin
+
diff -r 84738d495ffd -r 793377697c81 web/data/cubicweb.ajax.js
--- a/web/data/cubicweb.ajax.js Wed Sep 24 17:35:59 2014 +0200
+++ b/web/data/cubicweb.ajax.js Wed Sep 24 18:04:30 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.
@@ -312,7 +312,7 @@
$.extend(form, {
'fname': fname,
'pageid': pageid,
- 'arg': $.map(cw.utils.sliceList(arguments, 2), jQuery.toJSON)
+ 'arg': $.map(cw.utils.sliceList(arguments, 2), JSON.stringify)
});
return form;
}
@@ -338,7 +338,6 @@
} else if (this.size() < 1) {
cw.log('loadxhtml called without an element');
}
- var callback = null;
var node = this.get(0); // only consider the first element
if (cursor) {
setProgressCursor();
@@ -362,9 +361,6 @@
jQuery(node).append(domnode);
}
_postAjaxLoad(node);
- while (jQuery.isFunction(callback)) {
- callback = callback.apply(this, [domnode]);
- }
});
d.addErrback(remoteCallFailed);
if (cursor) {
@@ -521,16 +517,20 @@
});
}
-function userCallback(cbname) {
+userCallback = cw.utils.deprecatedFunction(
+ '[3.19] use a plain ajaxfunc instead of user callbacks',
+ function userCallback(cbname) {
setProgressCursor();
var d = loadRemote(AJAX_BASE_URL, ajaxFuncArgs('user_callback', null, cbname));
d.addCallback(resetCursor);
d.addErrback(resetCursor);
d.addErrback(remoteCallFailed);
return d;
-}
+});
-function userCallbackThenUpdateUI(cbname, compid, rql, msg, registry, nodeid) {
+userCallbackThenUpdateUI = cw.utils.deprecatedFunction(
+ '[3.19] use a plain ajaxfunc instead of user callbacks',
+ function userCallbackThenUpdateUI(cbname, compid, rql, msg, registry, nodeid) {
var d = userCallback(cbname);
d.addCallback(function() {
$('#' + nodeid).loadxhtml(AJAX_BASE_URL, ajaxFuncArgs('render', {'rql': rql},
@@ -539,9 +539,11 @@
updateMessage(msg);
}
});
-}
+});
-function userCallbackThenReloadPage(cbname, msg) {
+userCallbackThenReloadPage = cw.utils.deprecatedFunction(
+ '[3.19] use a plain ajaxfunc instead of user callbacks',
+ function userCallbackThenReloadPage(cbname, msg) {
var d = userCallback(cbname);
d.addCallback(function() {
window.location.reload();
@@ -549,7 +551,7 @@
updateMessage(msg);
}
});
-}
+});
/**
* .. function:: unregisterUserCallback(cbname)
@@ -557,14 +559,17 @@
* unregisters the python function registered on the server's side
* while the page was generated.
*/
-function unregisterUserCallback(cbname) {
+unregisterUserCallback = cw.utils.deprecatedFunction(
+ '[3.19] use a plain ajaxfunc instead of user callbacks',
+ function unregisterUserCallback(cbname) {
setProgressCursor();
var d = loadRemote(AJAX_BASE_URL, ajaxFuncArgs('unregister_user_callback',
null, cbname));
d.addCallback(resetCursor);
d.addErrback(resetCursor);
d.addErrback(remoteCallFailed);
-}
+});
+
//============= XXX move those functions? ====================================//
function openHash() {
@@ -749,7 +754,7 @@
var props = {
fname: fname,
pageid: pageid,
- arg: $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
+ arg: $.map(cw.utils.sliceList(arguments, 1), JSON.stringify)
};
var result = jQuery.ajax({
url: AJAX_BASE_URL,
@@ -769,7 +774,7 @@
var props = {
fname: fname,
pageid: pageid,
- arg: $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON)
+ arg: $.map(cw.utils.sliceList(arguments, 1), JSON.stringify)
};
// XXX we should inline the content of loadRemote here
var deferred = loadRemote(AJAX_BASE_URL, props, 'POST');
diff -r 84738d495ffd -r 793377697c81 web/data/cubicweb.edition.js
--- a/web/data/cubicweb.edition.js Wed Sep 24 17:35:59 2014 +0200
+++ b/web/data/cubicweb.edition.js Wed Sep 24 18:04:30 2014 +0200
@@ -26,7 +26,7 @@
var args = {
fname: 'prop_widget',
pageid: pageid,
- arg: $.map([key, varname, tabindex], jQuery.toJSON)
+ arg: $.map([key, varname, tabindex], JSON.stringify)
};
cw.jqNode('div:value:' + varname).loadxhtml(AJAX_BASE_URL, args, 'post');
}
@@ -328,7 +328,7 @@
_postAjaxLoad(dom);
});
d.addErrback(function(xxx) {
- log('xxx =', xxx);
+ cw.log('xxx =', xxx);
});
}
diff -r 84738d495ffd -r 793377697c81 web/data/cubicweb.js
--- a/web/data/cubicweb.js Wed Sep 24 17:35:59 2014 +0200
+++ b/web/data/cubicweb.js Wed Sep 24 18:04:30 2014 +0200
@@ -100,7 +100,8 @@
return $node.text();
}
return cw.evalJSON(sortvalue);
- }
+ },
+
});
@@ -384,11 +385,19 @@
*/
strFuncCall: function(fname /* ...*/) {
return (fname + '(' +
- $.map(cw.utils.sliceList(arguments, 1), jQuery.toJSON).join(',')
+ $.map(cw.utils.sliceList(arguments, 1), JSON.stringify).join(',')
+ ')'
);
+ },
+
+ callAjaxFuncThenReload: function callAjaxFuncThenReload (/*...*/) {
+ var d = asyncRemoteExec.apply(null, arguments);
+ d.addCallback(function(msg) {
+ window.location.reload();
+ if (msg)
+ updateMessage(msg);
+ });
}
-
});
/** DOM factories ************************************************************/
diff -r 84738d495ffd -r 793377697c81 web/data/cubicweb.old.css
--- a/web/data/cubicweb.old.css Wed Sep 24 17:35:59 2014 +0200
+++ b/web/data/cubicweb.old.css Wed Sep 24 18:04:30 2014 +0200
@@ -265,32 +265,48 @@
/* header */
table#header {
- background: %(headerBg)s;
+ background-image: linear-gradient(white, #e2e2e2);
width: 100%;
+ border-bottom: 1px solid #bbb;
+ text-shadow: 1px 1px 0 #f5f5f5;
}
table#header td {
vertical-align: middle;
}
-table#header a {
- color: #000;
+table#header, table#header a {
+ color: #444;
}
+
table#header td#headtext {
white-space: nowrap;
+ padding: 0 10px;
+ width: 10%;
+}
+
+#logo{
+ width: 150px;
+ height: 42px;
+ background-image: url(logo-cubicweb.svg);
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: contain;
+ float: left;
}
table#header td#header-right {
- padding-top: 1em;
white-space: nowrap;
+ width: 10%;
}
table#header td#header-center{
- width: 100%;
+ border-bottom-left-radius: 10px;
+ border-top-left-radius: 10px;
+ padding-left: 1em;
}
span#appliName {
font-weight: bold;
- color: #000;
white-space: nowrap;
}
@@ -642,6 +658,8 @@
div#userActionsBox {
width: 14em;
text-align: right;
+ display: inline-block;
+ padding-right: 10px;
}
div#userActionsBox a.popupMenu {
diff -r 84738d495ffd -r 793377697c81 web/data/favicon.ico
Binary file web/data/favicon.ico has changed
diff -r 84738d495ffd -r 793377697c81 web/data/jquery.json.js
--- a/web/data/jquery.json.js Wed Sep 24 17:35:59 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-(function($){function toIntegersAtLease(n)
-{return n<10?'0'+n:n;}
-Date.prototype.toJSON=function(date)
-{return date.getUTCFullYear()+'-'+
-toIntegersAtLease(date.getUTCMonth()+1)+'-'+
-toIntegersAtLease(date.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'}
-$.quoteString=function(string)
-{if(escapeable.test(string))
-{return'"'+string.replace(escapeable,function(a)
-{var c=meta[a];if(typeof c==='string'){return c;}
-c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"'}
-return'"'+string+'"';}
-$.toJSON=function(o)
-{var type=typeof(o);if(type=="undefined")
-return"undefined";else if(type=="number"||type=="boolean")
-return o+"";else if(o===null)
-return"null";if(type=="string")
-{return $.quoteString(o);}
-if(type=="object"&&typeof o.toJSON=="function")
-return o.toJSON();if(type!="function"&&typeof(o.length)=="number")
-{var ret=[];for(var i=0;i
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 84738d495ffd -r 793377697c81 web/data/logo-cubicweb-icon.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/data/logo-cubicweb-icon.svg Wed Sep 24 18:04:30 2014 +0200
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 84738d495ffd -r 793377697c81 web/data/logo-cubicweb-text.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/data/logo-cubicweb-text.svg Wed Sep 24 18:04:30 2014 +0200
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 84738d495ffd -r 793377697c81 web/data/logo-cubicweb.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/data/logo-cubicweb.svg Wed Sep 24 18:04:30 2014 +0200
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 84738d495ffd -r 793377697c81 web/data/uiprops.py
--- a/web/data/uiprops.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/data/uiprops.py Wed Sep 24 18:04:30 2014 +0200
@@ -10,7 +10,6 @@
# Javascripts files to include systematically in HTML headers
JAVASCRIPTS = [data('jquery.js'),
data('jquery-migrate.js'),
- data('jquery.json.js'),
data('cubicweb.js'),
data('cubicweb.compat.js'),
data('cubicweb.python.js'),
diff -r 84738d495ffd -r 793377697c81 web/facet.py
--- a/web/facet.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/facet.py Wed Sep 24 18:04:30 2014 +0200
@@ -34,6 +34,9 @@
.. autoclass:: cubicweb.web.facet.RangeFacet
.. autoclass:: cubicweb.web.facet.DateRangeFacet
.. autoclass:: cubicweb.web.facet.BitFieldFacet
+.. autoclass:: cubicweb.web.facet.AbstractRangeRQLPathFacet
+.. autoclass:: cubicweb.web.facet.RangeRQLPathFacet
+.. autoclass:: cubicweb.web.facet.DateRangeRQLPathFacet
Classes for facets implementor
------------------------------
@@ -1300,7 +1303,6 @@
self.target_attr_type, operator)
-
class DateRangeFacet(RangeFacet):
"""This class works similarly as the :class:`RangeFacet` but for attribute
of date type.
@@ -1324,6 +1326,110 @@
return '"%s"' % ustrftime(date_value, '%Y/%m/%d')
+class AbstractRangeRQLPathFacet(RQLPathFacet):
+ """
+ The :class:`AbstractRangeRQLPathFacet` is the base class for
+ RQLPathFacet-type facets allowing the use of RangeWidgets-like
+ widgets (such as (:class:`FacetRangeWidget`,
+ class:`DateFacetRangeWidget`) on the parent :class:`RQLPathFacet`
+ target attribute.
+ """
+ __abstract__ = True
+
+ def vocabulary(self):
+ """return vocabulary for this facet, eg a list of (label,
+ value)"""
+ select = self.select
+ select.save_state()
+ try:
+ filtered_variable = self.filtered_variable
+ cleanup_select(select, filtered_variable)
+ varmap, restrvar = self.add_path_to_select()
+ if self.label_variable:
+ attrvar = varmap[self.label_variable]
+ else:
+ attrvar = restrvar
+ # start RangeRQLPathFacet
+ minf = nodes.Function('MIN')
+ minf.append(nodes.VariableRef(restrvar))
+ select.add_selected(minf)
+ maxf = nodes.Function('MAX')
+ maxf.append(nodes.VariableRef(restrvar))
+ select.add_selected(maxf)
+ # add is restriction if necessary
+ if filtered_variable.stinfo['typerel'] is None:
+ etypes = frozenset(sol[filtered_variable.name] for sol in select.solutions)
+ select.add_type_restriction(filtered_variable, etypes)
+ # end RangeRQLPathFacet
+ try:
+ rset = self.rqlexec(select.as_string(), self.cw_rset.args)
+ except Exception:
+ self.exception('error while getting vocabulary for %s, rql: %s',
+ self, select.as_string())
+ return ()
+ finally:
+ select.recover()
+ # don't call rset_vocabulary on empty result set, it may be an empty
+ # *list* (see rqlexec implementation)
+ if rset:
+ minv, maxv = rset[0]
+ return [(unicode(minv), minv), (unicode(maxv), maxv)]
+ return []
+
+
+ def possible_values(self):
+ """return a list of possible values (as string since it's used to
+ compare to a form value in javascript) for this facet
+ """
+ return [strval for strval, val in self.vocabulary()]
+
+ def add_rql_restrictions(self):
+ infvalue = self.infvalue()
+ supvalue = self.supvalue()
+ if infvalue is None or supvalue is None: # nothing sent
+ return
+ varmap, restrvar = self.add_path_to_select(
+ skiplabel=True, skipattrfilter=True)
+ restrel = None
+ for part in self.path:
+ if isinstance(part, basestring):
+ part = part.split()
+ subject, rtype, object = part
+ if object == self.filter_variable:
+ restrel = rtype
+ assert restrel
+ # when a value is equal to one of the limit, don't add the restriction,
+ # else we filter out NULL values implicitly
+ if infvalue != self.infvalue(min=True):
+
+ self._add_restriction(infvalue, '>=', restrvar, restrel)
+ if supvalue != self.supvalue(max=True):
+ self._add_restriction(supvalue, '<=', restrvar, restrel)
+
+ def _add_restriction(self, value, operator, restrvar, restrel):
+ self.select.add_constant_restriction(restrvar,
+ restrel,
+ self.formatvalue(value),
+ self.target_attr_type, operator)
+
+
+class RangeRQLPathFacet(AbstractRangeRQLPathFacet, RQLPathFacet):
+ """
+ The :class:`RangeRQLPathFacet` uses the :class:`FacetRangeWidget`
+ on the :class:`AbstractRangeRQLPathFacet` target attribute
+ """
+ pass
+
+
+class DateRangeRQLPathFacet(AbstractRangeRQLPathFacet, DateRangeFacet):
+ """
+ The :class:`DateRangeRQLPathFacet` uses the
+ :class:`DateFacetRangeWidget` on the
+ :class:`AbstractRangeRQLPathFacet` target attribute
+ """
+ pass
+
+
class HasRelationFacet(AbstractFacet):
"""This class simply filter according to the presence of a relation
(whatever the entity at the other end). It display a simple checkbox that
diff -r 84738d495ffd -r 793377697c81 web/formfields.py
--- a/web/formfields.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/formfields.py Wed Sep 24 18:04:30 2014 +0200
@@ -1033,6 +1033,10 @@
# while it has no value, hence generating a false error.
return list(self.fields)
+ @property
+ def needs_multipart(self):
+ return any(f.needs_multipart for f in self.fields)
+
class RelationField(Field):
"""Use this field to edit a relation of an entity.
diff -r 84738d495ffd -r 793377697c81 web/formwidgets.py
--- a/web/formwidgets.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/formwidgets.py Wed Sep 24 18:04:30 2014 +0200
@@ -34,6 +34,7 @@
.. autoclass:: cubicweb.web.formwidgets.HiddenInput
.. autoclass:: cubicweb.web.formwidgets.TextInput
+.. autoclass:: cubicweb.web.formwidgets.EmailInput
.. autoclass:: cubicweb.web.formwidgets.PasswordSingleInput
.. autoclass:: cubicweb.web.formwidgets.FileInput
.. autoclass:: cubicweb.web.formwidgets.ButtonInput
@@ -314,6 +315,11 @@
type = 'text'
+class EmailInput(Input):
+ """Simple , will return a unicode string."""
+ type = 'email'
+
+
class PasswordSingleInput(Input):
"""Simple , will return a utf-8 encoded string.
diff -r 84738d495ffd -r 793377697c81 web/htmlwidgets.py
--- a/web/htmlwidgets.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/htmlwidgets.py Wed Sep 24 18:04:30 2014 +0200
@@ -153,8 +153,6 @@
else:
return u'' % self.liclass
- return self.label
-
def _render(self):
self.w(u'%s%s ' % (self._start_li(), self.label))
diff -r 84738d495ffd -r 793377697c81 web/http_headers.py
--- a/web/http_headers.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/http_headers.py Wed Sep 24 18:04:30 2014 +0200
@@ -8,6 +8,7 @@
from calendar import timegm
import base64
import re
+import urlparse
def dashCapitalize(s):
''' Capitalize a string, making sure to treat - as a word seperator '''
@@ -27,11 +28,11 @@
def casemappingify(d):
global header_case_mapping
- newd = dict([(key.lower(),key) for key in d])
+ newd = dict([(key.lower(), key) for key in d])
header_case_mapping.update(newd)
def lowerify(d):
- return dict([(key.lower(),value) for key,value in d.items()])
+ return dict([(key.lower(), value) for key, value in d.items()])
class HeaderHandler(object):
@@ -73,13 +74,13 @@
try:
for p in parser:
- # print "Parsing %s: %s(%s)" % (name, repr(p), repr(h))
+ #print "==> Parsing %s: %s(%s)" % (name, repr(p), repr(header))
header = p(header)
# if isinstance(h, types.GeneratorType):
- # h=list(h)
+ # h = list(h)
except ValueError as v:
# print v
- header=None
+ header = None
return header
@@ -187,7 +188,7 @@
# Two digit year, yucko.
day, month, year = parts[1].split('-')
time = parts[2]
- year=int(year)
+ year = int(year)
if year < 69:
year = year + 2000
elif year < 100:
@@ -242,8 +243,8 @@
Takes a raw header value (list of strings), and
Returns a generator of strings and Token class instances.
"""
- tokens=http_tokens
- ctls=http_ctls
+ tokens = http_tokens
+ ctls = http_ctls
string = ",".join(header)
list = []
@@ -265,7 +266,7 @@
elif x == '"':
quoted = False
yield qstring+string[start:cur]
- qstring=None
+ qstring = None
start = cur+1
elif x in tokens:
if start != cur:
@@ -339,7 +340,7 @@
hurt anything, in any case.
"""
- l=[]
+ l = []
for x in seq:
if not isinstance(x, Token):
l.append(x)
@@ -353,16 +354,16 @@
def parseKeyValue(val):
if len(val) == 1:
- return val[0],None
+ return val[0], None
elif len(val) == 3 and val[1] == Token('='):
- return val[0],val[2]
+ return val[0], val[2]
raise ValueError, "Expected key or key=value, but got %s." % (val,)
def parseArgs(field):
- args=split(field, Token(';'))
+ args = split(field, Token(';'))
val = args.next()
args = [parseKeyValue(arg) for arg in args]
- return val,args
+ return val, args
def listParser(fun):
"""Return a function which applies 'fun' to every element in the
@@ -377,8 +378,44 @@
def last(seq):
"""Return seq[-1]"""
+ return seq[-1]
- return seq[-1]
+def unique(seq):
+ '''if seq is not a string, check it's a sequence of one element and return it'''
+ if isinstance(seq, basestring):
+ return seq
+ if len(seq) != 1:
+ raise ValueError('single value required, not %s' % seq)
+ return seq[0]
+
+def parseHTTPMethod(method):
+ """Ensure a HTTP method is valid according the rfc2616, but extension-method ones"""
+ method = method.strip()
+ if method not in ("OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE",
+ "TRACE", "CONNECT"):
+ raise ValueError('Unsupported HTTP method %s' % method)
+ return method
+
+def parseAllowOrigin(origin):
+ """Ensure origin is a valid URL-base stuff, or null"""
+ if origin == 'null':
+ return origin
+ p = urlparse.urlparse(origin)
+ if p.params or p.query or p.username or p.path not in ('', '/'):
+ raise ValueError('Incorrect Accept-Control-Allow-Origin value %s' % origin)
+ if p.scheme not in ('http', 'https'):
+ raise ValueError('Unsupported Accept-Control-Allow-Origin URL scheme %s' % origin)
+ if not p.netloc:
+ raise ValueError('Accept-Control-Allow-Origin: host name cannot be unset (%s)' % origin)
+ return origin
+
+def parseAllowCreds(cred):
+ """Can be "true" """
+ if cred:
+ cred = cred.lower()
+ if cred and cred != 'true':
+ raise ValueError('Accept-Control-Allow-Credentials can only be "true" (%s)' % cred)
+ return cred
##### Generation utilities
def quoteString(s):
@@ -401,11 +438,11 @@
def generateKeyValues(kvs):
l = []
# print kvs
- for k,v in kvs:
+ for k, v in kvs:
if v is None:
l.append('%s' % k)
else:
- l.append('%s=%s' % (k,v))
+ l.append('%s=%s' % (k, v))
return ";".join(l)
@@ -453,7 +490,7 @@
##### Specific header parsers.
def parseAccept(field):
- type,args = parseArgs(field)
+ type, args = parseArgs(field)
if len(type) != 3 or type[1] != Token('/'):
raise ValueError, "MIME Type "+str(type)+" invalid."
@@ -465,30 +502,30 @@
num = 0
for arg in args:
if arg[0] == 'q':
- mimeparams=tuple(args[0:num])
- params=args[num:]
+ mimeparams = tuple(args[0:num])
+ params = args[num:]
break
num = num + 1
else:
- mimeparams=tuple(args)
- params=[]
+ mimeparams = tuple(args)
+ params = []
# Default values for parameters:
qval = 1.0
# Parse accept parameters:
for param in params:
- if param[0] =='q':
+ if param[0] == 'q':
qval = float(param[1])
else:
# Warn? ignored parameter.
pass
- ret = MimeType(type[0],type[2],mimeparams),qval
+ ret = MimeType(type[0], type[2], mimeparams), qval
return ret
def parseAcceptQvalue(field):
- type,args=parseArgs(field)
+ type, args = parseArgs(field)
type = checkSingleToken(type)
@@ -496,7 +533,7 @@
for arg in args:
if arg[0] == 'q':
qvalue = float(arg[1])
- return type,qvalue
+ return type, qvalue
def addDefaultCharset(charsets):
if charsets.get('*') is None and charsets.get('iso-8859-1') is None:
@@ -516,7 +553,7 @@
# Content-Type: multipart/form-data; boundary=CaSeFuLsTuFf
# So, we need to explicitly .lower() the type/subtype and arg keys.
- type,args = parseArgs(header)
+ type, args = parseArgs(header)
if len(type) != 3 or type[1] != Token('/'):
raise ValueError, "MIME Type "+str(type)+" invalid."
@@ -535,14 +572,14 @@
"""Parse a content-range header into (kind, start, end, realLength).
realLength might be None if real length is not known ('*').
- start and end might be None if start,end unspecified (for response code 416)
+ start and end might be None if start, end unspecified (for response code 416)
"""
kind, other = header.strip().split()
if kind.lower() != "bytes":
raise ValueError("a range of type %r is not supported")
startend, realLength = other.split("/")
if startend.strip() == '*':
- start,end=None,None
+ start, end = None, None
else:
start, end = map(int, startend.split("-"))
if realLength == "*":
@@ -552,9 +589,9 @@
return (kind, start, end, realLength)
def parseExpect(field):
- type,args=parseArgs(field)
+ type, args = parseArgs(field)
- type=parseKeyValue(type)
+ type = parseKeyValue(type)
return (type[0], (lambda *args:args)(type[1], *args))
def parseExpires(header):
@@ -586,16 +623,16 @@
if len(range) < 3 or range[1] != Token('='):
raise ValueError("Invalid range header format: %s" %(range,))
- type=range[0]
+ type = range[0]
if type != 'bytes':
raise ValueError("Unknown range unit: %s." % (type,))
- rangeset=split(range[2:], Token(','))
+ rangeset = split(range[2:], Token(','))
ranges = []
for byterangespec in rangeset:
if len(byterangespec) != 1:
raise ValueError("Invalid range header format: %s" % (range,))
- start,end=byterangespec[0].split('-')
+ start, end = byterangespec[0].split('-')
if not start and not end:
raise ValueError("Invalid range header format: %s" % (range,))
@@ -612,8 +649,8 @@
if start and end and start > end:
raise ValueError("Invalid range header, start > end: %s" % (range,))
- ranges.append((start,end))
- return type,ranges
+ ranges.append((start, end))
+ return type, ranges
def parseRetryAfter(header):
try:
@@ -676,9 +713,9 @@
#### Header generators
def generateAccept(accept):
- mimeType,q = accept
+ mimeType, q = accept
- out="%s/%s"%(mimeType.mediaType, mimeType.mediaSubtype)
+ out ="%s/%s"%(mimeType.mediaType, mimeType.mediaSubtype)
if mimeType.params:
out+=';'+generateKeyValues(mimeType.params.iteritems())
@@ -724,7 +761,7 @@
# quoted list of values
v = quoteString(generateList(
[header_case_mapping.get(name) or dashCapitalize(name) for name in v]))
- return '%s=%s' % (k,v)
+ return '%s=%s' % (k, v)
def generateContentRange(tup):
"""tup is (type, start, end, len)
@@ -767,7 +804,7 @@
return ''
return s
- type,ranges=range
+ type, ranges = range
if type != 'bytes':
raise ValueError("Unknown range unit: "+type+".")
@@ -781,9 +818,9 @@
return str(int(when - time.time()))
def generateContentType(mimeType):
- out="%s/%s"%(mimeType.mediaType, mimeType.mediaSubtype)
+ out = "%s/%s" % (mimeType.mediaType, mimeType.mediaSubtype)
if mimeType.params:
- out+=';'+generateKeyValues(mimeType.params.iteritems())
+ out += ';' + generateKeyValues(mimeType.params.iteritems())
return out
def generateIfRange(dateOrETag):
@@ -804,7 +841,7 @@
try:
l = []
- for k,v in dict(challenge).iteritems():
+ for k, v in dict(challenge).iteritems():
l.append("%s=%s" % (k, quoteString(v)))
_generated.append("%s %s" % (scheme, ", ".join(l)))
@@ -849,7 +886,7 @@
return "Etag(%r, weak=%r)" % (self.tag, self.weak)
def parse(tokens):
- tokens=tuple(tokens)
+ tokens = tuple(tokens)
if len(tokens) == 1 and not isinstance(tokens[0], Token):
return ETag(tokens[0])
@@ -859,7 +896,7 @@
raise ValueError("Invalid ETag.")
- parse=staticmethod(parse)
+ parse = staticmethod(parse)
def generate(self):
if self.weak:
@@ -868,14 +905,14 @@
return quoteString(self.tag)
def parseStarOrETag(tokens):
- tokens=tuple(tokens)
+ tokens = tuple(tokens)
if tokens == ('*',):
return '*'
else:
return ETag.parse(tokens)
def generateStarOrETag(etag):
- if etag=='*':
+ if etag == '*':
return etag
else:
return etag.generate()
@@ -885,20 +922,20 @@
# __slots__ = ['name', 'value', 'path', 'domain', 'ports', 'expires', 'discard', 'secure', 'comment', 'commenturl', 'version']
def __init__(self, name, value, path=None, domain=None, ports=None, expires=None, discard=False, secure=False, comment=None, commenturl=None, version=0):
- self.name=name
- self.value=value
- self.path=path
- self.domain=domain
- self.ports=ports
- self.expires=expires
- self.discard=discard
- self.secure=secure
- self.comment=comment
- self.commenturl=commenturl
- self.version=version
+ self.name = name
+ self.value = value
+ self.path = path
+ self.domain = domain
+ self.ports = ports
+ self.expires = expires
+ self.discard = discard
+ self.secure = secure
+ self.comment = comment
+ self.commenturl = commenturl
+ self.version = version
def __repr__(self):
- s="Cookie(%r=%r" % (self.name, self.value)
+ s = "Cookie(%r=%r" % (self.name, self.value)
if self.path is not None: s+=", path=%r" % (self.path,)
if self.domain is not None: s+=", domain=%r" % (self.domain,)
if self.ports is not None: s+=", ports=%r" % (self.ports,)
@@ -941,7 +978,7 @@
header = ';'.join(headers)
if header[0:8].lower() == "$version":
# RFC2965 cookie
- h=tokenize([header], foldCase=False)
+ h = tokenize([header], foldCase=False)
r_cookies = split(h, Token(','))
for r_cookie in r_cookies:
last_cookie = None
@@ -954,20 +991,20 @@
(name,), = nameval
value = None
- name=name.lower()
+ name = name.lower()
if name == '$version':
continue
if name[0] == '$':
if last_cookie is not None:
if name == '$path':
- last_cookie.path=value
+ last_cookie.path = value
elif name == '$domain':
- last_cookie.domain=value
+ last_cookie.domain = value
elif name == '$port':
if value is None:
last_cookie.ports = ()
else:
- last_cookie.ports=tuple([int(s) for s in value.split(',')])
+ last_cookie.ports = tuple([int(s) for s in value.split(',')])
else:
last_cookie = Cookie(name, value, version=1)
cookies.append(last_cookie)
@@ -978,9 +1015,9 @@
# however.
r_cookies = header.split(';')
for r_cookie in r_cookies:
- name,value = r_cookie.split('=', 1)
- name=name.strip(' \t')
- value=value.strip(' \t')
+ name, value = r_cookie.split('=', 1)
+ name = name.strip(' \t')
+ value = value.strip(' \t')
cookies.append(Cookie(name, value))
@@ -1048,7 +1085,7 @@
if cookie_validname_re.match(cookie.name) is None:
continue
- value=cookie.value
+ value = cookie.value
if cookie_validvalue_re.match(cookie.value) is None:
value = quoteString(value)
@@ -1078,13 +1115,13 @@
for part in parts:
namevalue = part.split('=',1)
if len(namevalue) == 1:
- name=namevalue[0]
- value=None
+ name = namevalue[0]
+ value = None
else:
- name,value=namevalue
- value=value.strip(' \t')
+ name, value = namevalue
+ value = value.strip(' \t')
- name=name.strip(' \t')
+ name = name.strip(' \t')
l.append((name, value))
@@ -1115,7 +1152,7 @@
cookie = Cookie(name, value)
hadMaxAge = False
- for name,value in tup[1:]:
+ for name, value in tup[1:]:
name = name.lower()
if value is None:
@@ -1229,15 +1266,15 @@
# def getMimeQuality(mimeType, accepts):
-# type,args = parseArgs(mimeType)
-# type=type.split(Token('/'))
+# type, args = parseArgs(mimeType)
+# type = type.split(Token('/'))
# if len(type) != 2:
# raise ValueError, "MIME Type "+s+" invalid."
# for accept in accepts:
-# accept,acceptQual=accept
-# acceptType=accept[0:1]
-# acceptArgs=accept[2]
+# accept, acceptQual = accept
+# acceptType = accept[0:1]
+# acceptArgs = accept[2]
# if ((acceptType == type or acceptType == (type[0],'*') or acceptType==('*','*')) and
# (args == acceptArgs or len(acceptArgs) == 0)):
@@ -1299,7 +1336,7 @@
def getRawHeaders(self, name, default=None):
"""Returns a list of headers matching the given name as the raw string given."""
- name=name.lower()
+ name = name.lower()
raw_header = self._raw_headers.get(name, default)
if raw_header is not _RecalcNeeded:
return raw_header
@@ -1314,7 +1351,7 @@
If the header doesn't exist, return default (or None if not specified)
"""
- name=name.lower()
+ name = name.lower()
parsed = self._headers.get(name, default)
if parsed is not _RecalcNeeded:
return parsed
@@ -1325,7 +1362,7 @@
Value should be a list of strings, each being one header of the
given name.
"""
- name=name.lower()
+ name = name.lower()
self._raw_headers[name] = value
self._headers[name] = _RecalcNeeded
@@ -1334,7 +1371,7 @@
Value should be a list of objects whose exact form depends
on the header in question.
"""
- name=name.lower()
+ name = name.lower()
self._raw_headers[name] = _RecalcNeeded
self._headers[name] = value
@@ -1344,7 +1381,7 @@
If it exists, add it as a separate header to output; do not
replace anything.
"""
- name=name.lower()
+ name = name.lower()
raw_header = self._raw_headers.get(name)
if raw_header is None:
# No header yet
@@ -1362,7 +1399,7 @@
If it exists, add it as a separate header to output; do not
replace anything.
"""
- name=name.lower()
+ name = name.lower()
header = self._headers.get(name)
if header is None:
# No header yet
@@ -1375,7 +1412,7 @@
def removeHeader(self, name):
"""Removes the header named."""
- name=name.lower()
+ name = name.lower()
if name in self._raw_headers:
del self._raw_headers[name]
del self._headers[name]
@@ -1389,10 +1426,10 @@
return header_case_mapping.get(name) or dashCapitalize(name)
def getAllRawHeaders(self):
- """Return an iterator of key,value pairs of all headers
+ """Return an iterator of key, value pairs of all headers
contained in this object, as strings. The keys are capitalized
in canonical capitalization."""
- for k,v in self._raw_headers.iteritems():
+ for k, v in self._raw_headers.iteritems():
if v is _RecalcNeeded:
v = self._toRaw(k)
yield self.canonicalNameCaps(k), v
@@ -1418,24 +1455,24 @@
parser_general_headers = {
- 'Cache-Control':(tokenize, listParser(parseCacheControl), dict),
- 'Connection':(tokenize,filterTokens),
- 'Date':(last,parseDateTime),
+ 'Cache-Control': (tokenize, listParser(parseCacheControl), dict),
+ 'Connection': (tokenize, filterTokens),
+ 'Date': (last, parseDateTime),
# 'Pragma':tokenize
# 'Trailer':tokenize
- 'Transfer-Encoding':(tokenize,filterTokens),
+ 'Transfer-Encoding': (tokenize, filterTokens),
# 'Upgrade':tokenize
-# 'Via':tokenize,stripComment
+# 'Via':tokenize, stripComment
# 'Warning':tokenize
}
generator_general_headers = {
- 'Cache-Control':(iteritems, listGenerator(generateCacheControl), singleHeader),
- 'Connection':(generateList,singleHeader),
- 'Date':(generateDateTime,singleHeader),
+ 'Cache-Control': (iteritems, listGenerator(generateCacheControl), singleHeader),
+ 'Connection': (generateList, singleHeader),
+ 'Date': (generateDateTime, singleHeader),
# 'Pragma':
# 'Trailer':
- 'Transfer-Encoding':(generateList,singleHeader),
+ 'Transfer-Encoding': (generateList, singleHeader),
# 'Upgrade':
# 'Via':
# 'Warning':
@@ -1444,102 +1481,114 @@
parser_request_headers = {
'Accept': (tokenize, listParser(parseAccept), dict),
'Accept-Charset': (tokenize, listParser(parseAcceptQvalue), dict, addDefaultCharset),
- 'Accept-Encoding':(tokenize, listParser(parseAcceptQvalue), dict, addDefaultEncoding),
- 'Accept-Language':(tokenize, listParser(parseAcceptQvalue), dict),
+ 'Accept-Encoding': (tokenize, listParser(parseAcceptQvalue), dict, addDefaultEncoding),
+ 'Accept-Language': (tokenize, listParser(parseAcceptQvalue), dict),
+ 'Access-Control-Allow-Origin': (last, parseAllowOrigin,),
+ 'Access-Control-Allow-Credentials': (last, parseAllowCreds,),
+ 'Access-Control-Allow-Methods': (tokenize, listParser(parseHTTPMethod), list),
+ 'Access-Control-Request-Method': (parseHTTPMethod, ),
+ 'Access-Control-Request-Headers': (filterTokens, ),
+ 'Access-Control-Expose-Headers': (filterTokens, ),
'Authorization': (last, parseAuthorization),
- 'Cookie':(parseCookie,),
- 'Expect':(tokenize, listParser(parseExpect), dict),
- 'From':(last,),
- 'Host':(last,),
- 'If-Match':(tokenize, listParser(parseStarOrETag), list),
- 'If-Modified-Since':(last, parseIfModifiedSince),
- 'If-None-Match':(tokenize, listParser(parseStarOrETag), list),
- 'If-Range':(parseIfRange,),
- 'If-Unmodified-Since':(last,parseDateTime),
- 'Max-Forwards':(last,int),
+ 'Cookie': (parseCookie,),
+ 'Expect': (tokenize, listParser(parseExpect), dict),
+ 'Origin': (last,),
+ 'From': (last,),
+ 'Host': (last,),
+ 'If-Match': (tokenize, listParser(parseStarOrETag), list),
+ 'If-Modified-Since': (last, parseIfModifiedSince),
+ 'If-None-Match': (tokenize, listParser(parseStarOrETag), list),
+ 'If-Range': (parseIfRange,),
+ 'If-Unmodified-Since': (last, parseDateTime),
+ 'Max-Forwards': (last, int),
# 'Proxy-Authorization':str, # what is "credentials"
- 'Range':(tokenize, parseRange),
- 'Referer':(last,str), # TODO: URI object?
- 'TE':(tokenize, listParser(parseAcceptQvalue), dict),
- 'User-Agent':(last,str),
+ 'Range': (tokenize, parseRange),
+ 'Referer': (last, str), # TODO: URI object?
+ 'TE': (tokenize, listParser(parseAcceptQvalue), dict),
+ 'User-Agent': (last, str),
}
generator_request_headers = {
- 'Accept': (iteritems,listGenerator(generateAccept),singleHeader),
- 'Accept-Charset': (iteritems, listGenerator(generateAcceptQvalue),singleHeader),
- 'Accept-Encoding': (iteritems, removeDefaultEncoding, listGenerator(generateAcceptQvalue),singleHeader),
- 'Accept-Language': (iteritems, listGenerator(generateAcceptQvalue),singleHeader),
+ 'Accept': (iteritems, listGenerator(generateAccept), singleHeader),
+ 'Accept-Charset': (iteritems, listGenerator(generateAcceptQvalue), singleHeader),
+ 'Accept-Encoding': (iteritems, removeDefaultEncoding,
+ listGenerator(generateAcceptQvalue), singleHeader),
+ 'Accept-Language': (iteritems, listGenerator(generateAcceptQvalue), singleHeader),
+ 'Access-Control-Request-Method': (unique, str, singleHeader, ),
+ 'Access-Control-Expose-Headers': (listGenerator(str), ),
+ 'Access-Control-Allow-Headers': (listGenerator(str), ),
'Authorization': (generateAuthorization,), # what is "credentials"
- 'Cookie':(generateCookie,singleHeader),
- 'Expect':(iteritems, listGenerator(generateExpect), singleHeader),
- 'From':(str,singleHeader),
- 'Host':(str,singleHeader),
- 'If-Match':(listGenerator(generateStarOrETag), singleHeader),
- 'If-Modified-Since':(generateDateTime,singleHeader),
- 'If-None-Match':(listGenerator(generateStarOrETag), singleHeader),
- 'If-Range':(generateIfRange, singleHeader),
- 'If-Unmodified-Since':(generateDateTime,singleHeader),
- 'Max-Forwards':(str, singleHeader),
+ 'Cookie': (generateCookie, singleHeader),
+ 'Expect': (iteritems, listGenerator(generateExpect), singleHeader),
+ 'From': (unique, str, singleHeader),
+ 'Host': (unique, str, singleHeader),
+ 'If-Match': (listGenerator(generateStarOrETag), singleHeader),
+ 'If-Modified-Since': (generateDateTime, singleHeader),
+ 'If-None-Match': (listGenerator(generateStarOrETag), singleHeader),
+ 'If-Range': (generateIfRange, singleHeader),
+ 'If-Unmodified-Since': (generateDateTime, singleHeader),
+ 'Max-Forwards': (unique, str, singleHeader),
+ 'Origin': (unique, str, singleHeader),
# 'Proxy-Authorization':str, # what is "credentials"
- 'Range':(generateRange,singleHeader),
- 'Referer':(str,singleHeader),
- 'TE': (iteritems, listGenerator(generateAcceptQvalue),singleHeader),
- 'User-Agent':(str,singleHeader),
+ 'Range': (generateRange, singleHeader),
+ 'Referer': (unique, str, singleHeader),
+ 'TE': (iteritems, listGenerator(generateAcceptQvalue), singleHeader),
+ 'User-Agent': (unique, str, singleHeader),
}
parser_response_headers = {
- 'Accept-Ranges':(tokenize, filterTokens),
- 'Age':(last,int),
- 'ETag':(tokenize, ETag.parse),
- 'Location':(last,), # TODO: URI object?
+ 'Accept-Ranges': (tokenize, filterTokens),
+ 'Age': (last, int),
+ 'ETag': (tokenize, ETag.parse),
+ 'Location': (last,), # TODO: URI object?
# 'Proxy-Authenticate'
- 'Retry-After':(last, parseRetryAfter),
- 'Server':(last,),
- 'Set-Cookie':(parseSetCookie,),
- 'Set-Cookie2':(tokenize, parseSetCookie2),
- 'Vary':(tokenize, filterTokens),
+ 'Retry-After': (last, parseRetryAfter),
+ 'Server': (last,),
+ 'Set-Cookie': (parseSetCookie,),
+ 'Set-Cookie2': (tokenize, parseSetCookie2),
+ 'Vary': (tokenize, filterTokens),
'WWW-Authenticate': (lambda h: tokenize(h, foldCase=False),
parseWWWAuthenticate,)
}
generator_response_headers = {
- 'Accept-Ranges':(generateList, singleHeader),
- 'Age':(str, singleHeader),
- 'ETag':(ETag.generate, singleHeader),
- 'Location':(str, singleHeader),
+ 'Accept-Ranges': (generateList, singleHeader),
+ 'Age': (unique, str, singleHeader),
+ 'ETag': (ETag.generate, singleHeader),
+ 'Location': (unique, str, singleHeader),
# 'Proxy-Authenticate'
- 'Retry-After':(generateRetryAfter, singleHeader),
- 'Server':(str, singleHeader),
- 'Set-Cookie':(generateSetCookie,),
- 'Set-Cookie2':(generateSetCookie2,),
- 'Vary':(generateList, singleHeader),
- 'WWW-Authenticate':(generateWWWAuthenticate,)
+ 'Retry-After': (generateRetryAfter, singleHeader),
+ 'Server': (unique, str, singleHeader),
+ 'Set-Cookie': (generateSetCookie,),
+ 'Set-Cookie2': (generateSetCookie2,),
+ 'Vary': (set, generateList, singleHeader),
+ 'WWW-Authenticate': (generateWWWAuthenticate,)
}
parser_entity_headers = {
- 'Allow':(lambda str:tokenize(str, foldCase=False), filterTokens),
- 'Content-Encoding':(tokenize, filterTokens),
- 'Content-Language':(tokenize, filterTokens),
- 'Content-Length':(last, int),
- 'Content-Location':(last,), # TODO: URI object?
- 'Content-MD5':(last, parseContentMD5),
- 'Content-Range':(last, parseContentRange),
- 'Content-Type':(lambda str:tokenize(str, foldCase=False), parseContentType),
- 'Expires':(last, parseExpires),
- 'Last-Modified':(last, parseDateTime),
+ 'Allow': (lambda str:tokenize(str, foldCase=False), filterTokens),
+ 'Content-Encoding': (tokenize, filterTokens),
+ 'Content-Language': (tokenize, filterTokens),
+ 'Content-Length': (last, int),
+ 'Content-Location': (last,), # TODO: URI object?
+ 'Content-MD5': (last, parseContentMD5),
+ 'Content-Range': (last, parseContentRange),
+ 'Content-Type': (lambda str:tokenize(str, foldCase=False), parseContentType),
+ 'Expires': (last, parseExpires),
+ 'Last-Modified': (last, parseDateTime),
}
generator_entity_headers = {
- 'Allow':(generateList, singleHeader),
- 'Content-Encoding':(generateList, singleHeader),
- 'Content-Language':(generateList, singleHeader),
- 'Content-Length':(str, singleHeader),
- 'Content-Location':(str, singleHeader),
- 'Content-MD5':(base64.encodestring, lambda x: x.strip("\n"), singleHeader),
- 'Content-Range':(generateContentRange, singleHeader),
- 'Content-Type':(generateContentType, singleHeader),
- 'Expires':(generateDateTime, singleHeader),
- 'Last-Modified':(generateDateTime, singleHeader),
+ 'Allow': (generateList, singleHeader),
+ 'Content-Encoding': (generateList, singleHeader),
+ 'Content-Language': (generateList, singleHeader),
+ 'Content-Length': (unique, str, singleHeader),
+ 'Content-Location': (unique, str, singleHeader),
+ 'Content-MD5': (base64.encodestring, lambda x: x.strip("\n"), singleHeader),
+ 'Content-Range': (generateContentRange, singleHeader),
+ 'Content-Type': (generateContentType, singleHeader),
+ 'Expires': (generateDateTime, singleHeader),
+ 'Last-Modified': (generateDateTime, singleHeader),
}
DefaultHTTPHandler.updateParsers(parser_general_headers)
diff -r 84738d495ffd -r 793377697c81 web/request.py
--- a/web/request.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/request.py Wed Sep 24 18:04:30 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
@@ -39,6 +38,7 @@
from logilab.common.deprecation import deprecated
from logilab.mtconverter import xml_escape
+from cubicweb.req import RequestSessionBase
from cubicweb.dbapi import DBAPIRequest
from cubicweb.uilib import remove_html_tags, js
from cubicweb.utils import SizeConstrainedList, HTMLHead, make_uid
@@ -81,20 +81,39 @@
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',)
-class CubicWebRequestBase(DBAPIRequest):
+ 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
Immutable attributes that describe the received query and generic configuration
"""
ajax_request = False # to be set to True by ajax controllers
- def __init__(self, vreg, https=False, form=None, headers={}):
+ def __init__(self, vreg, https=False, form=None, headers=None):
"""
:vreg: Vregistry,
:https: boolean, s this a https request
:form: Forms value
+ :headers: dict, request header
"""
- super(CubicWebRequestBase, self).__init__(vreg)
+ super(_CubicWebRequestBase, self).__init__(vreg)
#: (Boolean) Is this an https request.
self.https = https
#: User interface property (vary with https) (see :ref:`uiprops`)
@@ -113,12 +132,16 @@
self.html_headers = HTMLHead(self)
#: received headers
self._headers_in = Headers()
- for k, v in headers.iteritems():
- self._headers_in.addRawHeader(k, v)
+ if headers is not None:
+ for k, v in headers.iteritems():
+ self._headers_in.addRawHeader(k, v)
#: form parameters
self.setup_params(form)
#: received body
self.content = StringIO()
+ # set up language based on request headers or site default (we don't
+ # have a user yet, and might not get one)
+ self.set_user_language(None)
#: dictionary that may be used to store request data that has to be
#: shared among various components used to publish the request (views,
#: controller, application...)
@@ -169,7 +192,7 @@
if secure:
base_url = self.vreg.config.get('https-url')
if base_url is None:
- base_url = super(CubicWebRequestBase, self).base_url()
+ base_url = super(_CubicWebRequestBase, self).base_url()
return base_url
@property
@@ -195,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()
@@ -206,31 +229,6 @@
self.set_page_data('rql_varmaker', varmaker)
return varmaker
- def set_session(self, session, user=None):
- """method called by the session handler when the user is authenticated
- or an anonymous connection is open
- """
- super(CubicWebRequestBase, self).set_session(session, user)
- # set request language
- vreg = self.vreg
- if self.user:
- try:
- # 1. user specified language
- lang = vreg.typed_value('ui.language',
- self.user.properties['ui.language'])
- self.set_language(lang)
- return
- except KeyError:
- pass
- if vreg.config['language-negociation']:
- # 2. http negociated language
- for lang in self.header_accept_language():
- if lang in self.translations:
- self.set_language(lang)
- return
- # 3. default language
- self.set_default_language(vreg)
-
# input form parameters management ########################################
# common form parameters which should be protected against html values
@@ -327,6 +325,7 @@
def set_message(self, msg):
assert isinstance(msg, unicode)
+ self.reset_message()
self._msg = msg
def set_message_id(self, msgid):
@@ -357,6 +356,7 @@
if hasattr(self, '_msg'):
del self._msg
if hasattr(self, '_msgid'):
+ self.session.data.pop(self._msgid, u'')
del self._msgid
def update_search_state(self):
@@ -423,6 +423,7 @@
req.execute(rql, args, key)
return self.user_callback(rqlexec, rqlargs, *args, **kwargs)
+ @deprecated('[3.19] use a traditional ajaxfunc / controller')
def user_callback(self, cb, cbargs, *args, **kwargs):
"""register the given user callback and return a URL which can
be inserted in an HTML view. When the URL is accessed, the
@@ -725,7 +726,13 @@
if '__message' in kwargs:
msg = kwargs.pop('__message')
kwargs['_cwmsgid'] = self.set_redirect_message(msg)
- return super(CubicWebRequestBase, self).build_url(*args, **kwargs)
+ if not args:
+ method = 'view'
+ if (self.from_controller() == 'view'
+ and not '_restpath' in kwargs):
+ method = self.relative_path(includeparams=False) or 'view'
+ args = (method,)
+ return super(_CubicWebRequestBase, self).build_url(*args, **kwargs)
def url(self, includeparams=True):
"""return currently accessed url"""
@@ -986,6 +993,112 @@
def html_content_type(self):
return 'text/html'
+ def set_user_language(self, user):
+ vreg = self.vreg
+ if user is not None:
+ try:
+ # 1. user-specified language
+ lang = vreg.typed_value('ui.language', user.properties['ui.language'])
+ self.set_language(lang)
+ return
+ except KeyError:
+ pass
+ if vreg.config.get('language-negociation', False):
+ # 2. http accept-language
+ for lang in self.header_accept_language():
+ if lang in self.translations:
+ self.set_language(lang)
+ return
+ # 3. site's default language
+ self.set_default_language(vreg)
+
+
+class DBAPICubicWebRequestBase(_CubicWebRequestBase, DBAPIRequest):
+
+ def set_session(self, session):
+ """method called by the session handler when the user is authenticated
+ or an anonymous connection is open
+ """
+ super(CubicWebRequestBase, self).set_session(session)
+ # set request language
+ self.set_user_language(session.user)
+
+
+def _cnx_func(name):
+ def proxy(req, *args, **kwargs):
+ return getattr(req.cnx, name)(*args, **kwargs)
+ return proxy
+
+
+class ConnectionCubicWebRequestBase(_CubicWebRequestBase):
+
+ def __init__(self, vreg, https=False, form=None, headers={}):
+ """"""
+ self.cnx = None
+ self.session = None
+ self.vreg = vreg
+ try:
+ # no vreg or config which doesn't handle translations
+ self.translations = vreg.config.translations
+ except AttributeError:
+ self.translations = {}
+ super(ConnectionCubicWebRequestBase, self).__init__(vreg, https=https,
+ form=form, headers=headers)
+ from cubicweb.dbapi import DBAPISession, _NeedAuthAccessMock
+ self.session = DBAPISession(None)
+ self.cnx = self.user = _NeedAuthAccessMock()
+
+ @property
+ def transaction_data(self):
+ return self.cnx.transaction_data
+
+ def set_cnx(self, cnx):
+ self.cnx = cnx
+ self.session = cnx._session
+ self._set_user(cnx.user)
+ self.set_user_language(cnx.user)
+
+ def execute(self, *args, **kwargs):
+ rset = self.cnx.execute(*args, **kwargs)
+ rset.req = self
+ return rset
+
+ def set_default_language(self, vreg):
+ # XXX copy from dbapi
+ try:
+ lang = vreg.property_value('ui.language')
+ except Exception: # property may not be registered
+ lang = 'en'
+ try:
+ self.set_language(lang)
+ except KeyError:
+ # this occurs usually during test execution
+ self._ = self.__ = unicode
+ self.pgettext = lambda x, y: unicode(y)
+
+ entity_metas = _cnx_func('entity_metas')
+ source_defs = _cnx_func('source_defs')
+ get_shared_data = _cnx_func('get_shared_data')
+ set_shared_data = _cnx_func('set_shared_data')
+ describe = _cnx_func('describe') # deprecated XXX
+
+ # server-side service call #################################################
+
+ def call_service(self, regid, **kwargs):
+ return self.cnx.call_service(regid, **kwargs)
+
+ # entities cache management ###############################################
+
+ entity_cache = _cnx_func('entity_cache')
+ set_entity_cache = _cnx_func('set_entity_cache')
+ cached_entities = _cnx_func('cached_entities')
+ drop_entity_cache = _cnx_func('drop_entity_cache')
+
+
+
+
+CubicWebRequestBase = ConnectionCubicWebRequestBase
+
## HTTP-accept parsers / utilies ##############################################
def _mimetype_sort_key(accept_info):
@@ -1083,4 +1196,4 @@
}
from cubicweb import set_log_methods
-set_log_methods(CubicWebRequestBase, LOGGER)
+set_log_methods(_CubicWebRequestBase, LOGGER)
diff -r 84738d495ffd -r 793377697c81 web/test/data/schema.py
--- a/web/test/data/schema.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/data/schema.py Wed Sep 24 18:04:30 2014 +0200
@@ -43,7 +43,11 @@
class Personne(EntityType):
nom = String(fulltextindexed=True, required=True, maxsize=64)
prenom = String(fulltextindexed=True, maxsize=64)
- sexe = String(maxsize=1, default='M')
+ sexe = String(maxsize=1, default='M',
+ __permissions__={
+ 'read': ('managers', 'users', 'guests',),
+ 'add': ('managers', 'users'),
+ 'update': ('managers', )})
promo = String(vocabulary=('bon','pasbon'))
titre = String(fulltextindexed=True, maxsize=128)
ass = String(maxsize=128)
diff -r 84738d495ffd -r 793377697c81 web/test/data/views.py
--- a/web/test/data/views.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/data/views.py Wed Sep 24 18:04:30 2014 +0200
@@ -16,32 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see .
-from cubicweb.web import Redirect
-from cubicweb.web.application import CubicWebPublisher
from cubicweb.web.views.ajaxcontroller import ajaxfunc
-# proof of concept : monkey patch handle method so that if we are in an
-# anonymous session and __fblogin is found is req.form, the user with the
-# given login is created if necessary and then a session is opened for that
-# user
-# NOTE: this require "cookie" authentication mode
-def auto_login_handle_request(self, req, path):
- if (not req.cnx or req.cnx.anonymous_connection) and req.form.get('__fblogin'):
- login = password = req.form.pop('__fblogin')
- self.repo.register_user(login, password)
- req.form['__login'] = login
- req.form['__password'] = password
- if req.cnx:
- req.cnx.close()
- req.cnx = None
- try:
- self.session_handler.set_session(req)
- except Redirect:
- pass
- assert req.user.login == login
- return orig_handle(self, req, path)
-
-
def _recursive_replace_stream_by_content(tree):
""" Search for streams (i.e. object that have a 'read' method) in a tree
(which branches are lists or tuples), and substitute them by their content,
@@ -70,6 +46,3 @@
except Exception, ex:
import traceback as tb
tb.print_exc(ex)
-
-orig_handle = CubicWebPublisher.main_handle_request
-CubicWebPublisher.main_handle_request = auto_login_handle_request
diff -r 84738d495ffd -r 793377697c81 web/test/test_views.py
--- a/web/test/test_views.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/test_views.py Wed Sep 24 18:04:30 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -16,8 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see .
"""automatic tests"""
-from cubicweb.devtools import htmlparser
-from cubicweb.devtools.testlib import CubicWebTC, AutoPopulateTest, AutomaticWebTest
+from cubicweb.devtools.testlib import AutoPopulateTest, AutomaticWebTest
from cubicweb.view import AnyRsetView
class AutomaticWebTest(AutomaticWebTest):
@@ -28,8 +27,8 @@
]
def to_test_etypes(self):
- # We do not really want to test cube views here. So we can drop testing
- # some EntityType. The two Blog types below require the sioc cube that
+ # We do not really want to test cube views here. So we can drop testing
+ # some EntityType. The two Blog types below require the sioc cube that
# we do not want to add as a dependency.
etypes = super(AutomaticWebTest, self).to_test_etypes()
etypes -= set(('Blog', 'BlogEntry'))
@@ -50,29 +49,34 @@
"""regression test: make sure we can ask a copy of a
composite entity
"""
- rset = self.execute('CWUser X WHERE X login "admin"')
- self.view('copy', rset)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X WHERE X login "admin"')
+ self.view('copy', rset, req=req)
def test_sortable_js_added(self):
- rset = self.execute('CWUser X')
- # sortable.js should not be included by default
- self.assertFalse('jquery.tablesorter.js' in self.view('oneline', rset))
- # but should be included by the tableview
- rset = self.execute('Any P,F,S LIMIT 1 WHERE P is CWUser, P firstname F, P surname S')
- self.assertIn('jquery.tablesorter.js', self.view('table', rset).source)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X')
+ # sortable.js should not be included by default
+ self.assertFalse('jquery.tablesorter.js' in self.view('oneline', rset, req=req))
+ # but should be included by the tableview
+ rset = req.execute('Any P,F,S LIMIT 1 WHERE P is CWUser, P firstname F, P surname S')
+ self.assertIn('jquery.tablesorter.js', self.view('table', rset, req=req).source)
def test_js_added_only_once(self):
- self.vreg._loadedmods[__name__] = {}
- self.vreg.register(SomeView)
- rset = self.execute('CWUser X')
- source = self.view('someview', rset).source
- self.assertEqual(source.count('spam.js'), 1)
+ with self.admin_access.web_request() as req:
+ self.vreg._loadedmods[__name__] = {}
+ self.vreg.register(SomeView)
+ rset = req.execute('CWUser X')
+ source = self.view('someview', rset, req=req).source
+ self.assertEqual(source.count('spam.js'), 1)
def test_unrelateddivs(self):
- rset = self.execute('Any X WHERE X is CWUser, X login "admin"')
- group = self.request().create_entity('CWGroup', name=u'R&D')
- req = self.request(relation='in_group_subject')
- self.view('unrelateddivs', rset, req)
+ with self.admin_access.client_cnx() as cnx:
+ group = cnx.create_entity('CWGroup', name=u'R&D')
+ cnx.commit()
+ with self.admin_access.web_request(relation='in_group_subject') as req:
+ rset = req.execute('Any X WHERE X is CWUser, X login "admin"')
+ self.view('unrelateddivs', rset, req=req)
if __name__ == '__main__':
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_application.py
--- a/web/test/unittest_application.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_application.py Wed Sep 24 18:04:30 2014 +0200
@@ -18,20 +18,20 @@
"""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
from cubicweb.web import LogOut, Redirect, INTERNAL_FIELD_VALUE
from cubicweb.web.views.basecontrollers import ViewController
from cubicweb.web.application import anonymized_request
+from cubicweb.dbapi import DBAPISession, _NeedAuthAccessMock
+from cubicweb import repoapi
class FakeMapping:
"""emulates a mapping module"""
@@ -165,48 +165,40 @@
return config
def test_cnx_user_groups_sync(self):
- user = self.user()
- self.assertEqual(user.groups, set(('managers',)))
- self.execute('SET X in_group G WHERE X eid %s, G name "guests"' % user.eid)
- user = self.user()
- self.assertEqual(user.groups, set(('managers',)))
- self.commit()
- user = self.user()
- self.assertEqual(user.groups, set(('managers', 'guests')))
- # cleanup
- self.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
- self.commit()
-
- def test_nonregr_publish1(self):
- req = self.request(u'CWEType X WHERE X final FALSE, X meta FALSE')
- self.app.handle_request(req, 'view')
-
- def test_nonregr_publish2(self):
- req = self.request(u'Any count(N) WHERE N todo_by U, N is Note, U eid %s'
- % self.user().eid)
- self.app.handle_request(req, 'view')
+ with self.admin_access.client_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)
+ user = cnx.user
+ self.assertEqual(user.groups, set(('managers',)))
+ cnx.commit()
+ user = cnx.user
+ self.assertEqual(user.groups, set(('managers', 'guests')))
+ # cleanup
+ cnx.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
+ cnx.commit()
def test_publish_validation_error(self):
- req = self.request()
- user = self.user()
- eid = unicode(user.eid)
- req.form = {
- 'eid': eid,
- '__type:'+eid: 'CWUser', '_cw_entity_fields:'+eid: 'login-subject',
- 'login-subject:'+eid: '', # ERROR: no login specified
- # just a sample, missing some necessary information for real life
- '__errorurl': 'view?vid=edition...'
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- forminfo = req.session.data['view?vid=edition...']
- eidmap = forminfo['eidmap']
- self.assertEqual(eidmap, {})
- values = forminfo['values']
- self.assertEqual(values['login-subject:'+eid], '')
- self.assertEqual(values['eid'], eid)
- error = forminfo['error']
- self.assertEqual(error.entity, user.eid)
- self.assertEqual(error.errors['login-subject'], 'required field')
+ with self.admin_access.web_request() as req:
+ user = self.user(req)
+ eid = unicode(user.eid)
+ req.form = {
+ 'eid': eid,
+ '__type:'+eid: 'CWUser', '_cw_entity_fields:'+eid: 'login-subject',
+ 'login-subject:'+eid: '', # ERROR: no login specified
+ # just a sample, missing some necessary information for real life
+ '__errorurl': 'view?vid=edition...'
+ }
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ forminfo = req.session.data['view?vid=edition...']
+ eidmap = forminfo['eidmap']
+ self.assertEqual(eidmap, {})
+ values = forminfo['values']
+ self.assertEqual(values['login-subject:'+eid], '')
+ self.assertEqual(values['eid'], eid)
+ error = forminfo['error']
+ self.assertEqual(error.entity, user.eid)
+ self.assertEqual(error.errors['login-subject'], 'required field')
def test_validation_error_dont_loose_subentity_data_ctrl(self):
@@ -214,28 +206,28 @@
error occurs on the web controller
"""
- req = self.request()
- # set Y before X to ensure both entities are edited, not only X
- req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
- '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject',
- # missing required field
- 'login-subject:X': u'',
- # but email address is set
- '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
- 'address-subject:Y': u'bougloup@logilab.fr',
- 'use_email-object:Y': 'X',
- # necessary to get validation error handling
- '__errorurl': 'view?vid=edition...',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- forminfo = req.session.data['view?vid=edition...']
- self.assertEqual(set(forminfo['eidmap']), set('XY'))
- self.assertEqual(forminfo['eidmap']['X'], None)
- self.assertIsInstance(forminfo['eidmap']['Y'], int)
- self.assertEqual(forminfo['error'].entity, 'X')
- self.assertEqual(forminfo['error'].errors,
- {'login-subject': 'required field'})
- self.assertEqual(forminfo['values'], req.form)
+ with self.admin_access.web_request() as req:
+ # set Y before X to ensure both entities are edited, not only X
+ req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
+ '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject',
+ # missing required field
+ 'login-subject:X': u'',
+ # but email address is set
+ '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
+ 'address-subject:Y': u'bougloup@logilab.fr',
+ 'use_email-object:Y': 'X',
+ # necessary to get validation error handling
+ '__errorurl': 'view?vid=edition...',
+ }
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ forminfo = req.session.data['view?vid=edition...']
+ self.assertEqual(set(forminfo['eidmap']), set('XY'))
+ self.assertEqual(forminfo['eidmap']['X'], None)
+ self.assertIsInstance(forminfo['eidmap']['Y'], int)
+ self.assertEqual(forminfo['error'].entity, 'X')
+ self.assertEqual(forminfo['error'].errors,
+ {'login-subject': 'required field'})
+ self.assertEqual(forminfo['values'], req.form)
def test_validation_error_dont_loose_subentity_data_repo(self):
@@ -243,28 +235,28 @@
error occurs on the repository
"""
- req = self.request()
- # set Y before X to ensure both entities are edited, not only X
- req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
- '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject,upassword-subject',
- # already existent user
- 'login-subject:X': u'admin',
- 'upassword-subject:X': u'admin', 'upassword-subject-confirm:X': u'admin',
- '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
- 'address-subject:Y': u'bougloup@logilab.fr',
- 'use_email-object:Y': 'X',
- # necessary to get validation error handling
- '__errorurl': 'view?vid=edition...',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- forminfo = req.session.data['view?vid=edition...']
- self.assertEqual(set(forminfo['eidmap']), set('XY'))
- self.assertIsInstance(forminfo['eidmap']['X'], int)
- self.assertIsInstance(forminfo['eidmap']['Y'], int)
- self.assertEqual(forminfo['error'].entity, forminfo['eidmap']['X'])
- self.assertEqual(forminfo['error'].errors,
- {'login-subject': u'the value "admin" is already used, use another one'})
- self.assertEqual(forminfo['values'], req.form)
+ with self.admin_access.web_request() as req:
+ # set Y before X to ensure both entities are edited, not only X
+ req.form = {'eid': ['Y', 'X'], '__maineid': 'X',
+ '__type:X': 'CWUser', '_cw_entity_fields:X': 'login-subject,upassword-subject',
+ # already existent user
+ 'login-subject:X': u'admin',
+ 'upassword-subject:X': u'admin', 'upassword-subject-confirm:X': u'admin',
+ '__type:Y': 'EmailAddress', '_cw_entity_fields:Y': 'address-subject',
+ 'address-subject:Y': u'bougloup@logilab.fr',
+ 'use_email-object:Y': 'X',
+ # necessary to get validation error handling
+ '__errorurl': 'view?vid=edition...',
+ }
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ forminfo = req.session.data['view?vid=edition...']
+ self.assertEqual(set(forminfo['eidmap']), set('XY'))
+ self.assertIsInstance(forminfo['eidmap']['X'], int)
+ self.assertIsInstance(forminfo['eidmap']['Y'], int)
+ self.assertEqual(forminfo['error'].entity, forminfo['eidmap']['X'])
+ self.assertEqual(forminfo['error'].errors,
+ {'login-subject': u'the value "admin" is already used, use another one'})
+ self.assertEqual(forminfo['values'], req.form)
def test_ajax_view_raise_arbitrary_error(self):
class ErrorAjaxView(view.View):
@@ -273,17 +265,17 @@
raise Exception('whatever')
with self.temporary_appobjects(ErrorAjaxView):
with real_error_handling(self.app) as app:
- req = self.request(vid='test.ajax.error')
- req.ajax_request = True
- page = app.handle_request(req, '')
+ with self.admin_access.web_request(vid='test.ajax.error') as req:
+ req.ajax_request = True
+ page = app.handle_request(req, '')
self.assertEqual(httplib.INTERNAL_SERVER_ERROR,
req.status_out)
def _test_cleaned(self, kwargs, injected, cleaned):
- req = self.request(**kwargs)
- page = self.app.handle_request(req, 'view')
- self.assertFalse(injected in page, (kwargs, injected))
- self.assertTrue(cleaned in page, (kwargs, cleaned))
+ with self.admin_access.web_request(**kwargs) as req:
+ page = self.app_handle_request(req, 'view')
+ self.assertNotIn(injected, page)
+ self.assertIn(cleaned, page)
def test_nonregr_script_kiddies(self):
"""test against current script injection"""
@@ -302,39 +294,28 @@
vreg = self.app.vreg
# default value
self.assertEqual(vreg.property_value('ui.language'), 'en')
- self.execute('INSERT CWProperty X: X value "fr", X pkey "ui.language"')
- self.assertEqual(vreg.property_value('ui.language'), 'en')
- self.commit()
- self.assertEqual(vreg.property_value('ui.language'), 'fr')
- self.execute('SET X value "de" WHERE X pkey "ui.language"')
- self.assertEqual(vreg.property_value('ui.language'), 'fr')
- self.commit()
- self.assertEqual(vreg.property_value('ui.language'), 'de')
- self.execute('DELETE CWProperty X WHERE X pkey "ui.language"')
- self.assertEqual(vreg.property_value('ui.language'), 'de')
- self.commit()
- self.assertEqual(vreg.property_value('ui.language'), 'en')
-
- def test_fb_login_concept(self):
- """see data/views.py"""
- self.set_auth_mode('cookie', 'anon')
- self.login('anon')
- req = self.request()
- origcnx = req.cnx
- req.form['__fblogin'] = u'turlututu'
- page = self.app.handle_request(req, '')
- self.assertFalse(req.cnx is origcnx)
- self.assertEqual(req.user.login, 'turlututu')
- self.assertTrue('turlututu' in page, page)
- req.cnx.close() # avoid warning
+ with self.admin_access.client_cnx() as cnx:
+ cnx.execute('INSERT CWProperty X: X value "fr", X pkey "ui.language"')
+ self.assertEqual(vreg.property_value('ui.language'), 'en')
+ cnx.commit()
+ self.assertEqual(vreg.property_value('ui.language'), 'fr')
+ cnx.execute('SET X value "de" WHERE X pkey "ui.language"')
+ self.assertEqual(vreg.property_value('ui.language'), 'fr')
+ cnx.commit()
+ self.assertEqual(vreg.property_value('ui.language'), 'de')
+ cnx.execute('DELETE CWProperty X WHERE X pkey "ui.language"')
+ self.assertEqual(vreg.property_value('ui.language'), 'de')
+ cnx.commit()
+ self.assertEqual(vreg.property_value('ui.language'), 'en')
# authentication tests ####################################################
def test_http_auth_no_anon(self):
req, origsession = self.init_authentication('http')
self.assertAuthFailure(req)
- self.assertRaises(AuthenticationError, self.app_handle_request, req, 'login')
- self.assertEqual(req.cnx, None)
+ self.app.handle_request(req, 'login')
+ self.assertEqual(401, req.status_out)
+ clear_cache(req, 'get_authorization')
authstr = base64.encodestring('%s:%s' % (self.admlogin, self.admpassword))
req.set_request_header('Authorization', 'basic %s' % authstr)
self.assertAuthSuccess(req, origsession)
@@ -345,12 +326,13 @@
req, origsession = self.init_authentication('cookie')
self.assertAuthFailure(req)
try:
- form = self.app_handle_request(req, 'login')
+ form = self.app.handle_request(req, 'login')
except Redirect as redir:
self.fail('anonymous user should get login form')
- self.assertTrue('__login' in form)
- self.assertTrue('__password' in form)
- self.assertEqual(req.cnx, None)
+ clear_cache(req, 'get_authorization')
+ self.assertIn('__login', form)
+ self.assertIn('__password', form)
+ self.assertFalse(req.cnx) # Mock cnx are False
req.form['__login'] = self.admlogin
req.form['__password'] = self.admpassword
self.assertAuthSuccess(req, origsession)
@@ -358,18 +340,19 @@
self.assertEqual(len(self.open_sessions), 0)
def test_login_by_email(self):
- login = self.request().user.login
- address = login + u'@localhost'
- self.execute('INSERT EmailAddress X: X address %(address)s, U primary_email X '
- 'WHERE U login %(login)s', {'address': address, 'login': login})
- self.commit()
+ with self.admin_access.client_cnx() as cnx:
+ login = cnx.user.login
+ address = login + u'@localhost'
+ cnx.execute('INSERT EmailAddress X: X address %(address)s, U primary_email X '
+ 'WHERE U login %(login)s', {'address': address, 'login': login})
+ cnx.commit()
# # option allow-email-login not set
req, origsession = self.init_authentication('cookie')
# req.form['__login'] = address
# req.form['__password'] = self.admpassword
# self.assertAuthFailure(req)
# option allow-email-login set
- origsession.login = address
+ #origsession.login = address
self.set_option('allow-email-login', True)
req.form['__login'] = address
req.form['__password'] = self.admpassword
@@ -387,22 +370,27 @@
raw=True)
clear_cache(req, 'get_authorization')
# reset session as if it was a new incoming request
- req.session = req.cnx = None
+ req.session = DBAPISession(None)
+ req.user = req.cnx = _NeedAuthAccessMock
+
def _test_auth_anon(self, req):
- self.app.connect(req)
- asession = req.session
+ asession = self.app.get_session(req)
+ # important otherwise _reset_cookie will not use the right session
+ req.set_cnx(repoapi.ClientConnection(asession))
self.assertEqual(len(self.open_sessions), 1)
self.assertEqual(asession.login, 'anon')
self.assertTrue(asession.anonymous_session)
self._reset_cookie(req)
def _test_anon_auth_fail(self, req):
- self.assertEqual(len(self.open_sessions), 1)
- self.app.connect(req)
+ self.assertEqual(1, len(self.open_sessions))
+ session = self.app.get_session(req)
+ # important otherwise _reset_cookie will not use the right session
+ req.set_cnx(repoapi.ClientConnection(session))
self.assertEqual(req.message, 'authentication failure')
self.assertEqual(req.session.anonymous_session, True)
- self.assertEqual(len(self.open_sessions), 1)
+ self.assertEqual(1, len(self.open_sessions))
self._reset_cookie(req)
def test_http_auth_anon_allowed(self):
@@ -427,25 +415,25 @@
req.form['__password'] = self.admpassword
self.assertAuthSuccess(req, origsession)
self.assertRaises(LogOut, self.app_handle_request, req, 'logout')
- self.assertEqual(len(self.open_sessions), 0)
+ self.assertEqual(0, len(self.open_sessions))
def test_anonymized_request(self):
- req = self.request()
- self.assertEqual(req.session.login, self.admlogin)
- # admin should see anon + admin
- self.assertEqual(len(list(req.find_entities('CWUser'))), 2)
- with anonymized_request(req):
- self.assertEqual(req.session.login, 'anon')
- # anon should only see anon user
- self.assertEqual(len(list(req.find_entities('CWUser'))), 1)
- self.assertEqual(req.session.login, self.admlogin)
- self.assertEqual(len(list(req.find_entities('CWUser'))), 2)
+ with self.admin_access.web_request() as req:
+ self.assertEqual(self.admlogin, req.session.user.login)
+ # admin should see anon + admin
+ self.assertEqual(2, len(list(req.find('CWUser'))))
+ with anonymized_request(req):
+ self.assertEqual('anon', req.session.login, 'anon')
+ # anon should only see anon user
+ self.assertEqual(1, len(list(req.find('CWUser'))))
+ self.assertEqual(self.admlogin, req.session.login)
+ self.assertEqual(2, len(list(req.find('CWUser'))))
def test_non_regr_optional_first_var(self):
- req = self.request()
- # expect a rset with None in [0][0]
- req.form['rql'] = 'rql:Any OV1, X WHERE X custom_workflow OV1?'
- self.app_handle_request(req)
+ with self.admin_access.web_request() as req:
+ # expect a rset with None in [0][0]
+ req.form['rql'] = 'rql:Any OV1, X WHERE X custom_workflow OV1?'
+ self.app_handle_request(req)
if __name__ == '__main__':
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_breadcrumbs.py
--- a/web/test/unittest_breadcrumbs.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_breadcrumbs.py Wed Sep 24 18:04:30 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,21 +22,26 @@
class BreadCrumbsTC(CubicWebTC):
def test_base(self):
- req = self.request()
- f1 = req.create_entity('Folder', name=u'par&ent')
- f2 = req.create_entity('Folder', name=u'chi&ld')
- self.execute('SET F2 filed_under F1 WHERE F1 eid %(f1)s, F2 eid %(f2)s',
- {'f1' : f1.eid, 'f2' : f2.eid})
- self.commit()
- self.assertEqual(f2.view('breadcrumbs'),
- 'chi&ld ' % f2.eid)
- childrset = f2.as_rset()
- ibc = self.vreg['ctxcomponents'].select('breadcrumbs', self.request(), rset=childrset)
- l = []
- ibc.render(l.append)
- self.assertEqual(''.join(l),
- """ > Folder_plural > par&ent >
-chi&ld """ % (f1.eid, f2.eid))
+ with self.admin_access.web_request() as req:
+ f1 = req.create_entity('Folder', name=u'par&ent')
+ f2 = req.create_entity('Folder', name=u'chi&ld')
+ req.cnx.execute('SET F2 filed_under F1 WHERE F1 eid %(f1)s, F2 eid %(f2)s',
+ {'f1' : f1.eid, 'f2' : f2.eid})
+ req.cnx.commit()
+ self.assertEqual(f2.view('breadcrumbs'),
+ ''
+ 'chi&ld ' % f2.eid)
+ childrset = f2.as_rset()
+ ibc = self.vreg['ctxcomponents'].select('breadcrumbs', req, rset=childrset)
+ l = []
+ ibc.render(l.append)
+ self.assertMultiLineEqual(' > '
+ 'Folder_plural '
+ ' > par&ent > \n'
+ ''
+ 'chi&ld ' % (f1.eid, f2.eid),
+ ''.join(l))
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_controller.py
--- a/web/test/unittest_controller.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_controller.py Wed Sep 24 18:04:30 2014 +0200
@@ -28,30 +28,32 @@
class BaseControllerTC(testlib.CubicWebTC):
def test_parse_datetime_ok(self):
- ctrl = self.vreg['controllers'].select('view', self.request())
- pd = ctrl._cw.parse_datetime
- self.assertIsInstance(pd('2006/06/24 12:18'), datetime)
- self.assertIsInstance(pd('2006/06/24'), date)
- self.assertIsInstance(pd('2006/06/24 12:18', 'Datetime'), datetime)
- self.assertIsInstance(pd('2006/06/24', 'Datetime'), datetime)
- self.assertIsInstance(pd('2006/06/24', 'Date'), date)
- self.assertIsInstance(pd('12:18', 'Time'), time)
+ with self.admin_access.web_request() as req:
+ ctrl = self.vreg['controllers'].select('view', req)
+ pd = ctrl._cw.parse_datetime
+ self.assertIsInstance(pd('2006/06/24 12:18'), datetime)
+ self.assertIsInstance(pd('2006/06/24'), date)
+ self.assertIsInstance(pd('2006/06/24 12:18', 'Datetime'), datetime)
+ self.assertIsInstance(pd('2006/06/24', 'Datetime'), datetime)
+ self.assertIsInstance(pd('2006/06/24', 'Date'), date)
+ self.assertIsInstance(pd('12:18', 'Time'), time)
def test_parse_datetime_ko(self):
- ctrl = self.vreg['controllers'].select('view', self.request())
- pd = ctrl._cw.parse_datetime
- self.assertRaises(ValueError,
- pd, '2006/06/24 12:188', 'Datetime')
- self.assertRaises(ValueError,
- pd, '2006/06/240', 'Datetime')
- self.assertRaises(ValueError,
- pd, '2006/06/24 12:18', 'Date')
- self.assertRaises(ValueError,
- pd, '2006/24/06', 'Date')
- self.assertRaises(ValueError,
- pd, '2006/06/240', 'Date')
- self.assertRaises(ValueError,
- pd, '12:188', 'Time')
+ with self.admin_access.web_request() as req:
+ ctrl = self.vreg['controllers'].select('view', req)
+ pd = ctrl._cw.parse_datetime
+ self.assertRaises(ValueError,
+ pd, '2006/06/24 12:188', 'Datetime')
+ self.assertRaises(ValueError,
+ pd, '2006/06/240', 'Datetime')
+ self.assertRaises(ValueError,
+ pd, '2006/06/24 12:18', 'Date')
+ self.assertRaises(ValueError,
+ pd, '2006/24/06', 'Date')
+ self.assertRaises(ValueError,
+ pd, '2006/06/240', 'Date')
+ self.assertRaises(ValueError,
+ pd, '12:188', 'Time')
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_facet.py
--- a/web/test/unittest_facet.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_facet.py Wed Sep 24 18:04:30 2014 +0200
@@ -4,21 +4,20 @@
class BaseFacetTC(CubicWebTC):
- def prepare_rqlst(self, rql='CWUser X', mainvar='X',
+ def prepare_rqlst(self, req, rql='CWUser X', mainvar='X',
expected_baserql='Any X WHERE X is CWUser',
expected_preparedrql='DISTINCT Any WHERE X is CWUser'):
- req = self.request()
- rset = self.execute(rql)
+ rset = req.cnx.execute(rql)
rqlst = rset.syntax_tree().copy()
filtered_variable, baserql = facet.init_facets(rset, rqlst.children[0],
mainvar=mainvar)
self.assertEqual(filtered_variable.name, mainvar)
self.assertEqual(baserql, expected_baserql)
self.assertEqual(rqlst.as_string(), expected_preparedrql)
- return req, rset, rqlst, filtered_variable
+ return rset, rqlst, filtered_variable
- def _in_group_facet(self, cls=facet.RelationFacet, no_relation=False):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst()
+ def _in_group_facet(self, req, cls=facet.RelationFacet, no_relation=False):
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
cls.no_relation = no_relation
f = cls(req, rset=rset, select=rqlst.children[0],
filtered_variable=filtered_variable)
@@ -26,285 +25,328 @@
f.rtype = 'in_group'
f.role = 'subject'
f.target_attr = 'name'
- guests, managers = [eid for eid, in self.execute('CWGroup G ORDERBY GN '
- 'WHERE G name GN, G name IN ("guests", "managers")')]
- groups = [eid for eid, in self.execute('CWGroup G ORDERBY GN '
- 'WHERE G name GN, G name IN ("guests", "managers")')]
+ guests, managers = [eid for eid, in req.cnx.execute('CWGroup G ORDERBY GN '
+ 'WHERE G name GN, G name IN ("guests", "managers")')]
+ groups = [eid for eid, in req.cnx.execute('CWGroup G ORDERBY GN '
+ 'WHERE G name GN, G name IN ("guests", "managers")')]
return f, groups
def test_relation_simple(self):
- f, (guests, managers) = self._in_group_facet()
- self.assertEqual(f.vocabulary(),
- [(u'guests', guests), (u'managers', managers)])
- # ensure rqlst is left unmodified
- self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
- #rqlst = rset.syntax_tree()
- self.assertEqual(f.possible_values(),
- [str(guests), str(managers)])
- # ensure rqlst is left unmodified
- self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
- f._cw.form[f.__regid__] = str(guests)
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X is CWUser, X in_group D, D eid %s' % guests)
+ with self.admin_access.web_request() as req:
+ f, (guests, managers) = self._in_group_facet(req)
+ self.assertEqual(f.vocabulary(),
+ [(u'guests', guests), (u'managers', managers)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(f.possible_values(),
+ [str(guests), str(managers)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ f._cw.form[f.__regid__] = str(guests)
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, X in_group D, D eid %s' % guests)
def test_relation_multiple_and(self):
- f, (guests, managers) = self._in_group_facet()
- f._cw.form[f.__regid__] = [str(guests), str(managers)]
- f._cw.form[f.__regid__ + '_andor'] = 'AND'
- f.add_rql_restrictions()
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X is CWUser, X in_group A, B eid %s, X in_group B, A eid %s' % (guests, managers))
+ with self.admin_access.web_request() as req:
+ f, (guests, managers) = self._in_group_facet(req)
+ f._cw.form[f.__regid__] = [str(guests), str(managers)]
+ f._cw.form[f.__regid__ + '_andor'] = 'AND'
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, X in_group A, B eid %s, X in_group B, A eid %s' % (guests, managers))
def test_relation_multiple_or(self):
- f, (guests, managers) = self._in_group_facet()
- f._cw.form[f.__regid__] = [str(guests), str(managers)]
- f._cw.form[f.__regid__ + '_andor'] = 'OR'
- f.add_rql_restrictions()
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X is CWUser, X in_group A, A eid IN(%s, %s)' % (guests, managers))
+ with self.admin_access.web_request() as req:
+ f, (guests, managers) = self._in_group_facet(req)
+ f._cw.form[f.__regid__] = [str(guests), str(managers)]
+ f._cw.form[f.__regid__ + '_andor'] = 'OR'
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, X in_group A, A eid IN(%s, %s)' % (guests, managers))
def test_relation_optional_rel(self):
- req = self.request()
- rset = self.execute('Any X,GROUP_CONCAT(GN) GROUPBY X '
- 'WHERE X in_group G?, G name GN, NOT G name "users"')
- rqlst = rset.syntax_tree().copy()
- select = rqlst.children[0]
- filtered_variable, baserql = facet.init_facets(rset, select)
+ with self.admin_access.web_request() as req:
+ rset = req.cnx.execute('Any X,GROUP_CONCAT(GN) GROUPBY X '
+ 'WHERE X in_group G?, G name GN, NOT G name "users"')
+ rqlst = rset.syntax_tree().copy()
+ select = rqlst.children[0]
+ filtered_variable, baserql = facet.init_facets(rset, select)
- f = facet.RelationFacet(req, rset=rset,
- select=select,
- filtered_variable=filtered_variable)
- f.rtype = 'in_group'
- f.role = 'subject'
- f.target_attr = 'name'
- guests, managers = [eid for eid, in self.execute('CWGroup G ORDERBY GN '
- 'WHERE G name GN, G name IN ("guests", "managers")')]
- self.assertEqual(f.vocabulary(),
- [(u'guests', guests), (u'managers', managers)])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X in_group G?, G name GN, NOT G name "users"')
- #rqlst = rset.syntax_tree()
- self.assertEqual(sorted(f.possible_values()),
- [str(guests), str(managers)])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X in_group G?, G name GN, NOT G name "users"')
- req.form[f.__regid__] = str(guests)
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X in_group G?, G name GN, NOT G name "users", X in_group D, D eid %s' % guests)
+ f = facet.RelationFacet(req, rset=rset,
+ select=select,
+ filtered_variable=filtered_variable)
+ f.rtype = 'in_group'
+ f.role = 'subject'
+ f.target_attr = 'name'
+ guests, managers = [eid for eid, in req.cnx.execute('CWGroup G ORDERBY GN '
+ 'WHERE G name GN, G name IN ("guests", "managers")')]
+ self.assertEqual(f.vocabulary(),
+ [(u'guests', guests), (u'managers', managers)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), "DISTINCT Any WHERE X in_group G?, G name GN, NOT G name 'users'")
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(sorted(f.possible_values()),
+ [str(guests), str(managers)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), "DISTINCT Any WHERE X in_group G?, G name GN, NOT G name 'users'")
+ req.form[f.__regid__] = str(guests)
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X in_group G?, G name GN, NOT G name 'users', X in_group D, D eid %s" % guests)
def test_relation_no_relation_1(self):
- f, (guests, managers) = self._in_group_facet(no_relation=True)
- self.assertEqual(f.vocabulary(),
- [(u'guests', guests), (u'managers', managers)])
- self.assertEqual(f.possible_values(),
- [str(guests), str(managers)])
- f._cw.create_entity('CWUser', login=u'hop', upassword='toto')
- self.assertEqual(f.vocabulary(),
- [(u'', ''), (u'guests', guests), (u'managers', managers)])
- self.assertEqual(f.possible_values(),
- [str(guests), str(managers), ''])
- f._cw.form[f.__regid__] = ''
- f.add_rql_restrictions()
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X is CWUser, NOT X in_group G')
+ with self.admin_access.web_request() as req:
+ f, (guests, managers) = self._in_group_facet(req, no_relation=True)
+ self.assertEqual(f.vocabulary(),
+ [(u'guests', guests), (u'managers', managers)])
+ self.assertEqual(f.possible_values(),
+ [str(guests), str(managers)])
+ f._cw.create_entity('CWUser', login=u'hop', upassword='toto')
+ self.assertEqual(f.vocabulary(),
+ [(u'', ''), (u'guests', guests), (u'managers', managers)])
+ self.assertEqual(f.possible_values(),
+ [str(guests), str(managers), ''])
+ f._cw.form[f.__regid__] = ''
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, NOT X in_group G')
def test_relation_no_relation_2(self):
- f, (guests, managers) = self._in_group_facet(no_relation=True)
- f._cw.form[f.__regid__] = ['', guests]
- f.select.save_state()
- f.add_rql_restrictions()
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X is CWUser, (NOT X in_group B) OR (X in_group A, A eid %s)' % guests)
- f.select.recover()
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X is CWUser')
+ with self.admin_access.web_request() as req:
+ f, (guests, managers) = self._in_group_facet(req, no_relation=True)
+ f._cw.form[f.__regid__] = ['', guests]
+ f.select.save_state()
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, (NOT X in_group B) OR (X in_group A, A eid %s)' % guests)
+ f.select.recover()
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser')
def test_relationattribute(self):
- f, (guests, managers) = self._in_group_facet(cls=facet.RelationAttributeFacet)
- self.assertEqual(f.vocabulary(),
- [(u'guests', u'guests'), (u'managers', u'managers')])
- # ensure rqlst is left unmodified
- self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
- #rqlst = rset.syntax_tree()
- self.assertEqual(f.possible_values(),
- ['guests', 'managers'])
- # ensure rqlst is left unmodified
- self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
- f._cw.form[f.__regid__] = 'guests'
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X is CWUser, X in_group E, E name 'guests'")
+ with self.admin_access.web_request() as req:
+ f, (guests, managers) = self._in_group_facet(req, cls=facet.RelationAttributeFacet)
+ self.assertEqual(f.vocabulary(),
+ [(u'guests', u'guests'), (u'managers', u'managers')])
+ # ensure rqlst is left unmodified
+ self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(f.possible_values(),
+ ['guests', 'managers'])
+ # ensure rqlst is left unmodified
+ self.assertEqual(f.select.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ f._cw.form[f.__regid__] = 'guests'
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X is CWUser, X in_group E, E name 'guests'")
def test_daterange(self):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst()
- f = facet.DateRangeFacet(req, rset=rset,
- select=rqlst.children[0],
- filtered_variable=filtered_variable)
- f.rtype = 'creation_date'
- mind, maxd = self.execute('Any MIN(CD), MAX(CD) WHERE X is CWUser, X creation_date CD')[0]
- self.assertEqual(f.vocabulary(),
- [(str(mind), mind),
- (str(maxd), maxd)])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- #rqlst = rset.syntax_tree()
- self.assertEqual(f.possible_values(),
- [str(mind), str(maxd)])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- req.form['%s_inf' % f.__regid__] = str(datetime2ticks(mind))
- req.form['%s_sup' % f.__regid__] = str(datetime2ticks(mind))
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- 'DISTINCT Any WHERE X is CWUser, X creation_date >= "%s", '
- 'X creation_date <= "%s"'
- % (mind.strftime('%Y/%m/%d'),
- mind.strftime('%Y/%m/%d')))
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
+ f = facet.DateRangeFacet(req, rset=rset,
+ select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ f.rtype = 'creation_date'
+ mind, maxd = req.cnx.execute('Any MIN(CD), MAX(CD) WHERE X is CWUser, X creation_date CD')[0]
+ self.assertEqual(f.vocabulary(),
+ [(str(mind), mind),
+ (str(maxd), maxd)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(f.possible_values(),
+ [str(mind), str(maxd)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ req.form['%s_inf' % f.__regid__] = str(datetime2ticks(mind))
+ req.form['%s_sup' % f.__regid__] = str(datetime2ticks(mind))
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, X creation_date >= "%s", '
+ 'X creation_date <= "%s"'
+ % (mind.strftime('%Y/%m/%d'),
+ mind.strftime('%Y/%m/%d')))
def test_attribute(self):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst()
- f = facet.AttributeFacet(req, rset=rset,
- select=rqlst.children[0],
- filtered_variable=filtered_variable)
- f.rtype = 'login'
- self.assertEqual(f.vocabulary(),
- [(u'admin', u'admin'), (u'anon', u'anon')])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- #rqlst = rset.syntax_tree()
- self.assertEqual(f.possible_values(),
- ['admin', 'anon'])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- req.form[f.__regid__] = 'admin'
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X is CWUser, X login 'admin'")
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
+ f = facet.AttributeFacet(req, rset=rset,
+ select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ f.rtype = 'login'
+ self.assertEqual(f.vocabulary(),
+ [(u'admin', u'admin'), (u'anon', u'anon')])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(f.possible_values(),
+ ['admin', 'anon'])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ req.form[f.__regid__] = 'admin'
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X is CWUser, X login 'admin'")
def test_bitfield(self):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst(
- 'CWAttribute X WHERE X ordernum XO',
- expected_baserql='Any X WHERE X ordernum XO, X is CWAttribute',
- expected_preparedrql='DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
- f = facet.BitFieldFacet(req, rset=rset,
- select=rqlst.children[0],
- filtered_variable=filtered_variable)
- f.choices = [('un', 1,), ('deux', 2,)]
- f.rtype = 'ordernum'
- self.assertEqual(f.vocabulary(),
- [(u'deux', 2), (u'un', 1)])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
- #rqlst = rset.syntax_tree()
- self.assertEqual(f.possible_values(),
- ['2', '1'])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
- req.form[f.__regid__] = '3'
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X ordernum XO, X is CWAttribute, X ordernum C HAVING 3 = (C & 3)")
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req,
+ 'CWAttribute X WHERE X ordernum XO',
+ expected_baserql='Any X WHERE X ordernum XO, X is CWAttribute',
+ expected_preparedrql='DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
+ f = facet.BitFieldFacet(req, rset=rset,
+ select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ f.choices = [('un', 1,), ('deux', 2,)]
+ f.rtype = 'ordernum'
+ self.assertEqual(f.vocabulary(),
+ [(u'deux', 2), (u'un', 1)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(f.possible_values(),
+ ['2', '1'])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
+ req.form[f.__regid__] = '3'
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X ordernum XO, X is CWAttribute, X ordernum C HAVING 3 = (C & 3)")
def test_bitfield_0_value(self):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst(
- 'CWAttribute X WHERE X ordernum XO',
- expected_baserql='Any X WHERE X ordernum XO, X is CWAttribute',
- expected_preparedrql='DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
- f = facet.BitFieldFacet(req, rset=rset,
- select=rqlst.children[0],
- filtered_variable=filtered_variable)
- f.choices = [('zero', 0,), ('un', 1,), ('deux', 2,)]
- f.rtype = 'ordernum'
- self.assertEqual(f.vocabulary(),
- [(u'deux', 2), (u'un', 1), (u'zero', 0)])
- self.assertEqual(f.possible_values(),
- ['2', '1', '0'])
- req.form[f.__regid__] = '0'
- f.add_rql_restrictions()
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X ordernum XO, X is CWAttribute, X ordernum C HAVING 0 = C")
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req,
+ 'CWAttribute X WHERE X ordernum XO',
+ expected_baserql='Any X WHERE X ordernum XO, X is CWAttribute',
+ expected_preparedrql='DISTINCT Any WHERE X ordernum XO, X is CWAttribute')
+ f = facet.BitFieldFacet(req, rset=rset,
+ select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ f.choices = [('zero', 0,), ('un', 1,), ('deux', 2,)]
+ f.rtype = 'ordernum'
+ self.assertEqual(f.vocabulary(),
+ [(u'deux', 2), (u'un', 1), (u'zero', 0)])
+ self.assertEqual(f.possible_values(),
+ ['2', '1', '0'])
+ req.form[f.__regid__] = '0'
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X ordernum XO, X is CWAttribute, X ordernum C HAVING 0 = C")
def test_rql_path_eid(self):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst()
- class RPF(facet.RQLPathFacet):
- path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
- filter_variable = 'O'
- label_variable = 'OL'
- f = RPF(req, rset=rset, select=rqlst.children[0],
- filtered_variable=filtered_variable)
- self.assertEqual(f.vocabulary(), [(u'admin', self.user().eid),])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- #rqlst = rset.syntax_tree()
- self.assertEqual(f.possible_values(),
- [str(self.user().eid),])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- req.form[f.__regid__] = '1'
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X is CWUser, X created_by F, F owned_by G, G eid 1")
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
+ class RPF(facet.RQLPathFacet):
+ path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+ filter_variable = 'O'
+ label_variable = 'OL'
+ f = RPF(req, rset=rset, select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ self.assertEqual(f.vocabulary(), [(u'admin', req.user.eid),])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ #rqlst = rset.syntax_tree()
+ self.assertEqual(f.possible_values(),
+ [str(req.user.eid),])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ req.form[f.__regid__] = '1'
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X is CWUser, X created_by F, F owned_by G, G eid 1")
def test_rql_path_eid_no_label(self):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst()
- class RPF(facet.RQLPathFacet):
- path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
- filter_variable = 'O'
- f = RPF(req, rset=rset, select=rqlst.children[0],
- filtered_variable=filtered_variable)
- self.assertEqual(f.vocabulary(), [(str(self.user().eid), self.user().eid),])
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
+ class RPF(facet.RQLPathFacet):
+ path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+ filter_variable = 'O'
+ f = RPF(req, rset=rset, select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ self.assertEqual(f.vocabulary(), [(str(req.user.eid), req.user.eid),])
def test_rql_path_attr(self):
- req, rset, rqlst, filtered_variable = self.prepare_rqlst()
- class RPF(facet.RQLPathFacet):
- path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
- filter_variable = 'OL'
- f = RPF(req, rset=rset, select=rqlst.children[0],
- filtered_variable=filtered_variable)
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
+ class RPF(facet.RQLPathFacet):
+ path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+ filter_variable = 'OL'
+ f = RPF(req, rset=rset, select=rqlst.children[0],
+ filtered_variable=filtered_variable)
- self.assertEqual(f.vocabulary(), [(u'admin', 'admin'),])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- self.assertEqual(f.possible_values(), ['admin',])
- # ensure rqlst is left unmodified
- self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
- req.form[f.__regid__] = 'admin'
- f.add_rql_restrictions()
- # selection is cluttered because rqlst has been prepared for facet (it
- # is not in real life)
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X is CWUser, X created_by G, G owned_by H, H login 'admin'")
+ self.assertEqual(f.vocabulary(), [(u'admin', 'admin'),])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(f.possible_values(), ['admin',])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ req.form[f.__regid__] = 'admin'
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X is CWUser, X created_by G, G owned_by H, H login 'admin'")
def test_rql_path_check_filter_label_variable(self):
- req, rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst()
- class RPF(facet.RQLPathFacet):
- path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
- filter_variable = 'OL'
- label_variable = 'OL'
- self.assertRaises(AssertionError, RPF, req, rset=rset,
- select=rqlst.children[0],
- filtered_variable=filtered_variable)
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst(req)
+ class RPF(facet.RQLPathFacet):
+ path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+ filter_variable = 'OL'
+ label_variable = 'OL'
+ self.assertRaises(AssertionError, RPF, req, rset=rset,
+ select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+
- def prepareg_aggregat_rqlst(self):
- return self.prepare_rqlst(
+ def test_rqlpath_range(self):
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepare_rqlst(req)
+ class RRF(facet.DateRangeRQLPathFacet):
+ path = [('X created_by U'), ('U owned_by O'), ('O creation_date OL')]
+ filter_variable = 'OL'
+ f = RRF(req, rset=rset, select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ mind, maxd = req.cnx.execute('Any MIN(CD), MAX(CD) WHERE X is CWUser, X created_by U, U owned_by O, O creation_date CD')[0]
+ self.assertEqual(f.vocabulary(), [(str(mind), mind),
+ (str(maxd), maxd)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ self.assertEqual(f.possible_values(),
+ [str(mind), str(maxd)])
+ # ensure rqlst is left unmodified
+ self.assertEqual(rqlst.as_string(), 'DISTINCT Any WHERE X is CWUser')
+ req.form['%s_inf' % f.__regid__] = str(datetime2ticks(mind))
+ req.form['%s_sup' % f.__regid__] = str(datetime2ticks(mind))
+ f.add_rql_restrictions()
+ # selection is cluttered because rqlst has been prepared for facet (it
+ # is not in real life)
+ self.assertEqual(f.select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, X created_by G, G owned_by H, H creation_date >= "%s", '
+ 'H creation_date <= "%s"'
+ % (mind.strftime('%Y/%m/%d'),
+ mind.strftime('%Y/%m/%d')))
+
+ def prepareg_aggregat_rqlst(self, req):
+ return self.prepare_rqlst(req,
'Any 1, COUNT(X) WHERE X is CWUser, X creation_date XD, '
'X modification_date XM, Y creation_date YD, Y is CWGroup '
'HAVING DAY(XD)>=DAY(YD) AND DAY(XM)<=DAY(YD)', 'X',
@@ -317,47 +359,50 @@
def test_aggregat_query_cleanup_select(self):
- req, rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst()
- select = rqlst.children[0]
- facet.cleanup_select(select, filtered_variable=filtered_variable)
- self.assertEqual(select.as_string(),
- 'DISTINCT Any WHERE X is CWUser, X creation_date XD, '
- 'X modification_date XM, Y creation_date YD, Y is CWGroup '
- 'HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)')
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst(req)
+ select = rqlst.children[0]
+ facet.cleanup_select(select, filtered_variable=filtered_variable)
+ self.assertEqual(select.as_string(),
+ 'DISTINCT Any WHERE X is CWUser, X creation_date XD, '
+ 'X modification_date XM, Y creation_date YD, Y is CWGroup '
+ 'HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)')
def test_aggregat_query_rql_path(self):
- req, rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst()
- class RPF(facet.RQLPathFacet):
- path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
- filter_variable = 'OL'
- f = RPF(req, rset=rset, select=rqlst.children[0],
- filtered_variable=filtered_variable)
- self.assertEqual(f.vocabulary(), [(u'admin', u'admin')])
- self.assertEqual(f.possible_values(), ['admin'])
- req.form[f.__regid__] = 'admin'
- f.add_rql_restrictions()
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X is CWUser, X creation_date XD, "
- "X modification_date XM, Y creation_date YD, Y is CWGroup, "
- "X created_by G, G owned_by H, H login 'admin' "
- "HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)")
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst(req)
+ class RPF(facet.RQLPathFacet):
+ path = [('X created_by U'), ('U owned_by O'), ('O login OL')]
+ filter_variable = 'OL'
+ f = RPF(req, rset=rset, select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ self.assertEqual(f.vocabulary(), [(u'admin', u'admin')])
+ self.assertEqual(f.possible_values(), ['admin'])
+ req.form[f.__regid__] = 'admin'
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X is CWUser, X creation_date XD, "
+ "X modification_date XM, Y creation_date YD, Y is CWGroup, "
+ "X created_by G, G owned_by H, H login 'admin' "
+ "HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)")
def test_aggregat_query_attribute(self):
- req, rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst()
- f = facet.AttributeFacet(req, rset=rset,
- select=rqlst.children[0],
- filtered_variable=filtered_variable)
- f.rtype = 'login'
- self.assertEqual(f.vocabulary(),
- [(u'admin', u'admin'), (u'anon', u'anon')])
- self.assertEqual(f.possible_values(),
- ['admin', 'anon'])
- req.form[f.__regid__] = 'admin'
- f.add_rql_restrictions()
- self.assertEqual(f.select.as_string(),
- "DISTINCT Any WHERE X is CWUser, X creation_date XD, "
- "X modification_date XM, Y creation_date YD, Y is CWGroup, X login 'admin' "
- "HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)")
+ with self.admin_access.web_request() as req:
+ rset, rqlst, filtered_variable = self.prepareg_aggregat_rqlst(req)
+ f = facet.AttributeFacet(req, rset=rset,
+ select=rqlst.children[0],
+ filtered_variable=filtered_variable)
+ f.rtype = 'login'
+ self.assertEqual(f.vocabulary(),
+ [(u'admin', u'admin'), (u'anon', u'anon')])
+ self.assertEqual(f.possible_values(),
+ ['admin', 'anon'])
+ req.form[f.__regid__] = 'admin'
+ f.add_rql_restrictions()
+ self.assertEqual(f.select.as_string(),
+ "DISTINCT Any WHERE X is CWUser, X creation_date XD, "
+ "X modification_date XM, Y creation_date YD, Y is CWGroup, X login 'admin' "
+ "HAVING DAY(XD) >= DAY(YD), DAY(XM) <= DAY(YD)")
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_form.py
--- a/web/test/unittest_form.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_form.py Wed Sep 24 18:04:30 2014 +0200
@@ -34,131 +34,138 @@
class FieldsFormTC(CubicWebTC):
def test_form_field_format(self):
- form = FieldsForm(self.request(), None)
- self.assertEqual(StringField().format(form), 'text/html')
- self.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
- self.commit()
- self.assertEqual(StringField().format(form), 'text/rest')
+ with self.admin_access.web_request() as req:
+ form = FieldsForm(req, None)
+ self.assertEqual(StringField().format(form), 'text/html')
+ req.cnx.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
+ req.cnx.commit()
+ self.assertEqual(StringField().format(form), 'text/rest')
def test_process_posted(self):
class AForm(FieldsForm):
anint = IntField()
astring = StringField()
- form = AForm(self.request(anint='1', astring='2', _cw_fields='anint,astring'))
- self.assertEqual(form.process_posted(), {'anint': 1, 'astring': '2'})
- form = AForm(self.request(anint='1a', astring='2b', _cw_fields='anint,astring'))
- self.assertRaises(ValidationError, form.process_posted)
+ with self.admin_access.web_request(anint='1', astring='2', _cw_fields='anint,astring') as req:
+ form = AForm(req)
+ self.assertEqual(form.process_posted(), {'anint': 1, 'astring': '2'})
+ with self.admin_access.web_request(anint='1a', astring='2b', _cw_fields='anint,astring') as req:
+ form = AForm(req)
+ self.assertRaises(ValidationError, form.process_posted)
class EntityFieldsFormTC(CubicWebTC):
- def setUp(self):
- super(EntityFieldsFormTC, self).setUp()
- self.req = self.request()
- self.entity = self.user(self.req)
+ def test_form_field_choices(self):
+ with self.admin_access.web_request() as req:
+ b = req.create_entity('BlogEntry', title=u'di mascii code', content=u'a best-seller')
+ t = req.create_entity('Tag', name=u'x')
+ form1 = self.vreg['forms'].select('edition', req, entity=t)
+ choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
+ self.assertIn(unicode(b.eid), choices)
+ form2 = self.vreg['forms'].select('edition', req, entity=b)
+ choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
+ self.assertIn(unicode(t.eid), choices)
- def test_form_field_choices(self):
- b = self.req.create_entity('BlogEntry', title=u'di mascii code', content=u'a best-seller')
- t = self.req.create_entity('Tag', name=u'x')
- form1 = self.vreg['forms'].select('edition', self.req, entity=t)
- choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
- self.assertIn(unicode(b.eid), choices)
- form2 = self.vreg['forms'].select('edition', self.req, entity=b)
- choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
- self.assertIn(unicode(t.eid), choices)
+ b.cw_clear_all_caches()
+ t.cw_clear_all_caches()
+ req.cnx.execute('SET X tags Y WHERE X is Tag, Y is BlogEntry')
- b.cw_clear_all_caches()
- t.cw_clear_all_caches()
- self.execute('SET X tags Y WHERE X is Tag, Y is BlogEntry')
-
- choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
- self.assertIn(unicode(b.eid), choices)
- choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
- self.assertIn(unicode(t.eid), choices)
+ choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
+ self.assertIn(unicode(b.eid), choices)
+ choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
+ self.assertIn(unicode(t.eid), choices)
def test_form_field_choices_new_entity(self):
- e = self.vreg['etypes'].etype_class('CWUser')(self.request())
- form = self.vreg['forms'].select('edition', self.req, entity=e)
- unrelated = [rview for rview, reid in form.field_by_name('in_group', 'subject').choices(form)]
- # should be default groups but owners, i.e. managers, users, guests
- self.assertEqual(unrelated, [u'guests', u'managers', u'users'])
+ with self.admin_access.web_request() as req:
+ e = self.vreg['etypes'].etype_class('CWUser')(req)
+ form = self.vreg['forms'].select('edition', req, entity=e)
+ unrelated = [rview for rview, reid in form.field_by_name('in_group', 'subject').choices(form)]
+ # should be default groups but owners, i.e. managers, users, guests
+ self.assertEqual(unrelated, [u'guests', u'managers', u'users'])
def test_consider_req_form_params(self):
- e = self.vreg['etypes'].etype_class('CWUser')(self.request())
- e.eid = 'A'
- form = EntityFieldsForm(self.request(login=u'toto'), None, entity=e)
- field = StringField(name='login', role='subject', eidparam=True)
- form.append_field(field)
- form.build_context({})
- self.assertEqual(field.widget.values(form, field), (u'toto',))
+ with self.admin_access.web_request() as req:
+ e = self.vreg['etypes'].etype_class('CWUser')(req)
+ e.eid = 'A'
+ with self.admin_access.web_request(login=u'toto') as toto_req:
+ form = EntityFieldsForm(toto_req, None, entity=e)
+ field = StringField(name='login', role='subject', eidparam=True)
+ form.append_field(field)
+ form.build_context({})
+ self.assertEqual(field.widget.values(form, field), (u'toto',))
def test_linkto_field_duplication_inout(self):
- e = self.vreg['etypes'].etype_class('CWUser')(self.request())
- e.eid = 'A'
- e._cw = self.req
- geid = self.execute('CWGroup X WHERE X name "users"')[0][0]
- self.req.form['__linkto'] = 'in_group:%s:subject' % geid
- form = self.vreg['forms'].select('edition', self.req, entity=e)
- form.content_type = 'text/html'
- pageinfo = self._check_html(form.render(), form, template=None)
- inputs = pageinfo.find_tag('select', False)
- ok = False
- for selectnode in pageinfo.matching_nodes('select', name='from_in_group-subject:A'):
- for optionnode in selectnode:
- self.assertEqual(optionnode.get('value'), str(geid))
- self.assertEqual(ok, False)
- ok = True
- inputs = pageinfo.find_tag('input', False)
- self.assertFalse(list(pageinfo.matching_nodes('input', name='__linkto')))
+ with self.admin_access.web_request() as req:
+ e = self.vreg['etypes'].etype_class('CWUser')(req)
+ e.eid = 'A'
+ e._cw = req
+ geid = req.cnx.execute('CWGroup X WHERE X name "users"')[0][0]
+ req.form['__linkto'] = 'in_group:%s:subject' % geid
+ form = self.vreg['forms'].select('edition', req, entity=e)
+ form.content_type = 'text/html'
+ pageinfo = self._check_html(form.render(), form, template=None)
+ inputs = pageinfo.find_tag('select', False)
+ ok = False
+ for selectnode in pageinfo.matching_nodes('select', name='from_in_group-subject:A'):
+ for optionnode in selectnode:
+ self.assertEqual(optionnode.get('value'), str(geid))
+ self.assertEqual(ok, False)
+ ok = True
+ inputs = pageinfo.find_tag('input', False)
+ self.assertFalse(list(pageinfo.matching_nodes('input', name='__linkto')))
def test_reledit_composite_field(self):
- rset = self.execute('INSERT BlogEntry X: X title "cubicweb.org", X content "hop"')
- form = self.vreg['views'].select('reledit', self.request(),
- rset=rset, row=0, rtype='content')
- data = form.render(row=0, rtype='content', formid='base', action='edit_rtype')
- self.assertTrue('content_format' in data)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('INSERT BlogEntry X: X title "cubicweb.org", X content "hop"')
+ form = self.vreg['views'].select('reledit', req,
+ rset=rset, row=0, rtype='content')
+ data = form.render(row=0, rtype='content', formid='base', action='edit_rtype')
+ self.assertIn('content_format', data)
# form tests ##############################################################
def test_form_inheritance(self):
- class CustomChangeStateForm(ChangeStateForm):
- hello = IntField(name='youlou')
- creation_date = DateTimeField(widget=DateTimePicker)
- form = CustomChangeStateForm(self.req, redirect_path='perdu.com',
- entity=self.entity)
- form.render(formvalues=dict(state=123, trcomment=u'',
- trcomment_format=u'text/plain'))
+ with self.admin_access.web_request() as req:
+ class CustomChangeStateForm(ChangeStateForm):
+ hello = IntField(name='youlou')
+ creation_date = DateTimeField(widget=DateTimePicker)
+ form = CustomChangeStateForm(req, redirect_path='perdu.com',
+ entity=req.user)
+ form.render(formvalues=dict(state=123, trcomment=u'',
+ trcomment_format=u'text/plain'))
def test_change_state_form(self):
- form = ChangeStateForm(self.req, redirect_path='perdu.com',
- entity=self.entity)
- form.render(formvalues=dict(state=123, trcomment=u'',
- trcomment_format=u'text/plain'))
+ with self.admin_access.web_request() as req:
+ form = ChangeStateForm(req, redirect_path='perdu.com',
+ entity=req.user)
+ form.render(formvalues=dict(state=123, trcomment=u'',
+ trcomment_format=u'text/plain'))
# fields tests ############################################################
- def _render_entity_field(self, name, form):
+ def _render_entity_field(self, req, name, form):
form.build_context({})
- renderer = FormRenderer(self.req)
+ renderer = FormRenderer(req)
return form.field_by_name(name, 'subject').render(form, renderer)
- def _test_richtextfield(self, expected):
+ def _test_richtextfield(self, req, expected):
class RTFForm(EntityFieldsForm):
description = RichTextField(eidparam=True, role='subject')
- state = self.vreg['etypes'].etype_class('State')(self.req)
+ state = self.vreg['etypes'].etype_class('State')(req)
state.eid = 'S'
- form = RTFForm(self.req, redirect_path='perdu.com', entity=state)
+ form = RTFForm(req, redirect_path='perdu.com', entity=state)
# make it think it can use fck editor anyway
form.field_by_name('description', 'subject').format = lambda form, field=None: 'text/html'
- self.assertMultiLineEqual(self._render_entity_field('description', form),
+ self.assertMultiLineEqual(self._render_entity_field(req, 'description', form),
expected % {'eid': state.eid})
def test_richtextfield_1(self):
- self.req.use_fckeditor = lambda: False
- self._test_richtextfield('''
+ with self.admin_access.web_request() as req:
+ req.use_fckeditor = lambda: False
+ self._test_richtextfield(req, '''
text/cubicweb-page-template
text/html
text/plain
@@ -167,8 +174,9 @@
def test_richtextfield_2(self):
- self.req.use_fckeditor = lambda: True
- self._test_richtextfield(' ')
+ with self.admin_access.web_request() as req:
+ req.use_fckeditor = lambda: True
+ self._test_richtextfield(req, ' ')
def test_filefield(self):
@@ -179,10 +187,11 @@
encoding_field=StringField(name='data_encoding', max_length=20,
eidparam=True, role='subject'),
eidparam=True, role='subject')
- file = self.req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
- data=Binary('new widgets system'))
- form = FFForm(self.req, redirect_path='perdu.com', entity=file)
- self.assertMultiLineEqual(self._render_entity_field('data', form),
+ with self.admin_access.web_request() as req:
+ file = req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
+ data=Binary('new widgets system'))
+ form = FFForm(req, redirect_path='perdu.com', entity=file)
+ self.assertMultiLineEqual(self._render_entity_field(req, 'data', form),
'''
@@ -202,10 +211,11 @@
encoding_field=StringField('data_encoding', max_length=20,
eidparam=True, role='subject'),
eidparam=True, role='subject')
- file = self.req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
- data=Binary('new widgets system'))
- form = EFFForm(self.req, redirect_path='perdu.com', entity=file)
- self.assertMultiLineEqual(self._render_entity_field('data', form),
+ with self.admin_access.web_request() as req:
+ file = req.create_entity('File', data_name=u"pouet.txt", data_encoding=u'UTF-8',
+ data=Binary('new widgets system'))
+ form = EFFForm(req, redirect_path='perdu.com', entity=file)
+ self.assertMultiLineEqual(self._render_entity_field(req, 'data', form),
'''
@@ -222,13 +232,14 @@
def test_passwordfield(self):
class PFForm(EntityFieldsForm):
upassword = PasswordField(eidparam=True, role='subject')
- form = PFForm(self.req, redirect_path='perdu.com', entity=self.entity)
- self.assertMultiLineEqual(self._render_entity_field('upassword', form),
- '''
+ with self.admin_access.web_request() as req:
+ form = PFForm(req, redirect_path='perdu.com', entity=req.user)
+ self.assertMultiLineEqual(self._render_entity_field(req, 'upassword', form),
+ '''
-
confirm password ''' % {'eid': self.entity.eid})
+
confirm password ''' % {'eid': req.user.eid})
# def test_datefield(self):
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_formfields.py
--- a/web/test/unittest_formfields.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_formfields.py Wed Sep 24 18:04:30 2014 +0200
@@ -25,7 +25,7 @@
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.web.formwidgets import PasswordInput, TextArea, Select, Radio
from cubicweb.web.formfields import *
-from cubicweb.web.views.forms import EntityFieldsForm
+from cubicweb.web.views.forms import EntityFieldsForm, FieldsForm
from cubes.file.entities import File
@@ -37,14 +37,11 @@
class GuessFieldTC(CubicWebTC):
- def setUp(self):
- super(GuessFieldTC, self).setUp()
- self.req = self.request()
-
def test_state_fields(self):
- title_field = guess_field(schema['State'], schema['name'], req=self.req)
- self.assertIsInstance(title_field, StringField)
- self.assertEqual(title_field.required, True)
+ with self.admin_access.web_request() as req:
+ title_field = guess_field(schema['State'], schema['name'], req=req)
+ self.assertIsInstance(title_field, StringField)
+ self.assertEqual(title_field.required, True)
# synopsis_field = guess_field(schema['State'], schema['synopsis'])
# self.assertIsInstance(synopsis_field, StringField)
@@ -52,18 +49,20 @@
# self.assertEqual(synopsis_field.required, False)
# self.assertEqual(synopsis_field.help, 'an abstract for this state')
- description_field = guess_field(schema['State'], schema['description'], req=self.req)
- self.assertIsInstance(description_field, RichTextField)
- self.assertEqual(description_field.required, False)
- self.assertEqual(description_field.format_field, None)
+ with self.admin_access.web_request() as req:
+ description_field = guess_field(schema['State'], schema['description'], req=req)
+ self.assertIsInstance(description_field, RichTextField)
+ self.assertEqual(description_field.required, False)
+ self.assertEqual(description_field.format_field, None)
# description_format_field = guess_field(schema['State'], schema['description_format'])
# self.assertEqual(description_format_field, None)
- description_format_field = guess_field(schema['State'], schema['description_format'],
- req=self.req)
- self.assertEqual(description_format_field.internationalizable, True)
- self.assertEqual(description_format_field.sort, True)
+ with self.admin_access.web_request() as req:
+ description_format_field = guess_field(schema['State'], schema['description_format'],
+ req=req)
+ self.assertEqual(description_format_field.internationalizable, True)
+ self.assertEqual(description_format_field.sort, True)
# wikiid_field = guess_field(schema['State'], schema['wikiid'])
# self.assertIsInstance(wikiid_field, StringField)
@@ -71,25 +70,29 @@
def test_cwuser_fields(self):
- upassword_field = guess_field(schema['CWUser'], schema['upassword'], req=self.req)
- self.assertIsInstance(upassword_field, StringField)
- self.assertIsInstance(upassword_field.widget, PasswordInput)
- self.assertEqual(upassword_field.required, True)
+ with self.admin_access.web_request() as req:
+ upassword_field = guess_field(schema['CWUser'], schema['upassword'], req=req)
+ self.assertIsInstance(upassword_field, StringField)
+ self.assertIsInstance(upassword_field.widget, PasswordInput)
+ self.assertEqual(upassword_field.required, True)
- last_login_time_field = guess_field(schema['CWUser'], schema['last_login_time'], req=self.req)
- self.assertIsInstance(last_login_time_field, DateTimeField)
- self.assertEqual(last_login_time_field.required, False)
+ with self.admin_access.web_request() as req:
+ last_login_time_field = guess_field(schema['CWUser'], schema['last_login_time'], req=req)
+ self.assertIsInstance(last_login_time_field, DateTimeField)
+ self.assertEqual(last_login_time_field.required, False)
- in_group_field = guess_field(schema['CWUser'], schema['in_group'], req=self.req)
- self.assertIsInstance(in_group_field, RelationField)
- self.assertEqual(in_group_field.required, True)
- self.assertEqual(in_group_field.role, 'subject')
- self.assertEqual(in_group_field.help, 'groups grant permissions to the user')
+ with self.admin_access.web_request() as req:
+ in_group_field = guess_field(schema['CWUser'], schema['in_group'], req=req)
+ self.assertIsInstance(in_group_field, RelationField)
+ self.assertEqual(in_group_field.required, True)
+ self.assertEqual(in_group_field.role, 'subject')
+ self.assertEqual(in_group_field.help, 'groups grant permissions to the user')
- owned_by_field = guess_field(schema['CWUser'], schema['owned_by'], 'object', req=self.req)
- self.assertIsInstance(owned_by_field, RelationField)
- self.assertEqual(owned_by_field.required, False)
- self.assertEqual(owned_by_field.role, 'object')
+ with self.admin_access.web_request() as req:
+ owned_by_field = guess_field(schema['CWUser'], schema['owned_by'], 'object', req=req)
+ self.assertIsInstance(owned_by_field, RelationField)
+ self.assertEqual(owned_by_field.required, False)
+ self.assertEqual(owned_by_field.role, 'object')
def test_file_fields(self):
@@ -100,64 +103,85 @@
# data_name_field = guess_field(schema['File'], schema['data_name'])
# self.assertEqual(data_name_field, None)
- data_field = guess_field(schema['File'], schema['data'], req=self.req)
- self.assertIsInstance(data_field, FileField)
- self.assertEqual(data_field.required, True)
- self.assertIsInstance(data_field.format_field, StringField)
- self.assertIsInstance(data_field.encoding_field, StringField)
- self.assertIsInstance(data_field.name_field, StringField)
+ with self.admin_access.web_request() as req:
+ data_field = guess_field(schema['File'], schema['data'], req=req)
+ self.assertIsInstance(data_field, FileField)
+ self.assertEqual(data_field.required, True)
+ self.assertIsInstance(data_field.format_field, StringField)
+ self.assertIsInstance(data_field.encoding_field, StringField)
+ self.assertIsInstance(data_field.name_field, StringField)
def test_constraints_priority(self):
- salesterm_field = guess_field(schema['Salesterm'], schema['reason'], req=self.req)
- constraints = schema['reason'].rdef('Salesterm', 'String').constraints
- self.assertEqual([c.__class__ for c in constraints],
- [SizeConstraint, StaticVocabularyConstraint])
- self.assertIsInstance(salesterm_field, StringField)
- self.assertIsInstance(salesterm_field.widget, Select)
+ with self.admin_access.web_request() as req:
+ salesterm_field = guess_field(schema['Salesterm'], schema['reason'], req=req)
+ constraints = schema['reason'].rdef('Salesterm', 'String').constraints
+ self.assertEqual([c.__class__ for c in constraints],
+ [SizeConstraint, StaticVocabularyConstraint])
+ self.assertIsInstance(salesterm_field, StringField)
+ self.assertIsInstance(salesterm_field.widget, Select)
def test_bool_field_base(self):
- field = guess_field(schema['CWAttribute'], schema['indexed'], req=self.req)
- self.assertIsInstance(field, BooleanField)
- self.assertEqual(field.required, False)
- self.assertIsInstance(field.widget, Radio)
- self.assertEqual(field.vocabulary(mock(_cw=mock(_=unicode))),
- [(u'yes', '1'), (u'no', '')])
+ with self.admin_access.web_request() as req:
+ field = guess_field(schema['CWAttribute'], schema['indexed'], req=req)
+ self.assertIsInstance(field, BooleanField)
+ self.assertEqual(field.required, False)
+ self.assertIsInstance(field.widget, Radio)
+ self.assertEqual(field.vocabulary(mock(_cw=mock(_=unicode))),
+ [(u'yes', '1'), (u'no', '')])
def test_bool_field_explicit_choices(self):
- field = guess_field(schema['CWAttribute'], schema['indexed'],
- choices=[(u'maybe', '1'), (u'no', '')], req=self.req)
- self.assertIsInstance(field.widget, Radio)
- self.assertEqual(field.vocabulary(mock(req=mock(_=unicode))),
- [(u'maybe', '1'), (u'no', '')])
+ with self.admin_access.web_request() as req:
+ field = guess_field(schema['CWAttribute'], schema['indexed'],
+ choices=[(u'maybe', '1'), (u'no', '')], req=req)
+ self.assertIsInstance(field.widget, Radio)
+ self.assertEqual(field.vocabulary(mock(req=mock(_=unicode))),
+ [(u'maybe', '1'), (u'no', '')])
class MoreFieldsTC(CubicWebTC):
def test_rtf_format_field(self):
- req = self.request()
- req.use_fckeditor = lambda: False
- e = self.vreg['etypes'].etype_class('State')(req)
- form = EntityFieldsForm(req, entity=e)
- description_field = guess_field(schema['State'], schema['description'])
- description_format_field = description_field.get_format_field(form)
- self.assertEqual(description_format_field.internationalizable, True)
- self.assertEqual(description_format_field.sort, True)
- # unlike below, initial is bound to form.form_field_format
- self.assertEqual(description_format_field.value(form), 'text/html')
- self.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
- self.commit()
- self.assertEqual(description_format_field.value(form), 'text/rest')
+ with self.admin_access.web_request() as req:
+ req.use_fckeditor = lambda: False
+ e = self.vreg['etypes'].etype_class('State')(req)
+ form = EntityFieldsForm(req, entity=e)
+ description_field = guess_field(schema['State'], schema['description'])
+ description_format_field = description_field.get_format_field(form)
+ self.assertEqual(description_format_field.internationalizable, True)
+ self.assertEqual(description_format_field.sort, True)
+ # unlike below, initial is bound to form.form_field_format
+ self.assertEqual(description_format_field.value(form), 'text/html')
+ req.cnx.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
+ req.cnx.commit()
+ self.assertEqual(description_format_field.value(form), 'text/rest')
def test_property_key_field(self):
from cubicweb.web.views.cwproperties import PropertyKeyField
- req = self.request()
- field = PropertyKeyField(name='test')
- e = self.vreg['etypes'].etype_class('CWProperty')(req)
- renderer = self.vreg['formrenderers'].select('base', req)
- form = EntityFieldsForm(req, entity=e)
- form.formvalues = {}
- field.render(form, renderer)
+ with self.admin_access.web_request() as req:
+ field = PropertyKeyField(name='test')
+ e = self.vreg['etypes'].etype_class('CWProperty')(req)
+ renderer = self.vreg['formrenderers'].select('base', req)
+ form = EntityFieldsForm(req, entity=e)
+ form.formvalues = {}
+ field.render(form, renderer)
+
+
+class CompoundFieldTC(CubicWebTC):
+
+ def test_multipart(self):
+ """Ensures that compound forms have needs_multipart set if their
+ children require it"""
+ class AForm(FieldsForm):
+ comp = CompoundField([IntField(), StringField()])
+ with self.admin_access.web_request() as req:
+ aform = AForm(req, None)
+ self.assertFalse(aform.needs_multipart)
+ class MForm(FieldsForm):
+ comp = CompoundField([IntField(), FileField()])
+ with self.admin_access.web_request() as req:
+ mform = MForm(req, None)
+ self.assertTrue(mform.needs_multipart)
class UtilsTC(TestCase):
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_http.py
--- a/web/test/unittest_http.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_http.py Wed Sep 24 18:04:30 2014 +0200
@@ -15,9 +15,13 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see
.
+
+import contextlib
+
from logilab.common.testlib import TestCase, unittest_main, tag, Tags
from cubicweb.devtools.fake import FakeRequest
+from cubicweb.devtools.testlib import CubicWebTC
def _test_cache(hin, hout, method='GET'):
@@ -290,5 +294,165 @@
self.assertEqual(value, [DATE])
+alloworig = 'access-control-allow-origin'
+allowmethods = 'access-control-allow-methods'
+allowheaders = 'access-control-allow-headers'
+allowcreds = 'access-control-allow-credentials'
+exposeheaders = 'access-control-expose-headers'
+maxage = 'access-control-max-age'
+
+requestmethod = 'access-control-request-method'
+requestheaders = 'access-control-request-headers'
+
+class _BaseAccessHeadersTC(CubicWebTC):
+
+ @contextlib.contextmanager
+ def options(self, **options):
+ for k, values in options.items():
+ self.config.set_option(k, values)
+ try:
+ yield
+ finally:
+ for k in options:
+ self.config.set_option(k, '')
+ def check_no_cors(self, req):
+ self.assertEqual(None, req.get_response_header(alloworig))
+ self.assertEqual(None, req.get_response_header(allowmethods))
+ self.assertEqual(None, req.get_response_header(allowheaders))
+ self.assertEqual(None, req.get_response_header(allowcreds))
+ self.assertEqual(None, req.get_response_header(exposeheaders))
+ self.assertEqual(None, req.get_response_header(maxage))
+
+
+class SimpleAccessHeadersTC(_BaseAccessHeadersTC):
+
+ def test_noaccess(self):
+ with self.admin_access.web_request() as req:
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_noorigin(self):
+ with self.options(**{alloworig: '*'}):
+ with self.admin_access.web_request() as req:
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_origin_noaccess(self):
+ with self.admin_access.web_request() as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_origin_noaccess_bad_host(self):
+ with self.options(**{alloworig: '*'}):
+ with self.admin_access.web_request() as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ # in these tests, base_url is http://testing.fr/cubicweb/
+ req.set_request_header('Host', 'badhost.net')
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_explicit_origin_noaccess(self):
+ with self.options(**{alloworig: ['http://www.toto.org', 'http://othersite.fr']}):
+ with self.admin_access.web_request() as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ # in these tests, base_url is http://testing.fr/cubicweb/
+ req.set_request_header('Host', 'testing.fr')
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_origin_access(self):
+ with self.options(**{alloworig: '*'}):
+ with self.admin_access.web_request() as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ # in these tests, base_url is http://testing.fr/cubicweb/
+ req.set_request_header('Host', 'testing.fr')
+ data = self.app_handle_request(req)
+ self.assertEqual('http://www.cubicweb.org',
+ req.get_response_header(alloworig))
+
+ def test_explicit_origin_access(self):
+ with self.options(**{alloworig: ['http://www.cubicweb.org', 'http://othersite.fr']}):
+ with self.admin_access.web_request() as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ # in these tests, base_url is http://testing.fr/cubicweb/
+ req.set_request_header('Host', 'testing.fr')
+ data = self.app_handle_request(req)
+ self.assertEqual('http://www.cubicweb.org',
+ req.get_response_header(alloworig))
+
+ def test_origin_access_headers(self):
+ with self.options(**{alloworig: '*',
+ exposeheaders: ['ExposeHead1', 'ExposeHead2'],
+ allowheaders: ['AllowHead1', 'AllowHead2'],
+ allowmethods: ['GET', 'POST', 'OPTIONS']}):
+ with self.admin_access.web_request() as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ # in these tests, base_url is http://testing.fr/cubicweb/
+ req.set_request_header('Host', 'testing.fr')
+ data = self.app_handle_request(req)
+ self.assertEqual('http://www.cubicweb.org',
+ req.get_response_header(alloworig))
+ self.assertEqual("true",
+ req.get_response_header(allowcreds))
+ self.assertEqual(['ExposeHead1', 'ExposeHead2'],
+ req.get_response_header(exposeheaders))
+ self.assertEqual(None, req.get_response_header(allowmethods))
+ self.assertEqual(None, req.get_response_header(allowheaders))
+
+
+class PreflightAccessHeadersTC(_BaseAccessHeadersTC):
+
+ def test_noaccess(self):
+ with self.admin_access.web_request(method='OPTIONS') as req:
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_noorigin(self):
+ with self.options(**{alloworig: '*'}):
+ with self.admin_access.web_request(method='OPTIONS') as req:
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_origin_noaccess(self):
+ with self.admin_access.web_request(method='OPTIONS') as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_origin_noaccess_bad_host(self):
+ with self.options(**{alloworig: '*'}):
+ with self.admin_access.web_request(method='OPTIONS') as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ # in these tests, base_url is http://testing.fr/cubicweb/
+ req.set_request_header('Host', 'badhost.net')
+ data = self.app_handle_request(req)
+ self.check_no_cors(req)
+
+ def test_origin_access(self):
+ with self.options(**{alloworig: '*',
+ exposeheaders: ['ExposeHead1', 'ExposeHead2'],
+ allowheaders: ['AllowHead1', 'AllowHead2'],
+ allowmethods: ['GET', 'POST', 'OPTIONS']}):
+ with self.admin_access.web_request(method='OPTIONS') as req:
+ req.set_request_header('Origin', 'http://www.cubicweb.org')
+ # in these tests, base_url is http://testing.fr/cubicweb/
+ req.set_request_header('Host', 'testing.fr')
+ req.set_request_header(requestmethod, 'GET')
+
+ data = self.app_handle_request(req)
+ self.assertEqual(200, req.status_out)
+ self.assertEqual('http://www.cubicweb.org',
+ req.get_response_header(alloworig))
+ self.assertEqual("true",
+ req.get_response_header(allowcreds))
+ self.assertEqual(set(['GET', 'POST', 'OPTIONS']),
+ req.get_response_header(allowmethods))
+ self.assertEqual(set(['AllowHead1', 'AllowHead2']),
+ req.get_response_header(allowheaders))
+ self.assertEqual(None,
+ req.get_response_header(exposeheaders))
+
+
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_idownloadable.py
--- a/web/test/unittest_idownloadable.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_idownloadable.py Wed Sep 24 18:04:30 2014 +0200
@@ -21,7 +21,7 @@
from logilab.common.testlib import unittest_main
-from cubicweb.devtools.testlib import CubicWebTC
+from cubicweb.devtools.testlib import CubicWebTC, real_error_handling
from cubicweb import view
from cubicweb.predicates import is_instance
@@ -63,23 +63,22 @@
self.addCleanup(partial(self.vreg.unregister, IDownloadableUser))
def test_header_simple_case(self):
- req = self.request()
- req.form['vid'] = 'download'
- req.form['eid'] = str(req.user.eid)
- data = self.ctrl_publish(req, 'view')
- get = req.headers_out.getRawHeaders
- self.assertEqual(['attachment;filename="admin.txt"'],
- get('content-disposition'))
- self.assertEqual(['text/plain;charset=ascii'],
- get('content-type'))
- self.assertEqual('Babar is not dead!', data)
+ with self.admin_access.web_request() as req:
+ req.form['vid'] = 'download'
+ req.form['eid'] = str(req.user.eid)
+ data = self.ctrl_publish(req, 'view')
+ get = req.headers_out.getRawHeaders
+ self.assertEqual(['attachment;filename="admin.txt"'],
+ get('content-disposition'))
+ self.assertEqual(['text/plain;charset=ascii'],
+ get('content-type'))
+ self.assertEqual('Babar is not dead!', data)
def test_header_with_space(self):
- req = self.request()
- self.create_user(req, login=u'c c l a', password='babar')
- self.commit()
- with self.login(u'c c l a', password='babar'):
- req = self.request()
+ with self.admin_access.web_request() as req:
+ self.create_user(req, login=u'c c l a', password='babar')
+ req.cnx.commit()
+ with self.new_access(u'c c l a').web_request() as req:
req.form['vid'] = 'download'
req.form['eid'] = str(req.user.eid)
data = self.ctrl_publish(req,'view')
@@ -91,11 +90,10 @@
self.assertEqual('Babar is not dead!', data)
def test_header_with_space_and_comma(self):
- req = self.request()
- self.create_user(req, login=ur'c " l\ a', password='babar')
- self.commit()
- with self.login(ur'c " l\ a', password='babar'):
- req = self.request()
+ with self.admin_access.web_request() as req:
+ self.create_user(req, login=ur'c " l\ a', password='babar')
+ req.cnx.commit()
+ with self.new_access(ur'c " l\ a').web_request() as req:
req.form['vid'] = 'download'
req.form['eid'] = str(req.user.eid)
data = self.ctrl_publish(req,'view')
@@ -107,11 +105,10 @@
self.assertEqual('Babar is not dead!', data)
def test_header_unicode_filename(self):
- req = self.request()
- self.create_user(req, login=u'cécilia', password='babar')
- self.commit()
- with self.login(u'cécilia', password='babar'):
- req = self.request()
+ with self.admin_access.web_request() as req:
+ self.create_user(req, login=u'cécilia', password='babar')
+ req.cnx.commit()
+ with self.new_access(u'cécilia').web_request() as req:
req.form['vid'] = 'download'
req.form['eid'] = str(req.user.eid)
self.ctrl_publish(req,'view')
@@ -120,12 +117,11 @@
get('content-disposition'))
def test_header_unicode_long_filename(self):
- req = self.request()
name = u'Bèrte_hô_grand_nôm_ça_va_totallement_déborder_de_la_limite_là '
- self.create_user(req, login=name, password='babar')
- self.commit()
- with self.login(name, password='babar'):
- req = self.request()
+ with self.admin_access.web_request() as req:
+ self.create_user(req, login=name, password='babar')
+ req.cnx.commit()
+ with self.new_access(name).web_request() as req:
req.form['vid'] = 'download'
req.form['eid'] = str(req.user.eid)
self.ctrl_publish(req,'view')
@@ -137,20 +133,17 @@
def test_download_data_error(self):
self.vreg.register(BrokenIDownloadableGroup)
self.addCleanup(partial(self.vreg.unregister, BrokenIDownloadableGroup))
- req = self.request()
- req.form['vid'] = 'download'
- req.form['eid'] = str(req.execute('CWGroup X WHERE X name "managers"')[0][0])
- errhdlr = self.app.__dict__.pop('error_handler') # temporarily restore error handler
- try:
- data = self.app_handle_request(req)
- finally:
- self.app.error_handler = errhdlr
- get = req.headers_out.getRawHeaders
- self.assertEqual(['text/html;charset=UTF-8'],
- get('content-type'))
- self.assertEqual(None,
- get('content-disposition'))
- self.assertEqual(req.status_out, 500)
+ with self.admin_access.web_request() as req:
+ req.form['vid'] = 'download'
+ req.form['eid'] = str(req.execute('CWGroup X WHERE X name "managers"')[0][0])
+ with real_error_handling(self.app):
+ data = self.app_handle_request(req)
+ get = req.headers_out.getRawHeaders
+ self.assertEqual(['text/html;charset=UTF-8'],
+ get('content-type'))
+ self.assertEqual(None,
+ get('content-disposition'))
+ self.assertEqual(req.status_out, 500)
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_magicsearch.py
--- a/web/test/unittest_magicsearch.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_magicsearch.py Wed Sep 24 18:04:30 2014 +0200
@@ -19,6 +19,7 @@
"""Unit tests for cw.web.views.magicsearch"""
import sys
+from contextlib import contextmanager
from logilab.common.testlib import TestCase, unittest_main
@@ -50,110 +51,120 @@
class QueryTranslatorTC(CubicWebTC):
"""test suite for QueryTranslatorTC"""
- def setUp(self):
- super(QueryTranslatorTC, self).setUp()
- self.req = self.request()
- self.vreg.config.translations = {'en': (_translate, _ctxtranslate)}
- proc = self.vreg['components'].select('magicsearch', self.req)
- self.proc = [p for p in proc.processors if isinstance(p, QueryTranslator)][0]
+ @contextmanager
+ def proc(self):
+ with self.admin_access.web_request() as req:
+ self.vreg.config.translations = {'en': (_translate, _ctxtranslate)}
+ proc = self.vreg['components'].select('magicsearch', req)
+ proc = [p for p in proc.processors if isinstance(p, QueryTranslator)][0]
+ yield proc
def test_basic_translations(self):
"""tests basic translations (no ambiguities)"""
- rql = "Any C WHERE C is Adresse, P adel C, C adresse 'Logilab'"
- rql, = self.proc.preprocess_query(rql)
- self.assertEqual(rql, "Any C WHERE C is EmailAddress, P use_email C, C address 'Logilab'")
+ with self.proc() as proc:
+ rql = "Any C WHERE C is Adresse, P adel C, C adresse 'Logilab'"
+ rql, = proc.preprocess_query(rql)
+ self.assertEqual(rql, "Any C WHERE C is EmailAddress, P use_email C, C address 'Logilab'")
def test_ambiguous_translations(self):
"""tests possibly ambiguous translations"""
- rql = "Any P WHERE P adel C, C is EmailAddress, C nom 'Logilab'"
- rql, = self.proc.preprocess_query(rql)
- self.assertEqual(rql, "Any P WHERE P use_email C, C is EmailAddress, C alias 'Logilab'")
- rql = "Any P WHERE P is Utilisateur, P adel C, P nom 'Smith'"
- rql, = self.proc.preprocess_query(rql)
- self.assertEqual(rql, "Any P WHERE P is CWUser, P use_email C, P surname 'Smith'")
+ with self.proc() as proc:
+ rql = "Any P WHERE P adel C, C is EmailAddress, C nom 'Logilab'"
+ rql, = proc.preprocess_query(rql)
+ self.assertEqual(rql, "Any P WHERE P use_email C, C is EmailAddress, C alias 'Logilab'")
+ rql = "Any P WHERE P is Utilisateur, P adel C, P nom 'Smith'"
+ rql, = proc.preprocess_query(rql)
+ self.assertEqual(rql, "Any P WHERE P is CWUser, P use_email C, P surname 'Smith'")
class QSPreProcessorTC(CubicWebTC):
"""test suite for QSPreProcessor"""
- def setUp(self):
- super(QSPreProcessorTC, self).setUp()
+
+ @contextmanager
+ def proc(self):
self.vreg.config.translations = {'en': (_translate, _ctxtranslate)}
- self.req = self.request()
- proc = self.vreg['components'].select('magicsearch', self.req)
- self.proc = [p for p in proc.processors if isinstance(p, QSPreProcessor)][0]
- self.proc._cw = self.req
+ with self.admin_access.web_request() as req:
+ proc = self.vreg['components'].select('magicsearch', req)
+ proc = [p for p in proc.processors if isinstance(p, QSPreProcessor)][0]
+ proc._cw = req
+ yield proc
def test_entity_translation(self):
"""tests QSPreProcessor._get_entity_name()"""
- translate = self.proc._get_entity_type
- self.assertEqual(translate(u'EmailAddress'), "EmailAddress")
- self.assertEqual(translate(u'emailaddress'), "EmailAddress")
- self.assertEqual(translate(u'Adresse'), "EmailAddress")
- self.assertEqual(translate(u'adresse'), "EmailAddress")
- self.assertRaises(BadRQLQuery, translate, 'whatever')
+ with self.proc() as proc:
+ translate = proc._get_entity_type
+ self.assertEqual(translate(u'EmailAddress'), "EmailAddress")
+ self.assertEqual(translate(u'emailaddress'), "EmailAddress")
+ self.assertEqual(translate(u'Adresse'), "EmailAddress")
+ self.assertEqual(translate(u'adresse'), "EmailAddress")
+ self.assertRaises(BadRQLQuery, translate, 'whatever')
def test_attribute_translation(self):
"""tests QSPreProcessor._get_attribute_name"""
- translate = self.proc._get_attribute_name
- eschema = self.schema.eschema('CWUser')
- self.assertEqual(translate(u'prénom', eschema), "firstname")
- self.assertEqual(translate(u'nom', eschema), 'surname')
- eschema = self.schema.eschema('EmailAddress')
- self.assertEqual(translate(u'adresse', eschema), "address")
- self.assertEqual(translate(u'nom', eschema), 'alias')
- # should fail if the name is not an attribute for the given entity schema
- self.assertRaises(BadRQLQuery, translate, 'whatever', eschema)
- self.assertRaises(BadRQLQuery, translate, 'prénom', eschema)
+ with self.proc() as proc:
+ translate = proc._get_attribute_name
+ eschema = self.schema.eschema('CWUser')
+ self.assertEqual(translate(u'prénom', eschema), "firstname")
+ self.assertEqual(translate(u'nom', eschema), 'surname')
+ eschema = self.schema.eschema('EmailAddress')
+ self.assertEqual(translate(u'adresse', eschema), "address")
+ self.assertEqual(translate(u'nom', eschema), 'alias')
+ # should fail if the name is not an attribute for the given entity schema
+ self.assertRaises(BadRQLQuery, translate, 'whatever', eschema)
+ self.assertRaises(BadRQLQuery, translate, 'prénom', eschema)
def test_one_word_query(self):
"""tests the 'one word shortcut queries'"""
- transform = self.proc._one_word_query
- self.assertEqual(transform('123'),
- ('Any X WHERE X eid %(x)s', {'x': 123}, 'x'))
- self.assertEqual(transform('CWUser'),
- ('CWUser C',))
- self.assertEqual(transform('Utilisateur'),
- ('CWUser C',))
- self.assertEqual(transform('Adresse'),
- ('EmailAddress E',))
- self.assertEqual(transform('adresse'),
- ('EmailAddress E',))
- self.assertRaises(BadRQLQuery, transform, 'Workcases')
+ with self.proc() as proc:
+ transform = proc._one_word_query
+ self.assertEqual(transform('123'),
+ ('Any X WHERE X eid %(x)s', {'x': 123}, 'x'))
+ self.assertEqual(transform('CWUser'),
+ ('CWUser C',))
+ self.assertEqual(transform('Utilisateur'),
+ ('CWUser C',))
+ self.assertEqual(transform('Adresse'),
+ ('EmailAddress E',))
+ self.assertEqual(transform('adresse'),
+ ('EmailAddress E',))
+ self.assertRaises(BadRQLQuery, transform, 'Workcases')
def test_two_words_query(self):
"""tests the 'two words shortcut queries'"""
- transform = self.proc._two_words_query
- self.assertEqual(transform('CWUser', 'E'),
- ("CWUser E",))
- self.assertEqual(transform('CWUser', 'Smith'),
- ('CWUser C ORDERBY FTIRANK(C) DESC WHERE C has_text %(text)s', {'text': 'Smith'}))
- self.assertEqual(transform('utilisateur', 'Smith'),
- ('CWUser C ORDERBY FTIRANK(C) DESC WHERE C has_text %(text)s', {'text': 'Smith'}))
- self.assertEqual(transform(u'adresse', 'Logilab'),
- ('EmailAddress E ORDERBY FTIRANK(E) DESC WHERE E has_text %(text)s', {'text': 'Logilab'}))
- self.assertEqual(transform(u'adresse', 'Logi%'),
- ('EmailAddress E WHERE E alias LIKE %(text)s', {'text': 'Logi%'}))
- self.assertRaises(BadRQLQuery, transform, "pers", "taratata")
+ with self.proc() as proc:
+ transform = proc._two_words_query
+ self.assertEqual(transform('CWUser', 'E'),
+ ("CWUser E",))
+ self.assertEqual(transform('CWUser', 'Smith'),
+ ('CWUser C ORDERBY FTIRANK(C) DESC WHERE C has_text %(text)s', {'text': 'Smith'}))
+ self.assertEqual(transform('utilisateur', 'Smith'),
+ ('CWUser C ORDERBY FTIRANK(C) DESC WHERE C has_text %(text)s', {'text': 'Smith'}))
+ self.assertEqual(transform(u'adresse', 'Logilab'),
+ ('EmailAddress E ORDERBY FTIRANK(E) DESC WHERE E has_text %(text)s', {'text': 'Logilab'}))
+ self.assertEqual(transform(u'adresse', 'Logi%'),
+ ('EmailAddress E WHERE E alias LIKE %(text)s', {'text': 'Logi%'}))
+ self.assertRaises(BadRQLQuery, transform, "pers", "taratata")
def test_three_words_query(self):
"""tests the 'three words shortcut queries'"""
- transform = self.proc._three_words_query
- self.assertEqual(transform('utilisateur', u'prénom', 'cubicweb'),
- ('CWUser C WHERE C firstname %(text)s', {'text': 'cubicweb'}))
- self.assertEqual(transform('utilisateur', 'nom', 'cubicweb'),
- ('CWUser C WHERE C surname %(text)s', {'text': 'cubicweb'}))
- self.assertEqual(transform(u'adresse', 'nom', 'cubicweb'),
- ('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'}))
- self.assertEqual(transform('EmailAddress', 'nom', 'cubicweb'),
- ('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'}))
- self.assertEqual(transform('utilisateur', u'prénom', 'cubicweb%'),
- ('CWUser C WHERE C firstname LIKE %(text)s', {'text': 'cubicweb%'}))
- # expanded shortcuts
- self.assertEqual(transform('CWUser', 'use_email', 'Logilab'),
- ('CWUser C ORDERBY FTIRANK(C1) DESC WHERE C use_email C1, C1 has_text %(text)s', {'text': 'Logilab'}))
- self.assertEqual(transform('CWUser', 'use_email', '%Logilab'),
- ('CWUser C WHERE C use_email C1, C1 alias LIKE %(text)s', {'text': '%Logilab'}))
- self.assertRaises(BadRQLQuery, transform, 'word1', 'word2', 'word3')
+ with self.proc() as proc:
+ transform = proc._three_words_query
+ self.assertEqual(transform('utilisateur', u'prénom', 'cubicweb'),
+ ('CWUser C WHERE C firstname %(text)s', {'text': 'cubicweb'}))
+ self.assertEqual(transform('utilisateur', 'nom', 'cubicweb'),
+ ('CWUser C WHERE C surname %(text)s', {'text': 'cubicweb'}))
+ self.assertEqual(transform(u'adresse', 'nom', 'cubicweb'),
+ ('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'}))
+ self.assertEqual(transform('EmailAddress', 'nom', 'cubicweb'),
+ ('EmailAddress E WHERE E alias %(text)s', {'text': 'cubicweb'}))
+ self.assertEqual(transform('utilisateur', u'prénom', 'cubicweb%'),
+ ('CWUser C WHERE C firstname LIKE %(text)s', {'text': 'cubicweb%'}))
+ # expanded shortcuts
+ self.assertEqual(transform('CWUser', 'use_email', 'Logilab'),
+ ('CWUser C ORDERBY FTIRANK(C1) DESC WHERE C use_email C1, C1 has_text %(text)s', {'text': 'Logilab'}))
+ self.assertEqual(transform('CWUser', 'use_email', '%Logilab'),
+ ('CWUser C WHERE C use_email C1, C1 alias LIKE %(text)s', {'text': '%Logilab'}))
+ self.assertRaises(BadRQLQuery, transform, 'word1', 'word2', 'word3')
def test_quoted_queries(self):
"""tests how quoted queries are handled"""
@@ -163,12 +174,13 @@
(u'Utilisateur firstname "Jean Paul"', ('CWUser C WHERE C firstname %(text)s', {'text': 'Jean Paul'})),
(u'CWUser firstname "Jean Paul"', ('CWUser C WHERE C firstname %(text)s', {'text': 'Jean Paul'})),
]
- transform = self.proc._quoted_words_query
- for query, expected in queries:
- self.assertEqual(transform(query), expected)
- self.assertRaises(BadRQLQuery, transform, "unquoted rql")
- self.assertRaises(BadRQLQuery, transform, 'pers "Jean Paul"')
- self.assertRaises(BadRQLQuery, transform, 'CWUser firstname other "Jean Paul"')
+ with self.proc() as proc:
+ transform = proc._quoted_words_query
+ for query, expected in queries:
+ self.assertEqual(transform(query), expected)
+ self.assertRaises(BadRQLQuery, transform, "unquoted rql")
+ self.assertRaises(BadRQLQuery, transform, 'pers "Jean Paul"')
+ self.assertRaises(BadRQLQuery, transform, 'CWUser firstname other "Jean Paul"')
def test_process_query(self):
"""tests how queries are processed"""
@@ -178,24 +190,25 @@
(u'Utilisateur cubicweb', (u'CWUser C ORDERBY FTIRANK(C) DESC WHERE C has_text %(text)s', {'text': u'cubicweb'})),
(u'CWUser prénom cubicweb', (u'CWUser C WHERE C firstname %(text)s', {'text': 'cubicweb'},)),
]
- for query, expected in queries:
- self.assertEqual(self.proc.preprocess_query(query), expected)
- self.assertRaises(BadRQLQuery,
- self.proc.preprocess_query, 'Any X WHERE X is Something')
+ with self.proc() as proc:
+ for query, expected in queries:
+ self.assertEqual(proc.preprocess_query(query), expected)
+ self.assertRaises(BadRQLQuery,
+ proc.preprocess_query, 'Any X WHERE X is Something')
## Processor Chains tests ############################################
-
class ProcessorChainTC(CubicWebTC):
"""test suite for magic_search's processor chains"""
- def setUp(self):
- super(ProcessorChainTC, self).setUp()
+ @contextmanager
+ def proc(self):
self.vreg.config.translations = {'en': (_translate, _ctxtranslate)}
- self.req = self.request()
- self.proc = self.vreg['components'].select('magicsearch', self.req)
+ with self.admin_access.web_request() as req:
+ proc = self.vreg['components'].select('magicsearch', req)
+ yield proc
def test_main_preprocessor_chain(self):
"""tests QUERY_PROCESSOR"""
@@ -211,31 +224,34 @@
(u'Any P WHERE P is Utilisateur, P nom "Smith"',
('Any P WHERE P is CWUser, P surname "Smith"', None)),
]
- for query, expected in queries:
- rset = self.proc.process_query(query)
- self.assertEqual((rset.rql, rset.args), expected)
+ with self.proc() as proc:
+ for query, expected in queries:
+ rset = proc.process_query(query)
+ self.assertEqual((rset.rql, rset.args), expected)
def test_accentuated_fulltext(self):
"""we must be able to type accentuated characters in the search field"""
- rset = self.proc.process_query(u'écrire')
- self.assertEqual(rset.rql, "Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s")
- self.assertEqual(rset.args, {'text': u'écrire'})
+ with self.proc() as proc:
+ rset = proc.process_query(u'écrire')
+ self.assertEqual(rset.rql, "Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s")
+ self.assertEqual(rset.args, {'text': u'écrire'})
def test_explicit_component(self):
- self.assertRaises(RQLSyntaxError,
- self.proc.process_query, u'rql: CWUser E WHERE E noattr "Smith",')
- self.assertRaises(BadRQLQuery,
- self.proc.process_query, u'rql: CWUser E WHERE E noattr "Smith"')
- rset = self.proc.process_query(u'text: utilisateur Smith')
- self.assertEqual(rset.rql, 'Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s')
- self.assertEqual(rset.args, {'text': u'utilisateur Smith'})
+ with self.proc() as proc:
+ self.assertRaises(RQLSyntaxError,
+ proc.process_query, u'rql: CWUser E WHERE E noattr "Smith",')
+ self.assertRaises(BadRQLQuery,
+ proc.process_query, u'rql: CWUser E WHERE E noattr "Smith"')
+ rset = proc.process_query(u'text: utilisateur Smith')
+ self.assertEqual(rset.rql, 'Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s')
+ self.assertEqual(rset.args, {'text': u'utilisateur Smith'})
class RQLSuggestionsBuilderTC(CubicWebTC):
def suggestions(self, rql):
- req = self.request()
- rbs = self.vreg['components'].select('rql.suggestions', req)
- return rbs.build_suggestions(rql)
+ with self.admin_access.web_request() as req:
+ rbs = self.vreg['components'].select('rql.suggestions', req)
+ return rbs.build_suggestions(rql)
def test_no_restrictions_rql(self):
self.assertListEqual([], self.suggestions(''))
@@ -313,9 +329,10 @@
def test_attribute_value_rql(self):
# suggestions should contain any possible value for
# a given attribute (limited to 10)
- req = self.request()
- for i in xrange(15):
- req.create_entity('Personne', nom=u'n%s' % i, prenom=u'p%s' % i)
+ with self.admin_access.web_request() as req:
+ for i in xrange(15):
+ req.create_entity('Personne', nom=u'n%s' % i, prenom=u'p%s' % i)
+ req.cnx.commit()
self.assertListEqual(['Any X WHERE X is Personne, X nom "n0"',
'Any X WHERE X is Personne, X nom "n1"',
'Any X WHERE X is Personne, X nom "n10"',
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_propertysheet.py
--- a/web/test/unittest_propertysheet.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_propertysheet.py Wed Sep 24 18:04:30 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')
@@ -35,19 +35,19 @@
'a {bgcolor: #FFFFFF; size: 1%;}')
self.assertEqual(ps.process_resource(DATADIR, 'pouet.css'),
CACHEDIR)
- self.assertTrue('pouet.css' in ps._cache)
+ self.assertIn('pouet.css', ps._cache)
self.assertFalse(ps.need_reload())
os.utime(join(DATADIR, 'sheet1.py'), None)
- self.assertTrue('pouet.css' in ps._cache)
+ self.assertIn('pouet.css', ps._cache)
self.assertTrue(ps.need_reload())
- self.assertTrue('pouet.css' in ps._cache)
+ self.assertIn('pouet.css', ps._cache)
ps.reload()
- self.assertFalse('pouet.css' in ps._cache)
+ self.assertNotIn('pouet.css', ps._cache)
self.assertFalse(ps.need_reload())
ps.process_resource(DATADIR, 'pouet.css') # put in cache
os.utime(join(DATADIR, 'pouet.css'), None)
self.assertFalse(ps.need_reload())
- self.assertFalse('pouet.css' in ps._cache)
+ self.assertNotIn('pouet.css', ps._cache)
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_reledit.py
--- a/web/test/unittest_reledit.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_reledit.py Wed Sep 24 18:04:30 2014 +0200
@@ -25,10 +25,11 @@
class ReleditMixinTC(object):
def setup_database(self):
- self.req = self.request()
- self.proj = self.req.create_entity('Project', title=u'cubicweb-world-domination')
- self.tick = self.req.create_entity('Ticket', title=u'write the code')
- self.toto = self.req.create_entity('Personne', nom=u'Toto')
+ with self.admin_access.client_cnx() as cnx:
+ self.proj = cnx.create_entity('Project', title=u'cubicweb-world-domination').eid
+ self.tick = cnx.create_entity('Ticket', title=u'write the code').eid
+ self.toto = cnx.create_entity('Personne', nom=u'Toto').eid
+ cnx.commit()
class ClickAndEditFormTC(ReleditMixinTC, CubicWebTC):
@@ -39,13 +40,16 @@
'composite_card11_2ttypes': """<not specified>""",
'concerns': """<not specified>"""}
- for rschema, ttypes, role in self.proj.e_schema.relation_definitions(includefinal=True):
- if rschema not in reledit:
- continue
- rtype = rschema.type
- self.assertMultiLineEqual(reledit[rtype] % {'eid': self.proj.eid},
- self.proj.view('reledit', rtype=rtype, role=role),
- rtype)
+ with self.admin_access.web_request() as req:
+ proj = req.entity_from_eid(self.proj)
+
+ for rschema, ttypes, role in proj.e_schema.relation_definitions(includefinal=True):
+ if rschema not in reledit:
+ continue
+ rtype = rschema.type
+ self.assertMultiLineEqual(reledit[rtype] % {'eid': self.proj},
+ proj.view('reledit', rtype=rtype, role=role),
+ rtype)
def test_default_forms(self):
self.skipTest('Need to check if this test should still run post reledit/doreledit merge')
@@ -175,8 +179,10 @@
def setup_database(self):
super(ClickAndEditFormUICFGTC, self).setup_database()
- self.tick.cw_set(concerns=self.proj)
- self.proj.cw_set(manager=self.toto)
+ with self.admin_access.client_cnx() as cnx:
+ cnx.execute('SET T concerns P WHERE T eid %(t)s, P eid %(p)s', {'t': self.tick, 'p': self.proj})
+ cnx.execute('SET P manager T WHERE P eid %(p)s, T eid %(t)s', {'p': self.proj, 't': self.toto})
+ cnx.commit()
def test_with_uicfg(self):
old_rctl = reledit_ctrl._tagdefs.copy()
@@ -198,13 +204,15 @@
'composite_card11_2ttypes': """<not specified>""",
'concerns': """
"""
}
- for rschema, ttypes, role in self.proj.e_schema.relation_definitions(includefinal=True):
- if rschema not in reledit:
- continue
- rtype = rschema.type
- self.assertMultiLineEqual(reledit[rtype] % {'eid': self.proj.eid, 'toto': self.toto.eid, 'tick': self.tick.eid},
- self.proj.view('reledit', rtype=rtype, role=role),
- rtype)
+ with self.admin_access.web_request() as req:
+ proj = req.entity_from_eid(self.proj)
+ for rschema, ttypes, role in proj.e_schema.relation_definitions(includefinal=True):
+ if rschema not in reledit:
+ continue
+ rtype = rschema.type
+ self.assertMultiLineEqual(reledit[rtype] % {'eid': self.proj, 'toto': self.toto, 'tick': self.tick},
+ proj.view('reledit', rtype=rtype, role=role),
+ rtype)
reledit_ctrl.clear()
reledit_ctrl._tagdefs.update(old_rctl)
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_session.py
--- a/web/test/unittest_session.py Wed Sep 24 17:35:59 2014 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-"""unit tests for cubicweb.web.application
-
-:organization: Logilab
-:copyright: 2001-2011 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
-"""
-from cubicweb.devtools.testlib import CubicWebTC
-from cubicweb.web import InvalidSession
-
-class SessionTC(CubicWebTC):
-
- def test_session_expiration(self):
- sm = self.app.session_handler.session_manager
- # make is if the web session has been opened by the session manager
- sm._sessions[self.cnx.sessionid] = self.websession
- sessionid = self.websession.sessionid
- self.assertEqual(len(sm._sessions), 1)
- self.assertEqual(self.websession.sessionid, self.websession.cnx.sessionid)
- # fake the repo session is expiring
- self.repo.close(sessionid)
- try:
- # fake an incoming http query with sessionid in session cookie
- # don't use self.request() which try to call req.set_session
- req = self.requestcls(self.vreg)
- self.assertRaises(InvalidSession, sm.get_session, req, sessionid)
- self.assertEqual(len(sm._sessions), 0)
- finally:
- # avoid error in tearDown by telling this connection is closed...
- self.cnx._closed = True
-
-if __name__ == '__main__':
- from logilab.common.testlib import unittest_main
- unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_urlpublisher.py
--- a/web/test/unittest_urlpublisher.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_urlpublisher.py Wed Sep 24 18:04:30 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__':
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_urlrewrite.py
--- a/web/test/unittest_urlrewrite.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_urlrewrite.py Wed Sep 24 18:04:30 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
\w+)/(?P\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\w+)/(?P\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__':
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_actions.py
--- a/web/test/unittest_views_actions.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_actions.py Wed Sep 24 18:04:30 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,21 +23,19 @@
class ActionsTC(CubicWebTC):
def test_view_action(self):
- req = self.request(vid='rss', rql='CWUser X')
- rset = self.execute('CWUser X')
- actions = self.vreg['actions'].poss_visible_objects(req, rset=rset)
- vaction = [action for action in actions if action.__regid__ == 'view'][0]
- self.assertEqual(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X')
+ with self.admin_access.web_request(vid='rss', rql='CWUser X') as req:
+ rset = req.execute('CWUser X')
+ actions = self.vreg['actions'].poss_visible_objects(req, rset=rset)
+ vaction = [action for action in actions if action.__regid__ == 'view'][0]
+ self.assertEqual(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X')
def test_has_editable_relations(self):
"""ensure has_editable_relation predicate used by ModifyAction
return positive score if there is only some inlined forms
"""
use_email = self.schema['use_email'].rdefs['CWUser', 'EmailAddress']
- with self.temporary_permissions((use_email, {'add': ('guests',)}),
- ):
- with self.login('anon'):
- req = self.request()
+ with self.temporary_permissions((use_email, {'add': ('guests',)})):
+ with self.new_access('anon').web_request() as req:
predicate = actions.has_editable_relation()
self.assertEqual(predicate(None, req, rset=req.user.as_rset()),
1)
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_basecontrollers.py
--- a/web/test/unittest_views_basecontrollers.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_basecontrollers.py Wed Sep 24 18:04:30 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 Transaction as OldTransaction
-from cubicweb.entities.authobjs import CWUser
+from cubicweb.server.session import Connection as OldConnection
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,631 +40,166 @@
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.assertTrue('users' in self.schema.eschema('CWGroup').get_groups('read'))
+ self.assertIn('users', self.schema.eschema('CWGroup').get_groups('read'))
def tearDown(self):
CubicWebTC.tearDown(self)
- self.assertTrue('users' in self.schema.eschema('CWGroup').get_groups('read'))
+ self.assertIn('users', self.schema.eschema('CWGroup').get_groups('read'))
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.assertFalse('vid' in 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(''''''%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('''''', 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('''''', self.ctrl_publish(req, 'validateform'))
-
- self.assertEqual('''''', 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(''''''%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('''''', 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('''''', self.ctrl_publish(req, 'validateform'))
+
+ self.assertMultiLineEqual('''''', 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(''))
+ 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('
'))
# 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,122 +896,129 @@
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'
hello
', res)
+ with self.remote_calling('foo') as (res, _):
+ self.assertEqual(u'
hello
', 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):
def setUp(self):
- class Transaction(OldTransaction):
+ class Connection(OldConnection):
"""Force undo feature to be turned on in all case"""
undo_actions = property(lambda tx: True, lambda x, y:None)
- cubicweb.server.session.Transaction = Transaction
+ cubicweb.server.session.Connection = Connection
super(UndoControllerTC, self).setUp()
def tearDown(self):
super(UndoControllerTC, self).tearDown()
- cubicweb.server.session.Transaction = OldTransaction
-
+ 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()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_basetemplates.py
--- a/web/test/unittest_views_basetemplates.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_basetemplates.py Wed Sep 24 18:04:30 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.
@@ -24,10 +24,8 @@
def _login_labels(self):
valid = self.content_type_validators.get('text/html', XMLValidator)()
- req = self.request()
- req.cnx.anonymous_connection = True
- page = valid.parse_string(self.vreg['views'].main_template(self.request(), 'login'))
- req.cnx.anonymous_connection = False
+ req = self.requestcls(self.vreg, url='login')
+ page = valid.parse_string(self.vreg['views'].main_template(req, 'login'))
return page.find_tag('label')
def test_label(self):
@@ -40,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__':
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_baseviews.py
--- a/web/test/unittest_views_baseviews.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_baseviews.py Wed Sep 24 18:04:30 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'
', 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'', 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'', u'loo"ong blabla', e.creation_date])
class HTMLStreamTests(CubicWebTC):
@@ -129,11 +123,15 @@
def call(self):
self._cw.set_doctype('')
- 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(['', ''], 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(['',
+ ''],
+ 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, '', ''],
- 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,
+ '',
+ ''],
+ source_lines[:3])
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_csv.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/unittest_views_csv.py Wed Sep 24 18:04:30 2014 +0200
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# copyright 2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb. If not, see .
+
+from cubicweb.devtools.testlib import CubicWebTC
+
+
+class CSVExportViewsTC(CubicWebTC):
+
+ def test_csvexport(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('csvexport', rset, req=req)
+ self.assertEqual(req.headers_out.getRawHeaders('content-type'),
+ ['text/comma-separated-values;charset=UTF-8'])
+ expected_data = "String;COUNT(CWUser)\nguests;1\nmanagers;1"
+ self.assertMultiLineEqual(expected_data, data)
+
+ def test_csvexport_on_empty_rset(self):
+ """Should return the CSV header.
+ """
+ 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, X login "Miles"')
+ data = self.view('csvexport', rset, req=req)
+ self.assertEqual(req.headers_out.getRawHeaders('content-type'),
+ ['text/comma-separated-values;charset=UTF-8'])
+ expected_data = "String;COUNT(CWUser)"
+ self.assertMultiLineEqual(expected_data, data)
+
+
+if __name__ == '__main__':
+ from logilab.common.testlib import unittest_main
+ unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_editforms.py
--- a/web/test/unittest_views_editforms.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_editforms.py Wed Sep 24 18:04:30 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 .
-"""
-
-"""
from logilab.common.testlib import unittest_main, mock_object
from cubicweb.devtools.testlib import CubicWebTC
@@ -32,154 +29,191 @@
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))
+
+ def test_attribute_add_permissions(self):
+ # https://www.cubicweb.org/ticket/4342844
+ with self.admin_access.repo_cnx() as cnx:
+ self.create_user(cnx, 'toto')
+ cnx.commit()
+ with self.new_access('toto').web_request() as req:
+ e = self.vreg['etypes'].etype_class('Personne')(req)
+ cform = self.vreg['forms'].select('edition', req, entity=e)
+ self.assertIn('sexe',
+ [rschema.type
+ for rschema, _ in cform.editable_attributes()])
+ with self.new_access('toto').repo_cnx() as cnx:
+ person_eid = cnx.create_entity('Personne', nom=u'Robert').eid
+ cnx.commit()
+ person = req.entity_from_eid(person_eid)
+ mform = self.vreg['forms'].select('edition', req, entity=person)
+ self.assertNotIn('sexe',
+ [rschema.type
+ for rschema, _ in mform.editable_attributes()])
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)
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_errorform.py
--- a/web/test/unittest_views_errorform.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_errorform.py Wed Sep 24 18:04:30 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.
@@ -15,25 +15,20 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see .
+import re
+import sys
from logilab.common.testlib import unittest_main
-from logilab.mtconverter import html_unescape
-from cubicweb import Forbidden, ValidationError
+from cubicweb import Forbidden
from cubicweb.devtools.testlib import CubicWebTC
-from cubicweb.utils import json
-from cubicweb.view import StartupView, TRANSITIONAL_DOCTYPE_NOEXT
+from cubicweb.view import StartupView
from cubicweb.web import Redirect
-from cubicweb.web.htmlwidgets import TableWidget
-from cubicweb.web.views import vid_from_rset
-import re
-import hmac
class ErrorViewTC(CubicWebTC):
def setUp(self):
super(ErrorViewTC, self).setUp()
- self.req = self.request()
self.vreg.config['submit-mail'] = "test@logilab.fr"
self.vreg.config['print-traceback'] = "yes"
@@ -48,15 +43,16 @@
raise ValueError('This is wrong')
with self.temporary_appobjects(MyWrongView):
- try:
- self.view('my-view')
- except Exception as e:
- import sys
- self.req.data['excinfo'] = sys.exc_info()
- self.req.data['ex'] = e
- html = self.view('error', req=self.req)
- self.failUnless(re.search(r'^ $',
- html.source, re.M))
+ with self.admin_access.web_request() as req:
+ try:
+ self.view('my-view', req=req)
+ except Exception as e:
+ req.data['excinfo'] = sys.exc_info()
+ req.data['ex'] = e
+ html = self.view('error', req=req)
+ self.failUnless(re.search(r'^ $',
+ html.source, re.M))
def test_error_submit_nosig(self):
@@ -64,36 +60,33 @@
tests that the reportbug controller refuses submission if
there is not content signature
"""
-
- self.req.form = {'description': u'toto',
- }
- with self.assertRaises(Forbidden) as cm:
- self.ctrl_publish(self.req, 'reportbug')
+ with self.admin_access.web_request() as req:
+ req.form = {'description': u'toto'}
+ with self.assertRaises(Forbidden) as cm:
+ self.ctrl_publish(req, 'reportbug')
def test_error_submit_wrongsig(self):
"""
tests that the reportbug controller refuses submission if the
content signature is invalid
"""
-
- self.req.form = {'__signature': 'X',
- 'description': u'toto',
- }
- with self.assertRaises(Forbidden) as cm:
- self.ctrl_publish(self.req, 'reportbug')
+ with self.admin_access.web_request() as req:
+ req.form = {'__signature': 'X',
+ 'description': u'toto'}
+ with self.assertRaises(Forbidden) as cm:
+ self.ctrl_publish(req, 'reportbug')
def test_error_submit_ok(self):
"""
tests that the reportbug controller accept the email submission if the
content signature is valid
"""
-
- sign = self.vreg.config.sign_text('toto')
- self.req.form = {'__signature': sign,
- 'description': u'toto',
- }
- with self.assertRaises(Redirect) as cm:
- self.ctrl_publish(self.req, 'reportbug')
+ with self.admin_access.web_request() as req:
+ sign = self.vreg.config.sign_text('toto')
+ req.form = {'__signature': sign,
+ 'description': u'toto'}
+ with self.assertRaises(Redirect) as cm:
+ self.ctrl_publish(req, 'reportbug')
if __name__ == '__main__':
unittest_main()
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_json.py
--- a/web/test/unittest_views_json.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_json.py Wed Sep 24 18:04:30 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# copyright 2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 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,9 +18,6 @@
# with CubicWeb. If not, see .
from cubicweb.devtools.testlib import CubicWebTC
-from cubicweb.utils import json
-
-from cubicweb.web.application import anonymized_request
class JsonViewsTC(CubicWebTC):
anonymize = True
@@ -31,47 +28,47 @@
self.config.global_set_option('anonymize-jsonp-queries', self.anonymize)
def test_json_rsetexport(self):
- req = self.request()
- rset = req.execute('Any GN,COUNT(X) GROUPBY GN ORDERBY GN WHERE X in_group G, G name GN')
- data = self.view('jsonexport', rset)
- self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
- self.assertListEqual(data, [["guests", 1], ["managers", 1]])
+ 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, 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):
- req = self.request()
- rset = req.execute('Any X WHERE X is CWUser, X login "foobarbaz"')
- data = self.view('jsonexport', rset)
- self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
- self.assertListEqual(data, [])
+ 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, req=req)
+ self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
+ self.assertListEqual(data, [])
def test_json_rsetexport_with_jsonp(self):
- req = self.request()
- req.form.update({'callback': 'foo',
- 'rql': 'Any GN,COUNT(X) GROUPBY GN ORDERBY GN WHERE X in_group G, G name GN',
- })
- data = self.ctrl_publish(req, ctrl='jsonp')
- self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript'])
- # because jsonp anonymizes data, only 'guests' group should be found
- self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data)
+ with self.admin_access.web_request() as req:
+ req.form.update({'callback': 'foo',
+ 'rql': 'Any GN,COUNT(X) GROUPBY GN ORDERBY GN '
+ 'WHERE X in_group G, G name GN'})
+ data = self.ctrl_publish(req, ctrl='jsonp')
+ self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript'])
+ # because jsonp anonymizes data, only 'guests' group should be found
+ self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data)
def test_json_rsetexport_with_jsonp_and_bad_vid(self):
- req = self.request()
- req.form.update({'callback': 'foo',
- 'vid': 'table', # <-- this parameter should be ignored by jsonp controller
- 'rql': 'Any GN,COUNT(X) GROUPBY GN ORDERBY GN WHERE X in_group G, G name GN',
- })
- data = self.ctrl_publish(req, ctrl='jsonp')
- self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript'])
- # result should be plain json, not the table view
- self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data)
+ with self.admin_access.web_request() as req:
+ req.form.update({'callback': 'foo',
+ 'vid': 'table', # <-- this parameter should be ignored by jsonp controller
+ 'rql': 'Any GN,COUNT(X) GROUPBY GN ORDERBY GN '
+ 'WHERE X in_group G, G name GN'})
+ data = self.ctrl_publish(req, ctrl='jsonp')
+ self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/javascript'])
+ # result should be plain json, not the table view
+ self.assertEqual(data, 'foo(%s)' % self.res_jsonp_data)
def test_json_ersetexport(self):
- req = self.request()
- rset = req.execute('Any G ORDERBY GN WHERE G is CWGroup, G name GN')
- data = self.view('ejsonexport', rset)
- self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
- self.assertEqual(data[0]['name'], 'guests')
- self.assertEqual(data[1]['name'], 'managers')
+ 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, req=req)
+ self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
+ self.assertEqual(data[0]['name'], 'guests')
+ self.assertEqual(data[1]['name'], 'managers')
class NotAnonymousJsonViewsTC(JsonViewsTC):
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_navigation.py
--- a/web/test/unittest_views_navigation.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_navigation.py Wed Sep 24 18:04:30 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 .
"""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.assertTrue('breadcrumbs' in 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.assertFalse('breadcrumbs' in 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.assertTrue('breadcrumbs' in clsids)
- # objs = self.vreg['ctxcomponents'].poss_visible_objects(
- # req, rset=rset, view=view, context='navtop')
-
- # clsids = [obj.id for obj in objs]
- # self.assertFalse('breadcrumbs' in clsids)
if __name__ == '__main__':
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_pyviews.py
--- a/web/test/unittest_views_pyviews.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_pyviews.py Wed Sep 24 18:04:30 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.
@@ -21,20 +21,22 @@
class PyViewsTC(CubicWebTC):
def test_pyvaltable(self):
- view = self.vreg['views'].select('pyvaltable', self.request(),
- pyvalue=[[1, 'a'], [2, 'b']])
- content = view.render(pyvalue=[[1, 'a'], [2, 'b']],
- headers=['num', 'char'])
- self.assertEqual(content.strip(), '''\
+ with self.admin_access.web_request() as req:
+ view = self.vreg['views'].select('pyvaltable', req,
+ pyvalue=[[1, 'a'], [2, 'b']])
+ content = view.render(pyvalue=[[1, 'a'], [2, 'b']],
+ headers=['num', 'char'])
+ self.assertEqual(content.strip(), '''''')
def test_pyvallist(self):
- view = self.vreg['views'].select('pyvallist', self.request(),
- pyvalue=[1, 'a'])
- content = view.render(pyvalue=[1, 'a'])
- self.assertEqual(content.strip(), '''
+ with self.admin_access.web_request() as req:
+ view = self.vreg['views'].select('pyvallist', req,
+ pyvalue=[1, 'a'])
+ content = view.render(pyvalue=[1, 'a'])
+ self.assertEqual(content.strip(), '''''')
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_staticcontrollers.py
--- a/web/test/unittest_views_staticcontrollers.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_staticcontrollers.py Wed Sep 24 18:04:30 2014 +0200
@@ -1,5 +1,25 @@
+# -*- coding: utf-8 -*-
+# 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.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb. If not, see .
+from contextlib import contextmanager
+
from logilab.common import tempattr
-from logilab.common.testlib import tag, Tags
+from logilab.common.testlib import Tags
from cubicweb.devtools.testlib import CubicWebTC
import os
@@ -9,50 +29,46 @@
from cubicweb.utils import HTMLHead
from cubicweb.web.views.staticcontrollers import ConcatFilesHandler
-class StaticControllerCacheTC(CubicWebTC):
+class staticfilespublishermixin(object):
+ @contextmanager
+ def _publish_static_files(self, url, header={}):
+ with self.admin_access.web_request(headers=header) as req:
+ req._url = url
+ self.app_handle_request(req, url)
+ yield req
+
+class StaticControllerCacheTC(staticfilespublishermixin, CubicWebTC):
tags = CubicWebTC.tags | Tags('static_controller', 'cache', 'http')
-
- def _publish_static_files(self, url, header={}):
- req = self.request(headers=header)
- req._url = url
- return self.app_handle_request(req, url), req
-
def test_static_file_are_cached(self):
- _, req = self._publish_static_files('data/cubicweb.css')
- self.assertEqual(200, req.status_out)
- self.assertIn('last-modified', req.headers_out)
+ with self._publish_static_files('data/cubicweb.css') as req:
+ self.assertEqual(200, req.status_out)
+ self.assertIn('last-modified', req.headers_out)
next_headers = {
'if-modified-since': req.get_response_header('last-modified', raw=True),
}
- _, req = self._publish_static_files('data/cubicweb.css', next_headers)
- self.assertEqual(304, req.status_out)
+ with self._publish_static_files('data/cubicweb.css', next_headers) as req:
+ self.assertEqual(304, req.status_out)
-class DataControllerTC(CubicWebTC):
-
+class DataControllerTC(staticfilespublishermixin, CubicWebTC):
tags = CubicWebTC.tags | Tags('static_controller', 'data', 'http')
- def _publish_static_files(self, url, header={}):
- req = self.request(headers=header)
- req._url = url
- return self.app_handle_request(req, url), req
-
def _check_datafile_ok(self, fname):
- _, req = self._publish_static_files(fname)
- self.assertEqual(200, req.status_out)
- self.assertIn('last-modified', req.headers_out)
+ with self._publish_static_files(fname) as req:
+ self.assertEqual(200, req.status_out)
+ self.assertIn('last-modified', req.headers_out)
next_headers = {
'if-modified-since': req.get_response_header('last-modified', raw=True),
}
- _, req = self._publish_static_files(fname, next_headers)
- self.assertEqual(304, req.status_out)
+ with self._publish_static_files(fname, next_headers) as req:
+ self.assertEqual(304, req.status_out)
def _check_no_datafile(self, fname):
- _, req = self._publish_static_files(fname)
- self.assertEqual(404, req.status_out)
+ with self._publish_static_files(fname) as req:
+ self.assertEqual(404, req.status_out)
def test_static_data_mode(self):
hash = self.vreg.config.instance_md5_version()
@@ -83,12 +99,15 @@
for fname in glob.glob(osp.join(uicachedir, 'cache_concat_*')):
os.unlink(osp.join(uicachedir, fname))
+ @contextmanager
def _publish_js_files(self, js_files):
- req = self.request()
- head = HTMLHead(req)
- url = head.concat_urls([req.data_url(js_file) for js_file in js_files])[len(req.base_url()):]
- req._url = url
- return self.app_handle_request(req, url), req
+ with self.admin_access.web_request() as req:
+ head = HTMLHead(req)
+ url = head.concat_urls([req.data_url(js_file)
+ for js_file in js_files])[len(req.base_url()):]
+ req._url = url
+ res = self.app_handle_request(req, url)
+ yield res, req
def expected_content(self, js_files):
content = u''
@@ -101,14 +120,14 @@
def test_cache(self):
js_files = ('cubicweb.ajax.js', 'jquery.js')
- result, req = self._publish_js_files(js_files)
- self.assertNotEqual(404, req.status_out)
- # check result content
- self.assertEqual(result, self.expected_content(js_files))
- # make sure we kept a cached version on filesystem
- concat_hander = ConcatFilesHandler(self.config)
- filepath = concat_hander.build_filepath(js_files)
- self.assertTrue(osp.isfile(filepath))
+ with self._publish_js_files(js_files) as (result, req):
+ self.assertNotEqual(404, req.status_out)
+ # check result content
+ self.assertEqual(result, self.expected_content(js_files))
+ # make sure we kept a cached version on filesystem
+ concat_hander = ConcatFilesHandler(self.config)
+ filepath = concat_hander.build_filepath(js_files)
+ self.assertTrue(osp.isfile(filepath))
def test_invalid_file_in_debug_mode(self):
@@ -116,18 +135,18 @@
# in debug mode, an error is raised
self.config.debugmode = True
try:
- result, req = self._publish_js_files(js_files)
- #print result
- self.assertEqual(404, req.status_out)
+ with self._publish_js_files(js_files) as (result, req):
+ #print result
+ self.assertEqual(404, req.status_out)
finally:
self.config.debugmode = False
def test_invalid_file_in_production_mode(self):
js_files = ('cubicweb.ajax.js', 'dummy.js')
- result, req = self._publish_js_files(js_files)
- self.assertNotEqual(404, req.status_out)
- # check result content
- self.assertEqual(result, self.expected_content(js_files))
+ with self._publish_js_files(js_files) as (result, req):
+ self.assertNotEqual(404, req.status_out)
+ # check result content
+ self.assertEqual(result, self.expected_content(js_files))
if __name__ == '__main__':
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_views_xmlrss.py
--- a/web/test/unittest_views_xmlrss.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_views_xmlrss.py Wed Sep 24 18:04:30 2014 +0200
@@ -1,14 +1,16 @@
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.web.views.xmlrss import SERIALIZERS
+
class EntityXMLViewTC(CubicWebTC):
"""see also cw.sobjects.test.unittest_parsers"""
def test(self):
- req = self.request(relation=['tags-object', 'in_group-subject',
- 'in_state-subject', 'use_email-subject'])
- self.assertMultiLineEqual(
- req.user.view('xml'),
- '''\
-
+ rels = ['tags-object', 'in_group-subject',
+ 'in_state-subject', 'use_email-subject']
+ with self.admin_access.web_request(relation=rels) as req:
+ self.assertMultiLineEqual(
+ req.user.view('xml'),
+ '''\
+
admin
@@ -19,10 +21,10 @@
-
+
-
+
diff -r 84738d495ffd -r 793377697c81 web/test/unittest_viewselector.py
--- a/web/test/unittest_viewselector.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/test/unittest_viewselector.py Wed Sep 24 18:04:30 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.
@@ -21,16 +21,17 @@
from logilab.common.testlib import unittest_main
from cubicweb.devtools.testlib import CubicWebTC
-from cubicweb import CW_SOFTWARE_ROOT as BASE, Binary, UnknownProperty
-from cubicweb.predicates import (match_user_groups, is_instance,
+from cubicweb import Binary, UnknownProperty
+from cubicweb.predicates import (is_instance,
specified_etype_implements, rql_condition)
from cubicweb.web import NoSelectableObject
from cubicweb.web.action import Action
-from cubicweb.web.views import (
- primary, baseviews, tableview, editforms, calendar, management, embedding,
- actions, startup, cwuser, schema, xbel, vcard, owl, treeview, idownloadable,
- wdoc, debug, cwuser, cwproperties, cwsources, workflow, xmlrss, rdf,
- csvexport, json, undohistory)
+
+from cubicweb.web.views import (primary, baseviews, tableview,
+ editforms, management, actions, startup, cwuser, schema, xbel,
+ vcard, owl, treeview, idownloadable, wdoc, debug, cwuser,
+ cwproperties, cwsources, xmlrss, rdf, csvexport, json,
+ undohistory)
from cubes.folder import views as folderviews
@@ -55,11 +56,12 @@
class ViewSelectorTC(CubicWebTC):
def setup_database(self):
- req = self.request()
- req.create_entity('BlogEntry', title=u"une news !", content=u"cubicweb c'est beau")
- req.create_entity('Bookmark', title=u"un signet !", path=u"view?vid=index")
- req.create_entity('EmailAddress', address=u"devel@logilab.fr", alias=u'devel')
- req.create_entity('Tag', name=u'x')
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.create_entity('BlogEntry', title=u"une news !", content=u"cubicweb c'est beau")
+ cnx.create_entity('Bookmark', title=u"un signet !", path=u"view?vid=index")
+ cnx.create_entity('EmailAddress', address=u"devel@logilab.fr", alias=u'devel')
+ cnx.create_entity('Tag', name=u'x')
+ cnx.commit()
class VRegistryTC(ViewSelectorTC):
"""test the view selector"""
@@ -85,389 +87,381 @@
assert self.vreg['views']['propertiesform']
def test_possible_views_none_rset(self):
- req = self.request()
- self.assertListEqual(self.pviews(req, None),
- [('cw.sources-management', cwsources.CWSourcesManagementView),
- ('cw.users-and-groups-management', cwuser.UsersAndGroupsManagementView),
- ('gc', debug.GCView),
- ('index', startup.IndexView),
- ('info', debug.ProcessInformationView),
- ('manage', startup.ManageView),
- ('owl', owl.OWLView),
- ('propertiesform', cwproperties.CWPropertiesForm),
- ('registry', debug.RegistryView),
- ('schema', schema.SchemaView),
- ('siteinfo', debug.SiteInfoView),
- ('systempropertiesform', cwproperties.SystemCWPropertiesForm),
- ('tree', folderviews.FolderTreeView),
- ('undohistory', undohistory.UndoHistoryView),
- ])
+ with self.admin_access.web_request() as req:
+ self.assertListEqual(self.pviews(req, None),
+ [('cw.sources-management', cwsources.CWSourcesManagementView),
+ ('cw.users-and-groups-management', cwuser.UsersAndGroupsManagementView),
+ ('gc', debug.GCView),
+ ('index', startup.IndexView),
+ ('info', debug.ProcessInformationView),
+ ('manage', startup.ManageView),
+ ('owl', owl.OWLView),
+ ('propertiesform', cwproperties.CWPropertiesForm),
+ ('registry', debug.RegistryView),
+ ('schema', schema.SchemaView),
+ ('siteinfo', debug.SiteInfoView),
+ ('systempropertiesform', cwproperties.SystemCWPropertiesForm),
+ ('tree', folderviews.FolderTreeView),
+ ('undohistory', undohistory.UndoHistoryView)])
def test_possible_views_noresult(self):
- req = self.request()
- rset = req.execute('Any X WHERE X eid 999999')
- self.assertListEqual([('jsonexport', json.JsonRsetView)],
- self.pviews(req, rset))
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X eid 999999')
+ self.assertListEqual(self.pviews(req, rset),
+ [('csvexport', csvexport.CSVRsetView),
+ ('ecsvexport', csvexport.CSVEntityView),
+ ('jsonexport', json.JsonRsetView),
+ ])
def test_possible_views_one_egroup(self):
- req = self.request()
- rset = req.execute('CWGroup X WHERE X name "managers"')
- self.assertListEqual(self.pviews(req, rset),
- [('csvexport', csvexport.CSVRsetView),
- ('ecsvexport', csvexport.CSVEntityView),
- ('ejsonexport', json.JsonEntityView),
- ('filetree', treeview.FileTreeView),
- ('jsonexport', json.JsonRsetView),
- ('list', baseviews.ListView),
- ('oneline', baseviews.OneLineView),
- ('owlabox', owl.OWLABOXView),
- ('primary', cwuser.CWGroupPrimaryView)] + RDFVIEWS + [
- ('rsetxml', xmlrss.XMLRsetView),
- ('rss', xmlrss.RSSView),
- ('sameetypelist', baseviews.SameETypeListView),
- ('security', management.SecurityManagementView),
- ('table', tableview.RsetTableView),
- ('text', baseviews.TextView),
- ('treeview', treeview.TreeView),
- ('xbel', xbel.XbelView),
- ('xml', xmlrss.XMLView),
- ])
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWGroup X WHERE X name "managers"')
+ self.assertListEqual(self.pviews(req, rset),
+ [('csvexport', csvexport.CSVRsetView),
+ ('ecsvexport', csvexport.CSVEntityView),
+ ('ejsonexport', json.JsonEntityView),
+ ('filetree', treeview.FileTreeView),
+ ('jsonexport', json.JsonRsetView),
+ ('list', baseviews.ListView),
+ ('oneline', baseviews.OneLineView),
+ ('owlabox', owl.OWLABOXView),
+ ('primary', cwuser.CWGroupPrimaryView)] + \
+ RDFVIEWS + \
+ [('rsetxml', xmlrss.XMLRsetView),
+ ('rss', xmlrss.RSSView),
+ ('sameetypelist', baseviews.SameETypeListView),
+ ('security', management.SecurityManagementView),
+ ('table', tableview.RsetTableView),
+ ('text', baseviews.TextView),
+ ('treeview', treeview.TreeView),
+ ('xbel', xbel.XbelView),
+ ('xml', xmlrss.XMLView)])
def test_possible_views_multiple_egroups(self):
- req = self.request()
- rset = req.execute('CWGroup X')
- self.assertListEqual(self.pviews(req, rset),
- [('csvexport', csvexport.CSVRsetView),
- ('ecsvexport', csvexport.CSVEntityView),
- ('ejsonexport', json.JsonEntityView),
- ('filetree', treeview.FileTreeView),
- ('jsonexport', json.JsonRsetView),
- ('list', baseviews.ListView),
- ('oneline', baseviews.OneLineView),
- ('owlabox', owl.OWLABOXView),
- ('primary', cwuser.CWGroupPrimaryView)] + RDFVIEWS + [
- ('rsetxml', xmlrss.XMLRsetView),
- ('rss', xmlrss.RSSView),
- ('sameetypelist', baseviews.SameETypeListView),
- ('security', management.SecurityManagementView),
- ('table', tableview.RsetTableView),
- ('text', baseviews.TextView),
- ('treeview', treeview.TreeView),
- ('xbel', xbel.XbelView),
- ('xml', xmlrss.XMLView),
- ])
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWGroup X')
+ self.assertListEqual(self.pviews(req, rset),
+ [('csvexport', csvexport.CSVRsetView),
+ ('ecsvexport', csvexport.CSVEntityView),
+ ('ejsonexport', json.JsonEntityView),
+ ('filetree', treeview.FileTreeView),
+ ('jsonexport', json.JsonRsetView),
+ ('list', baseviews.ListView),
+ ('oneline', baseviews.OneLineView),
+ ('owlabox', owl.OWLABOXView),
+ ('primary', cwuser.CWGroupPrimaryView)] + RDFVIEWS + [
+ ('rsetxml', xmlrss.XMLRsetView),
+ ('rss', xmlrss.RSSView),
+ ('sameetypelist', baseviews.SameETypeListView),
+ ('security', management.SecurityManagementView),
+ ('table', tableview.RsetTableView),
+ ('text', baseviews.TextView),
+ ('treeview', treeview.TreeView),
+ ('xbel', xbel.XbelView),
+ ('xml', xmlrss.XMLView),
+ ])
def test_propertiesform_admin(self):
assert self.vreg['views']['propertiesform']
- req1 = self.request()
- req2 = self.request()
- rset1 = req1.execute('CWUser X WHERE X login "admin"')
- rset2 = req2.execute('CWUser X WHERE X login "anon"')
- self.assertTrue(self.vreg['views'].select('propertiesform', req1, rset=None))
- self.assertTrue(self.vreg['views'].select('propertiesform', req1, rset=rset1))
- self.assertTrue(self.vreg['views'].select('propertiesform', req2, rset=rset2))
+ with self.admin_access.web_request() as req:
+ rset1 = req.execute('CWUser X WHERE X login "admin"')
+ self.assertTrue(self.vreg['views'].select('propertiesform', req, rset=None))
+ self.assertTrue(self.vreg['views'].select('propertiesform', req, rset=rset1))
+ rset2 = req.execute('CWUser X WHERE X login "anon"')
+ self.assertTrue(self.vreg['views'].select('propertiesform', req, rset=rset2))
def test_propertiesform_anon(self):
- self.login('anon')
- req1 = self.request()
- req2 = self.request()
- rset1 = req1.execute('CWUser X WHERE X login "admin"')
- rset2 = req2.execute('CWUser X WHERE X login "anon"')
- self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=None)
- self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=rset1)
- self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=rset2)
+ with self.new_access('anon').web_request() as req:
+ rset1 = req.execute('CWUser X WHERE X login "admin"')
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req, rset=None)
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req, rset=rset1)
+ rset2 = req.execute('CWUser X WHERE X login "anon"')
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req, rset=rset2)
def test_propertiesform_jdoe(self):
- self.create_user(self.request(), 'jdoe')
- self.login('jdoe')
- req1 = self.request()
- req2 = self.request()
- rset1 = req1.execute('CWUser X WHERE X login "admin"')
- rset2 = req2.execute('CWUser X WHERE X login "jdoe"')
- self.assertTrue(self.vreg['views'].select('propertiesform', req1, rset=None))
- self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req1, rset=rset1)
- self.assertTrue(self.vreg['views'].select('propertiesform', req2, rset=rset2))
+ with self.admin_access.repo_cnx() as cnx:
+ self.create_user(cnx, 'jdoe')
+ cnx.commit()
+ with self.new_access('jdoe').web_request() as req:
+ rset1 = req.execute('CWUser X WHERE X login "admin"')
+ rset2 = req.execute('CWUser X WHERE X login "jdoe"')
+ self.assertTrue(self.vreg['views'].select('propertiesform', req, rset=None))
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'propertiesform', req, rset=rset1)
+ self.assertTrue(self.vreg['views'].select('propertiesform', req, rset=rset2))
def test_possible_views_multiple_different_types(self):
- req = self.request()
- rset = req.execute('Any X')
- self.assertListEqual(self.pviews(req, rset),
- [('csvexport', csvexport.CSVRsetView),
- ('ecsvexport', csvexport.CSVEntityView),
- ('ejsonexport', json.JsonEntityView),
- ('filetree', treeview.FileTreeView),
- ('jsonexport', json.JsonRsetView),
- ('list', baseviews.ListView),
- ('oneline', baseviews.OneLineView),
- ('owlabox', owl.OWLABOXView),
- ('primary', primary.PrimaryView),] + RDFVIEWS + [
- ('rsetxml', xmlrss.XMLRsetView),
- ('rss', xmlrss.RSSView),
- ('security', management.SecurityManagementView),
- ('table', tableview.RsetTableView),
- ('text', baseviews.TextView),
- ('treeview', treeview.TreeView),
- ('xbel', xbel.XbelView),
- ('xml', xmlrss.XMLView),
- ])
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X')
+ self.assertListEqual(self.pviews(req, rset),
+ [('csvexport', csvexport.CSVRsetView),
+ ('ecsvexport', csvexport.CSVEntityView),
+ ('ejsonexport', json.JsonEntityView),
+ ('filetree', treeview.FileTreeView),
+ ('jsonexport', json.JsonRsetView),
+ ('list', baseviews.ListView),
+ ('oneline', baseviews.OneLineView),
+ ('owlabox', owl.OWLABOXView),
+ ('primary', primary.PrimaryView),] + RDFVIEWS + [
+ ('rsetxml', xmlrss.XMLRsetView),
+ ('rss', xmlrss.RSSView),
+ ('security', management.SecurityManagementView),
+ ('table', tableview.RsetTableView),
+ ('text', baseviews.TextView),
+ ('treeview', treeview.TreeView),
+ ('xbel', xbel.XbelView),
+ ('xml', xmlrss.XMLView),
+ ])
def test_possible_views_any_rset(self):
- req = self.request()
- rset = req.execute('Any N, X WHERE X in_group Y, Y name N')
- self.assertListEqual(self.pviews(req, rset),
- [('csvexport', csvexport.CSVRsetView),
- ('jsonexport', json.JsonRsetView),
- ('rsetxml', xmlrss.XMLRsetView),
- ('table', tableview.RsetTableView),
- ])
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any N, X WHERE X in_group Y, Y name N')
+ self.assertListEqual(self.pviews(req, rset),
+ [('csvexport', csvexport.CSVRsetView),
+ ('ecsvexport', csvexport.CSVEntityView),
+ ('jsonexport', json.JsonRsetView),
+ ('rsetxml', xmlrss.XMLRsetView),
+ ('table', tableview.RsetTableView),
+ ])
def test_possible_views_multiple_eusers(self):
- req = self.request()
- rset = req.execute('CWUser X')
- self.assertListEqual(self.pviews(req, rset),
- [('csvexport', csvexport.CSVRsetView),
- ('ecsvexport', csvexport.CSVEntityView),
- ('ejsonexport', json.JsonEntityView),
- ('filetree', treeview.FileTreeView),
- ('foaf', cwuser.FoafView),
- ('jsonexport', json.JsonRsetView),
- ('list', baseviews.ListView),
- ('oneline', baseviews.OneLineView),
- ('owlabox', owl.OWLABOXView),
- ('primary', primary.PrimaryView)] + RDFVIEWS + [
- ('rsetxml', xmlrss.XMLRsetView),
- ('rss', xmlrss.RSSView),
- ('sameetypelist', baseviews.SameETypeListView),
- ('security', management.SecurityManagementView),
- ('table', tableview.RsetTableView),
- ('text', baseviews.TextView),
- ('treeview', treeview.TreeView),
- ('vcard', vcard.VCardCWUserView),
- ('xbel', xbel.XbelView),
- ('xml', xmlrss.XMLView),
- ])
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X')
+ self.assertListEqual(self.pviews(req, rset),
+ [('csvexport', csvexport.CSVRsetView),
+ ('ecsvexport', csvexport.CSVEntityView),
+ ('ejsonexport', json.JsonEntityView),
+ ('filetree', treeview.FileTreeView),
+ ('foaf', cwuser.FoafView),
+ ('jsonexport', json.JsonRsetView),
+ ('list', baseviews.ListView),
+ ('oneline', baseviews.OneLineView),
+ ('owlabox', owl.OWLABOXView),
+ ('primary', primary.PrimaryView)] + RDFVIEWS + [
+ ('rsetxml', xmlrss.XMLRsetView),
+ ('rss', xmlrss.RSSView),
+ ('sameetypelist', baseviews.SameETypeListView),
+ ('security', management.SecurityManagementView),
+ ('table', tableview.RsetTableView),
+ ('text', baseviews.TextView),
+ ('treeview', treeview.TreeView),
+ ('vcard', vcard.VCardCWUserView),
+ ('xbel', xbel.XbelView),
+ ('xml', xmlrss.XMLView),
+ ])
def test_possible_actions_none_rset(self):
- req = self.request()
- self.assertDictEqual(self.pactionsdict(req, None, skipcategories=()),
- {'useractions': USERACTIONS,
- 'siteactions': SITEACTIONS,
- 'manage': MANAGEACTIONS,
- 'footer': FOOTERACTIONS,
+ with self.admin_access.web_request() as req:
+ self.assertDictEqual(self.pactionsdict(req, None, skipcategories=()),
+ {'useractions': USERACTIONS,
+ 'siteactions': SITEACTIONS,
+ 'manage': MANAGEACTIONS,
+ 'footer': FOOTERACTIONS})
- })
def test_possible_actions_no_entity(self):
- req = self.request()
- rset = req.execute('Any X WHERE X eid 999999')
- self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
- {'useractions': USERACTIONS,
- 'siteactions': SITEACTIONS,
- 'manage': MANAGEACTIONS,
- 'footer': FOOTERACTIONS,
- })
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X eid 999999')
+ self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
+ {'useractions': USERACTIONS,
+ 'siteactions': SITEACTIONS,
+ 'manage': MANAGEACTIONS,
+ 'footer': FOOTERACTIONS,
+ })
def test_possible_actions_same_type_entities(self):
- req = self.request()
- rset = req.execute('CWGroup X')
- self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
- {'useractions': USERACTIONS,
- 'siteactions': SITEACTIONS,
- 'manage': MANAGEACTIONS,
- 'footer': FOOTERACTIONS,
- 'mainactions': [actions.MultipleEditAction],
- 'moreactions': [actions.DeleteAction,
- actions.AddNewAction],
- })
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWGroup X')
+ self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
+ {'useractions': USERACTIONS,
+ 'siteactions': SITEACTIONS,
+ 'manage': MANAGEACTIONS,
+ 'footer': FOOTERACTIONS,
+ 'mainactions': [actions.MultipleEditAction],
+ 'moreactions': [actions.DeleteAction,
+ actions.AddNewAction]})
def test_possible_actions_different_types_entities(self):
- req = self.request()
- rset = req.execute('Any X')
- self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
- {'useractions': USERACTIONS,
- 'siteactions': SITEACTIONS,
- 'manage': MANAGEACTIONS,
- 'footer': FOOTERACTIONS,
- 'moreactions': [actions.DeleteAction],
- })
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X')
+ self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
+ {'useractions': USERACTIONS,
+ 'siteactions': SITEACTIONS,
+ 'manage': MANAGEACTIONS,
+ 'footer': FOOTERACTIONS,
+ 'moreactions': [actions.DeleteAction],
+ })
def test_possible_actions_final_entities(self):
- req = self.request()
- rset = req.execute('Any N, X WHERE X in_group Y, Y name N')
- self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
- {'useractions': USERACTIONS,
- 'siteactions': SITEACTIONS,
- 'manage': MANAGEACTIONS,
- 'footer': FOOTERACTIONS,
- })
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any N, X WHERE X in_group Y, Y name N')
+ self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
+ {'useractions': USERACTIONS,
+ 'siteactions': SITEACTIONS,
+ 'manage': MANAGEACTIONS,
+ 'footer': FOOTERACTIONS,
+ })
def test_possible_actions_eetype_cwuser_entity(self):
- req = self.request()
- rset = req.execute('CWEType X WHERE X name "CWUser"')
- self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
- {'useractions': USERACTIONS,
- 'siteactions': SITEACTIONS,
- 'manage': MANAGEACTIONS,
- 'footer': FOOTERACTIONS,
- 'mainactions': [actions.ModifyAction,
- actions.ViewSameCWEType],
- 'moreactions': [actions.ManagePermissionsAction,
- actions.AddRelatedActions,
- actions.DeleteAction,
- actions.CopyAction,
- ],
- })
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWEType X WHERE X name "CWUser"')
+ self.assertDictEqual(self.pactionsdict(req, rset, skipcategories=()),
+ {'useractions': USERACTIONS,
+ 'siteactions': SITEACTIONS,
+ 'manage': MANAGEACTIONS,
+ 'footer': FOOTERACTIONS,
+ 'mainactions': [actions.ModifyAction,
+ actions.ViewSameCWEType],
+ 'moreactions': [actions.ManagePermissionsAction,
+ actions.AddRelatedActions,
+ actions.DeleteAction,
+ actions.CopyAction,
+ ],
+ })
def test_select_creation_form(self):
rset = None
- req = self.request()
- # creation form
- req.form['etype'] = 'CWGroup'
- self.assertIsInstance(self.vreg['views'].select('creation', req, rset=rset),
- editforms.CreationFormView)
- del req.form['etype']
- # custom creation form
- class CWUserCreationForm(editforms.CreationFormView):
- __select__ = specified_etype_implements('CWUser')
- self.vreg._loadedmods[__name__] = {}
- self.vreg.register(CWUserCreationForm)
- req.form['etype'] = 'CWUser'
- self.assertIsInstance(self.vreg['views'].select('creation', req, rset=rset),
- CWUserCreationForm)
+ with self.admin_access.web_request() as req:
+ # creation form
+ req.form['etype'] = 'CWGroup'
+ self.assertIsInstance(self.vreg['views'].select('creation', req, rset=rset),
+ editforms.CreationFormView)
+
+ with self.admin_access.web_request() as req:
+ # custom creation form
+ class CWUserCreationForm(editforms.CreationFormView):
+ __select__ = specified_etype_implements('CWUser')
+
+ self.vreg._loadedmods[__name__] = {}
+ self.vreg.register(CWUserCreationForm)
+ req.form['etype'] = 'CWUser'
+
+ self.assertIsInstance(self.vreg['views'].select('creation', req, rset=rset),
+ CWUserCreationForm)
def test_select_view(self):
# no entity
rset = None
- req = self.request()
- self.assertIsInstance(self.vreg['views'].select('index', req, rset=rset),
- startup.IndexView)
- self.assertRaises(NoSelectableObject,
- self.vreg['views'].select, 'primary', req, rset=rset)
- self.assertRaises(NoSelectableObject,
- self.vreg['views'].select, 'table', req, rset=rset)
+ with self.admin_access.web_request() as req:
+ self.assertIsInstance(self.vreg['views'].select('index', req, rset=rset),
+ startup.IndexView)
+ self.assertRaises(NoSelectableObject,
+ self.vreg['views'].select, 'primary', req, rset=rset)
+ self.assertRaises(NoSelectableObject,
+ self.vreg['views'].select, 'table', req, rset=rset)
- # no entity
- req = self.request()
- rset = req.execute('Any X WHERE X eid 999999')
- self.assertRaises(NoSelectableObject,
+ # no entity
+ rset = req.execute('Any X WHERE X eid 999999')
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'index', req, rset=rset)
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'creation', req, rset=rset)
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'primary', req, rset=rset)
- self.assertRaises(NoSelectableObject,
- self.vreg['views'].select, 'table', req, rset=rset)
- # one entity
- req = self.request()
- rset = req.execute('CWGroup X WHERE X name "managers"')
- self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
- primary.PrimaryView)
- self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
- baseviews.ListView)
- self.assertIsInstance(self.vreg['views'].select('edition', req, rset=rset),
- editforms.EditionFormView)
- self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
- tableview.RsetTableView)
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
+ self.vreg['views'].select, 'table', req, rset=rset)
+ # one entity
+ rset = req.execute('CWGroup X WHERE X name "managers"')
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
+ primary.PrimaryView)
+ self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
+ baseviews.ListView)
+ self.assertIsInstance(self.vreg['views'].select('edition', req, rset=rset),
+ editforms.EditionFormView)
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
+ tableview.RsetTableView)
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'creation', req, rset=rset)
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'index', req, rset=rset)
- # list of entities of the same type
- req = self.request()
- rset = req.execute('CWGroup X')
- self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
- primary.PrimaryView)
- self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
- baseviews.ListView)
- self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
- tableview.RsetTableView)
- self.assertRaises(NoSelectableObject,
+ # list of entities of the same type
+ rset = req.execute('CWGroup X')
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
+ primary.PrimaryView)
+ self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
+ baseviews.ListView)
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
+ tableview.RsetTableView)
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'creation', req, rset=rset)
- # list of entities of different types
- req = self.request()
- rset = req.execute('Any X')
- self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
+ # list of entities of different types
+ rset = req.execute('Any X')
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
primary.PrimaryView)
- self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('list', req, rset=rset),
baseviews.ListView)
- self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
tableview.RsetTableView)
- self.assertRaises(NoSelectableObject,
- self.vreg['views'].select, 'creation', req, rset=rset)
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
+ self.vreg['views'].select, 'creation', req, rset=rset)
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'index', req, rset=rset)
- # whatever
- req = self.request()
- rset = req.execute('Any N, X WHERE X in_group Y, Y name N')
- self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
+ # whatever
+ rset = req.execute('Any N, X WHERE X in_group Y, Y name N')
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
tableview.RsetTableView)
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'index', req, rset=rset)
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'creation', req, rset=rset)
- self.assertRaises(NoSelectableObject,
- self.vreg['views'].select, 'primary', req, rset=rset)
- self.assertRaises(NoSelectableObject,
- self.vreg['views'].select, 'list', req, rset=rset)
- self.assertRaises(NoSelectableObject,
- self.vreg['views'].select, 'edition', req, rset=rset)
- # mixed query
- req = self.request()
- rset = req.execute('Any U,G WHERE U is CWUser, G is CWGroup')
- self.assertRaises(NoSelectableObject,
+ self.assertRaises(NoSelectableObject,
+ self.vreg['views'].select, 'primary', req, rset=rset)
+ self.assertRaises(NoSelectableObject,
+ self.vreg['views'].select, 'list', req, rset=rset)
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'edition', req, rset=rset)
- self.assertRaises(NoSelectableObject,
+ # mixed query
+ rset = req.execute('Any U,G WHERE U is CWUser, G is CWGroup')
+ self.assertRaises(NoSelectableObject,
+ self.vreg['views'].select, 'edition', req, rset=rset)
+ self.assertRaises(NoSelectableObject,
self.vreg['views'].select, 'creation', req, rset=rset)
- self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
- tableview.RsetTableView)
+ self.assertIsInstance(self.vreg['views'].select('table', req, rset=rset),
+ tableview.RsetTableView)
def test_interface_selector(self):
- image = self.request().create_entity('File', data_name=u'bim.png', data=Binary('bim'))
- # image primary view priority
- req = self.request()
- rset = req.execute('File X WHERE X data_name "bim.png"')
- self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
- idownloadable.IDownloadablePrimaryView)
+ with self.admin_access.web_request() as req:
+ req.create_entity('File', data_name=u'bim.png', data=Binary('bim'))
+ # image primary view priority
+ rset = req.execute('File X WHERE X data_name "bim.png"')
+ self.assertIsInstance(self.vreg['views'].select('primary', req, rset=rset),
+ idownloadable.IDownloadablePrimaryView)
def test_score_entity_selector(self):
- image = self.request().create_entity('File', data_name=u'bim.png', data=Binary('bim'))
- # image/ehtml primary view priority
- req = self.request()
- rset = req.execute('File X WHERE X data_name "bim.png"')
- self.assertIsInstance(self.vreg['views'].select('image', req, rset=rset),
- idownloadable.ImageView)
- self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'ehtml', req, rset=rset)
+ with self.admin_access.web_request() as req:
+ req.create_entity('File', data_name=u'bim.png', data=Binary('bim'))
+ # image/ehtml primary view priority
+ rset = req.execute('File X WHERE X data_name "bim.png"')
+ self.assertIsInstance(self.vreg['views'].select('image', req, rset=rset),
+ idownloadable.ImageView)
+ self.assertRaises(NoSelectableObject, self.vreg['views'].select, 'ehtml', req, rset=rset)
- fileobj = self.request().create_entity('File', data_name=u'bim.html', data=Binary('bambam '
- % (self._cw.base_url(), self._cw.uiprops['LOGO']))
+ w(u' ' % self._cw.base_url())
class ApplicationName(HeaderComponent):
@@ -188,79 +187,18 @@
"""
__select__ = yes()
__regid__ = 'applmessages'
- # don't want user to hide this component using an cwproperty
+ # don't want user to hide this component using a cwproperty
cw_property_defs = {}
def call(self, msg=None):
if msg is None:
- msgs = []
- if self._cw.cnx:
- srcmsg = self._cw.get_shared_data('sources_error', pop=True, txdata=True)
- if srcmsg:
- msgs.append(srcmsg)
- reqmsg = self._cw.message # XXX don't call self._cw.message twice
- if reqmsg:
- msgs.append(reqmsg)
- else:
- msgs = [msg]
+ msg = self._cw.message # XXX don't call self._cw.message twice
self.w(u'\n' %
- (toggle_action('appMsg'), (msgs and ' ' or 'hidden')))
- for msg in msgs:
- self.w(u'
%s
' % (self.domid, msg))
+ (toggle_action('appMsg'), (msg and ' ' or 'hidden')))
+ self.w(u'
%s
' % (self.domid, msg))
self.w(u'
')
-class EtypeRestrictionComponent(component.Component):
- """displays the list of entity types contained in the resultset
- to be able to filter accordingly.
- """
- __regid__ = 'etypenavigation'
- __select__ = multi_etypes_rset() | match_form_params(
- '__restrtype', '__restrtypes', '__restrrql')
- cw_property_defs = VISIBLE_PROP_DEF
- # don't want user to hide this component using an cwproperty
- site_wide = True
- visible = False # disabled by default
-
- def call(self):
- _ = self._cw._
- self.w(u'')
- restrtype = self._cw.form.get('__restrtype')
- restrtypes = self._cw.form.get('__restrtypes', '').split(',')
- restrrql = self._cw.form.get('__restrrql')
- if not restrrql:
- rqlst = self.cw_rset.syntax_tree()
- restrrql = rqlst.as_string(self._cw.encoding, self.cw_rset.args)
- restrtypes = self.cw_rset.column_types(0)
- else:
- rqlst = parse(restrrql)
- html = []
- on_etype = False
- etypes = sorted((display_name(self._cw, etype).capitalize(), etype)
- for etype in restrtypes)
- for elabel, etype in etypes:
- if etype == restrtype:
- html.append(u'
%s ' % elabel)
- on_etype = True
- else:
- rqlst.save_state()
- for select in rqlst.children:
- select.add_type_restriction(select.selection[0].variable, etype)
- newrql = rqlst.as_string(self._cw.encoding, self.cw_rset.args)
- url = self._cw.build_url(rql=newrql, __restrrql=restrrql,
- __restrtype=etype, __restrtypes=','.join(restrtypes))
- html.append(u'
%s ' % (
- xml_escape(url), elabel))
- rqlst.recover()
- if on_etype:
- url = self._cw.build_url(rql=restrrql)
- html.insert(0, u'
%s ' % (
- url, _('Any')))
- else:
- html.insert(0, u'
%s ' % _('Any'))
- self.w(u' | '.join(html))
- self.w(u'
')
-
# contextual components ########################################################
diff -r 84738d495ffd -r 793377697c81 web/views/basetemplates.py
--- a/web/views/basetemplates.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/views/basetemplates.py Wed Sep 24 18:04:30 2014 +0200
@@ -176,7 +176,6 @@
w = self.whead
lang = self._cw.lang
self.write_doctype()
- # explictly close the tag to avoid IE 6 bugs while browsing DOM
self._cw.html_headers.define_var('BASE_URL', self._cw.base_url())
self._cw.html_headers.define_var('DATA_URL', self._cw.datadir_url)
w(u' \n'
@@ -474,7 +473,7 @@
if target and target != '/':
url_args['postlogin_path'] = target
return self._cw.build_url('login', __secure__=True, **url_args)
- return super(LogForm, self).form_action()
+ return super(BaseLogForm, self).form_action()
class LogForm(BaseLogForm):
"""Simple login form that send username and password
diff -r 84738d495ffd -r 793377697c81 web/views/csvexport.py
--- a/web/views/csvexport.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/views/csvexport.py Wed Sep 24 18:04:30 2014 +0200
@@ -21,6 +21,7 @@
_ = unicode
from cubicweb.schema import display_name
+from cubicweb.predicates import any_rset
from cubicweb.uilib import UnicodeCSVWriter
from cubicweb.view import EntityView, AnyRsetView
@@ -47,6 +48,7 @@
class CSVRsetView(CSVMixIn, AnyRsetView):
"""dumps raw result set in CSV"""
__regid__ = 'csvexport'
+ __select__ = any_rset()
title = _('csv export')
def call(self):
@@ -78,6 +80,7 @@
contents)
"""
__regid__ = 'ecsvexport'
+ __select__ = any_rset()
title = _('csv export (entities)')
def call(self):
diff -r 84738d495ffd -r 793377697c81 web/views/cwsources.py
--- a/web/views/cwsources.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/views/cwsources.py Wed Sep 24 18:04:30 2014 +0200
@@ -99,7 +99,7 @@
cellvids={1: 'editable-final'})
-MAPPED_SOURCE_TYPES = set( ('pyrorql', 'datafeed') )
+MAPPED_SOURCE_TYPES = set( ('datafeed',) )
class CWSourceMappingTab(EntityView):
__regid__ = 'cwsource-mapping'
@@ -117,21 +117,7 @@
'Any X, SCH, XO ORDERBY ET WHERE X options XO, X cw_for_source S, S eid %(s)s, '
'X cw_schema SCH, SCH is ET', {'s': entity.eid})
self.wview('table', rset, 'noresult')
- # self.w('%s ' % _('Relations that should not be crossed'))
- # self.w('%s
' % _(
- # 'By default, when a relation is not supported by a source, it is '
- # 'supposed that a local relation may point to an entity from the '
- # 'external source. Relations listed here won\'t have this '
- # '"crossing" behaviour.'))
- # self.wview('list', entity.related('cw_dont_cross'), 'noresult')
- # self.w('%s ' % _('Relations that can be crossed'))
- # self.w('%s
' % _(
- # 'By default, when a relation is supported by a source, it is '
- # 'supposed that a local relation can\'t point to an entity from the '
- # 'external source. Relations listed here may have this '
- # '"crossing" behaviour anyway.'))
- # self.wview('list', entity.related('cw_may_cross'), 'noresult')
- checker = MAPPING_CHECKERS.get(entity.type, MappingChecker)(entity)
+ checker = MappingChecker(entity)
checker.check()
if (checker.errors or checker.warnings or checker.infos):
self.w('%s ' % _('Detected problems'))
@@ -215,49 +201,6 @@
pass
-class PyroRQLMappingChecker(MappingChecker):
- """pyrorql source mapping checker"""
-
- def init(self):
- self.dontcross = set()
- self.maycross = set()
- super(PyroRQLMappingChecker, self).init()
-
- def init_schemacfg(self, schemacfg):
- options = schemacfg.options or ()
- if 'dontcross' in options:
- self.dontcross.add(schemacfg.schema.name)
- else:
- super(PyroRQLMappingChecker, self).init_schemacfg(schemacfg)
- if 'maycross' in options:
- self.maycross.add(schemacfg.schema.name)
-
- def custom_check(self):
- error = self.errors.append
- info = self.infos.append
- for etype in self.sentities:
- eschema = self.schema[etype]
- for rschema, ttypes, role in eschema.relation_definitions():
- if rschema in META_RTYPES:
- continue
- if not rschema in self.srelations:
- if rschema not in self.dontcross:
- if role == 'subject' and rschema.inlined:
- error(_('inlined relation %(rtype)s of %(etype)s '
- 'should be supported') %
- {'rtype': rschema, 'etype': etype})
- elif (rschema not in self.seen and rschema not in self.maycross):
- info(_('you may want to specify something for %s') %
- rschema)
- self.seen.add(rschema)
- elif rschema in self.maycross and rschema.inlined:
- error(_('you should un-inline relation %s which is '
- 'supported and may be crossed ') % rschema)
-
-MAPPING_CHECKERS = {
- 'pyrorql': PyroRQLMappingChecker,
- }
-
class CWSourceImportsTab(EntityView):
__regid__ = 'cwsource-imports'
diff -r 84738d495ffd -r 793377697c81 web/views/debug.py
--- a/web/views/debug.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/views/debug.py Wed Sep 24 18:04:30 2014 +0200
@@ -97,7 +97,7 @@
w(u'%s ' % _('Repository'))
w(u'%s ' % _('resources usage'))
w(u'')
- stats = repo.stats()
+ stats = self._cw.call_service('repo_stats')
for element in sorted(stats):
w(u'%s %s %s '
% (element, xml_escape(unicode(stats[element])),
@@ -105,7 +105,7 @@
w(u'
')
if req.cnx.is_repo_in_memory and req.user.is_in_group('managers'):
w(u'%s ' % _('opened sessions'))
- sessions = repo._sessions.itervalues()
+ sessions = repo._sessions.values()
if sessions:
w(u'')
for session in sessions:
@@ -131,19 +131,9 @@
sessions = SESSION_MANAGER.current_sessions()
w(u'%s ' % _('opened web sessions'))
if sessions:
- n_no_cnx_sessions = 0
w(u'')
for session in sessions:
- if not session.cnx:
- # We do not want to list all sessions without cnx
- # Their session ID are useless, hence we just count them
- n_no_cnx_sessions += 1
- continue
- try:
- last_usage_time = session.cnx.check()
- except BadConnectionId:
- w(u'%s (INVALID) ' % session.sessionid)
- continue
+ last_usage_time = session.mtime
w(u'%s (%s: %s) ' % (
session.sessionid,
_('last usage'),
@@ -151,9 +141,6 @@
dict_to_html(w, session.data)
w(u' ')
w(u' ')
- if n_no_cnx_sessions > 0:
- w(u'%s %s ' % (n_no_cnx_sessions,
- _('web sessions without CNX')))
else:
w(u'%s
' % _('no web sessions found'))
diff -r 84738d495ffd -r 793377697c81 web/views/editcontroller.py
--- a/web/views/editcontroller.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/views/editcontroller.py Wed Sep 24 18:04:30 2014 +0200
@@ -178,7 +178,7 @@
form = req.form
# so we're able to know the main entity from the repository side
if '__maineid' in form:
- req.set_shared_data('__maineid', form['__maineid'], txdata=True)
+ req.transaction_data['__maineid'] = form['__maineid']
# no specific action, generic edition
self._to_create = req.data['eidmap'] = {}
# those two data variables are used to handle relation from/to entities
@@ -252,15 +252,7 @@
formid = 'edition'
form = req.vreg['forms'].select(formid, req, entity=entity)
eid = form.actual_eid(entity.eid)
- try:
- editedfields = formparams['_cw_entity_fields']
- except KeyError:
- try:
- editedfields = formparams['_cw_edited_fields']
- warn('[3.13] _cw_edited_fields has been renamed _cw_entity_fields',
- DeprecationWarning)
- except KeyError:
- raise RequestError(req._('no edited fields specified for entity %s' % entity.eid))
+ editedfields = formparams['_cw_entity_fields']
form.formvalues = {} # init fields value cache
for field in form.iter_modified_fields(editedfields, entity):
self.handle_formfield(form, field, rqlquery)
diff -r 84738d495ffd -r 793377697c81 web/views/formrenderers.py
--- a/web/views/formrenderers.py Wed Sep 24 17:35:59 2014 +0200
+++ b/web/views/formrenderers.py Wed Sep 24 18:04:30 2014 +0200
@@ -202,6 +202,8 @@
attrs.setdefault('class', form.cssclass)
if form.cwtarget:
attrs.setdefault('cubicweb:target', form.cwtarget)
+ if not form.autocomplete:
+ attrs.setdefault('autocomplete', 'off')
return '