--- a/web/application.py Wed Apr 22 16:56:03 2009 +0200
+++ b/web/application.py Wed Apr 22 16:56:19 2009 +0200
@@ -26,7 +26,7 @@
class AbstractSessionManager(Component):
"""manage session data associated to a session identifier"""
id = 'sessionmanager'
-
+
def __init__(self):
self.session_time = self.vreg.config['http-session-time'] or None
assert self.session_time is None or self.session_time > 0
@@ -39,7 +39,7 @@
assert self.cleanup_anon_session_time < self.session_time
self.authmanager = self.vreg.select_component('authmanager')
assert self.authmanager, 'no authentication manager found'
-
+
def clean_sessions(self):
"""cleanup sessions which has not been unused since a given amount of
time. Return the number of sessions which have been closed.
@@ -57,28 +57,28 @@
self.close_session(session)
closed += 1
return closed, total - closed
-
+
def has_expired(self, session):
"""return True if the web session associated to the session is expired
"""
return not (self.session_time is None or
time() < session.last_usage_time + self.session_time)
-
+
def current_sessions(self):
"""return currently open sessions"""
raise NotImplementedError()
-
+
def get_session(self, req, sessionid):
"""return existing session for the given session identifier"""
raise NotImplementedError()
def open_session(self, req):
"""open and return a new session for the given request
-
+
:raise ExplicitLogin: if authentication is required
"""
raise NotImplementedError()
-
+
def close_session(self, session):
"""close session on logout or on invalid session detected (expired out,
corrupted...)
@@ -92,13 +92,13 @@
def authenticate(self, req):
"""authenticate user and return corresponding user object
-
+
:raise ExplicitLogin: if authentication is required (no authentication
info found or wrong user/password)
"""
raise NotImplementedError()
-
+
class CookieSessionHandler(object):
"""a session handler using a cookie to store the session identifier
@@ -107,7 +107,7 @@
identifier
"""
SESSION_VAR = '__session'
-
+
def __init__(self, appli):
self.session_manager = appli.vreg.select_component('sessionmanager')
assert self.session_manager, 'no session manager found'
@@ -121,7 +121,7 @@
time
"""
self.session_manager.clean_sessions()
-
+
def set_session(self, req):
"""associate a session to the request
@@ -132,7 +132,7 @@
if no session id is found, open a new session for the connected user
or request authentification as needed
- :raise Redirect: if authentication has occured and succeed
+ :raise Redirect: if authentication has occured and succeed
"""
assert req.cnx is None # at this point no cnx should be set on the request
cookie = req.get_cookie()
@@ -154,7 +154,7 @@
def get_session(self, req, sessionid):
return self.session_manager.get_session(req, sessionid)
-
+
def open_session(self, req):
session = self.session_manager.open_session(req)
cookie = req.get_cookie()
@@ -177,7 +177,7 @@
except:
req.cnx.rollback()
raise
-
+
def _postlogin(self, req):
"""postlogin: the user has been authenticated, redirect to the original
page (index by default) with a welcome message
@@ -197,7 +197,7 @@
if path == 'login':
path = 'view'
raise Redirect(req.build_url(path, **args))
-
+
def logout(self, req):
"""logout from the application by cleaning the session and raising
`AuthenticationError`
@@ -211,7 +211,7 @@
"""Central registry for the web application. This is one of the central
object in the web application, coupling dynamically loaded objects with
the application's schema and the application's configuration objects.
-
+
It specializes the VRegistry by adding some convenience methods to
access to stored objects. Currently we have the following registries
of objects known by the web application (library may use some others
@@ -223,7 +223,7 @@
* components
* actions
"""
-
+
def __init__(self, config, debug=None,
session_handler_fact=CookieSessionHandler,
vreg=None):
@@ -243,14 +243,14 @@
from threading import Lock
self._query_log = open(config['query-log-file'], 'a')
self.publish = self.log_publish
- self._logfile_lock = Lock()
+ self._logfile_lock = Lock()
else:
self._query_log = None
self.publish = self.main_publish
# instantiate session and url resolving helpers
self.session_handler = session_handler_fact(self)
self.url_resolver = vreg.select_component('urlpublisher')
-
+
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
@@ -266,9 +266,9 @@
req=req, appli=self)
except NoSelectableObject:
raise Unauthorized(req._('not authorized'))
-
+
# publish methods #########################################################
-
+
def log_publish(self, path, req):
"""wrapper around _publish to log all queries executed for a given
accessed path
@@ -293,13 +293,13 @@
def main_publish(self, path, req):
"""method called by the main publisher to process <path>
-
+
should return a string containing the resulting page or raise a
`NotFound` exception
:type path: str
:param path: the path part of the url to publish
-
+
:type req: `web.Request`
:param req: the request object
@@ -370,7 +370,7 @@
req.set_session_data(req.form['__errorurl'], forminfo)
raise Redirect(req.form['__errorurl'])
self.error_handler(req, ex, tb=False)
-
+
def error_handler(self, req, ex, tb=False):
excinfo = sys.exc_info()
self.exception(repr(ex))
@@ -389,13 +389,13 @@
except:
content = self.vreg.main_template(req, 'error-template')
raise StatusResponse(500, content)
-
+
def need_login_content(self, req):
return self.vreg.main_template(req, 'login')
-
+
def loggedout_content(self, req):
return self.vreg.main_template(req, 'loggedout')
-
+
def notfound_content(self, req):
req.form['vid'] = '404'
view = self.vreg.select_view('404', req, None)
@@ -407,7 +407,7 @@
if template not in self.vreg.registry('views') :
template = 'main-template'
return template
-
+
set_log_methods(CubicWebPublisher, LOGGER)
set_log_methods(CookieSessionHandler, LOGGER)
--- a/web/request.py Wed Apr 22 16:56:03 2009 +0200
+++ b/web/request.py Wed Apr 22 16:56:19 2009 +0200
@@ -73,7 +73,7 @@
self.data = {}
# search state: 'normal' or 'linksearch' (eg searching for an object
# to create a relation with another)
- self.search_state = ('normal',)
+ self.search_state = ('normal',)
# tabindex generator
self.tabindexgen = count()
self.next_tabindex = self.tabindexgen.next
@@ -106,27 +106,27 @@
return
# 3. default language
self.set_default_language(vreg)
-
+
def set_language(self, lang):
self._ = self.__ = self.translations[lang]
self.lang = lang
self.debug('request language: %s', lang)
-
+
# input form parameters management ########################################
-
+
# common form parameters which should be protected against html values
# XXX can't add 'eid' for instance since it may be multivalued
# dont put rql as well, if query contains < and > it will be corrupted!
- no_script_form_params = set(('vid',
- 'etype',
+ no_script_form_params = set(('vid',
+ 'etype',
'vtitle', 'title',
'__message',
'__redirectvid', '__redirectrql'))
-
+
def setup_params(self, params):
"""WARNING: we're intentionaly leaving INTERNAL_FIELD_VALUE here
- subclasses should overrides to
+ subclasses should overrides to
"""
if params is None:
params = {}
@@ -146,7 +146,7 @@
del self.form[k]
else:
self.form[k] = v
-
+
def no_script_form_param(self, param, default=None, value=None):
"""ensure there is no script in a user form param
@@ -167,11 +167,11 @@
value = value[0]
return remove_html_tags(value)
return value
-
+
def list_form_param(self, param, form=None, pop=False):
"""get param from form parameters and return its value as a list,
skipping internal markers if any
-
+
* if the parameter isn't defined, return an empty list
* if the parameter is a single (unicode) value, return a list
containing that value
@@ -182,8 +182,8 @@
"""
if form is None:
form = self.form
- return list_form_param(form, param, pop)
-
+ return list_form_param(form, param, pop)
+
def reset_headers(self):
"""used by AutomaticWebTest to clear html headers between tests on
@@ -193,11 +193,11 @@
return self
# web state helpers #######################################################
-
+
def set_message(self, msg):
assert isinstance(msg, unicode)
self.message = msg
-
+
def update_search_state(self):
"""update the current search state"""
searchstate = self.form.get('__mode')
@@ -247,7 +247,7 @@
def register_onetime_callback(self, func, *args):
cbname = 'cb_%s' % (
sha.sha('%s%s%s%s' % (time.time(), func.__name__,
- random.random(),
+ random.random(),
self.user.login)).hexdigest())
def _cb(req):
try:
@@ -255,12 +255,12 @@
except TypeError:
from warnings import warn
warn('user callback should now take request as argument')
- ret = func(*args)
+ ret = func(*args)
self.unregister_callback(self.pageid, cbname)
return ret
self.set_page_data(cbname, _cb)
return cbname
-
+
def unregister_callback(self, pageid, cbname):
assert pageid is not None
assert cbname.startswith('cb_')
@@ -273,9 +273,9 @@
callbacks = [key for key in sessdata if key.startswith('cb_')]
for callback in callbacks:
self.del_session_data(callback)
-
+
# web edition helpers #####################################################
-
+
@cached # so it's writed only once
def fckeditor_config(self):
self.add_js('fckeditor/fckeditor.js')
@@ -330,7 +330,7 @@
print eid, params
raise RequestError(self._('missing parameters for entity %s') % eid)
return params
-
+
def get_pending_operations(self, entity, relname, role):
operations = {'insert' : [], 'delete' : []}
for optype in ('insert', 'delete'):
@@ -342,7 +342,7 @@
if role == 'object' and entity.eid == eidto:
operations[optype].append(eidfrom)
return operations
-
+
def get_pending_inserts(self, eid=None):
"""shortcut to access req's pending_insert entry
@@ -377,7 +377,7 @@
"""
self.del_session_data(errorurl)
self.remove_pending_operations()
-
+
# high level methods for HTTP headers management ##########################
# must be cached since login/password are popped from the form dictionary
@@ -395,7 +395,7 @@
return None, None
else:
return self.header_authorization()
-
+
def get_cookie(self):
"""retrieve request cookies, returns an empty cookie if not found"""
try:
@@ -423,7 +423,7 @@
morsel['Max-Age'] = 0
# The only way to set up cookie age for IE is to use an old "expired"
# syntax. IE doesn't support Max-Age there is no library support for
- # managing
+ # managing
# ===> Do _NOT_ comment this line :
morsel['expires'] = 'Thu, 01-Jan-1970 00:00:00 GMT'
self.add_header('Set-Cookie', morsel.OutputString())
@@ -476,9 +476,9 @@
if localfile:
cssfile = self.datadir_url + cssfile
add_css(cssfile, media)
-
+
# urls/path management ####################################################
-
+
def url(self, includeparams=True):
"""return currently accessed url"""
return self.base_url() + self.relative_path(includeparams)
@@ -486,7 +486,7 @@
def _datadir_url(self):
"""return url of the application's data directory"""
return self.base_url() + 'data%s/' % self.vreg.config.instance_md5_version()
-
+
def selected(self, url):
"""return True if the url is equivalent to currently accessed url"""
reqpath = self.relative_path().lower()
@@ -502,7 +502,7 @@
def base_url_path(self):
"""returns the absolute path of the base url"""
return urlsplit(self.base_url())[2]
-
+
@cached
def from_controller(self):
"""return the id (string) of the controller issuing the request"""
@@ -512,7 +512,7 @@
if controller in registered_controllers:
return controller
return 'view'
-
+
def external_resource(self, rid, default=_MARKER):
"""return a path to an external resource, using its identifier
@@ -541,9 +541,9 @@
self._validate_cache()
if self.http_method() == 'HEAD':
raise StatusResponse(200, '')
-
+
# abstract methods to override according to the web front-end #############
-
+
def http_method(self):
"""returns 'POST', 'GET', 'HEAD', etc."""
raise NotImplementedError()
@@ -553,7 +553,7 @@
exists and is still usable
"""
raise NotImplementedError()
-
+
def relative_path(self, includeparams=True):
"""return the normalized path of the request (ie at least relative
to the application's root, but some other normalization may be needed
@@ -577,11 +577,11 @@
def add_header(self, header, value):
"""add an output HTTP header"""
raise NotImplementedError()
-
+
def remove_header(self, header):
"""remove an output HTTP header"""
raise NotImplementedError()
-
+
def header_authorization(self):
"""returns a couple (auth-type, auth-value)"""
auth = self.get_header("Authorization", None)
@@ -619,21 +619,21 @@
mx date time value (GMT), else return None
"""
raise NotImplementedError()
-
+
# page data management ####################################################
def get_page_data(self, key, default=None):
"""return value associated to `key` in curernt page data"""
page_data = self.cnx.get_session_data(self.pageid, {})
return page_data.get(key, default)
-
+
def set_page_data(self, key, value):
"""set value associated to `key` in current page data"""
self.html_headers.add_unload_pagedata()
page_data = self.cnx.get_session_data(self.pageid, {})
page_data[key] = value
return self.cnx.set_session_data(self.pageid, page_data)
-
+
def del_page_data(self, key=None):
"""remove value associated to `key` in current page data
if `key` is None, all page data will be cleared
@@ -654,7 +654,7 @@
def ie_browser(self):
useragent = self.useragent()
return useragent and 'MSIE' in useragent
-
+
def xhtml_browser(self):
useragent = self.useragent()
# * MSIE/Konqueror does not support xml content-type
--- a/web/test/unittest_views_basecontrollers.py Wed Apr 22 16:56:03 2009 +0200
+++ b/web/test/unittest_views_basecontrollers.py Wed Apr 22 16:56:19 2009 +0200
@@ -11,7 +11,7 @@
from cubicweb.common.uilib import rql_for_eid
from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect, RequestError
-from cubicweb.web.views.basecontrollers import xmlize
+from cubicweb.web.views.basecontrollers import xhtml_wrap
from cubicweb.entities.authobjs import CWUser
@@ -20,25 +20,25 @@
def setUp(self):
ControllerTC.setUp(self)
self.failUnless('users' in self.schema.eschema('CWGroup').get_groups('read'))
-
+
def tearDown(self):
ControllerTC.tearDown(self)
self.failUnless('users' in self.schema.eschema('CWGroup').get_groups('read'))
-
+
def test_noparam_edit(self):
"""check behaviour of this controller without any form parameter
"""
-
+
self.req.form = {}
self.assertRaises(ValidationError, self.publish, self.req)
-
+
def test_validation_unique(self):
"""test creation of two linked entities
- """
+ """
user = self.user()
self.req.form = {'eid': 'X', '__type:X': 'CWUser',
- 'login:X': u'admin', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
+ 'login:X': u'admin', 'edits-login:X': u'',
+ 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
}
self.assertRaises(ValidationError, self.publish, self.req)
@@ -117,23 +117,23 @@
self.assertEquals([g.eid for g in e.in_group], groupeids)
stateeids = [eid for eid, in self.execute('State S WHERE S name "activated"')]
self.assertEquals([s.eid for s in e.in_state], stateeids)
-
-
+
+
def test_create_multiple_linked(self):
gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
self.req.form = {'eid': ['X', 'Y'],
-
+
'__type:X': 'CWUser',
'__maineid' : 'X',
- 'login:X': u'adim', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
+ 'login:X': u'adim', 'edits-login:X': u'',
+ 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
'surname:X': u'Di Mascio', 'edits-surname:X': '',
- 'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
-
+ 'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
+
'__type:Y': 'EmailAddress',
'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
- 'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
+ 'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
}
path, params = self.expect_redirect_publish()
# should be redirected on the created person
@@ -142,17 +142,17 @@
self.assertEquals(e.surname, 'Di Mascio')
email = e.use_email[0]
self.assertEquals(email.address, 'dima@logilab.fr')
-
+
def test_edit_multiple_linked(self):
peid = self.create_user('adim').eid
self.req.form = {'eid': [`peid`, 'Y'],
'__type:%s'%peid: 'CWUser',
'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: '',
-
+
'__type:Y': 'EmailAddress',
'address:Y': u'dima@logilab.fr', 'edits-address:Y': '',
'use_email:%s'%peid: 'Y', 'edits-use_email:%s'%peid: INTERNAL_FIELD_VALUE,
-
+
'__redirectrql': 'Any X WHERE X eid %s'%peid,
}
path, params = self.expect_redirect_publish()
@@ -162,14 +162,14 @@
self.assertEquals(e.surname, 'Di Masci')
email = e.use_email[0]
self.assertEquals(email.address, 'dima@logilab.fr')
-
+
emaileid = email.eid
self.req.form = {'eid': [`peid`, `emaileid`],
'__type:%s'%peid: 'CWUser',
'surname:%s'%peid: u'Di Masci', 'edits-surname:%s'%peid: 'Di Masci',
'__type:%s'%emaileid: 'EmailAddress',
'address:%s'%emaileid: u'adim@logilab.fr', 'edits-address:%s'%emaileid: 'dima@logilab.fr',
- 'use_email:%s'%peid: `emaileid`, 'edits-use_email:%s'%peid: `emaileid`,
+ 'use_email:%s'%peid: `emaileid`, 'edits-use_email:%s'%peid: `emaileid`,
'__redirectrql': 'Any X WHERE X eid %s'%peid,
}
path, params = self.expect_redirect_publish()
@@ -180,21 +180,21 @@
email = e.use_email[0]
self.assertEquals(email.address, 'adim@logilab.fr')
-
+
def test_password_confirm(self):
"""test creation of two linked entities
- """
+ """
user = self.user()
self.req.form = {'__cloned_eid:X': user.eid,
'eid': 'X', '__type:X': 'CWUser',
- 'login:X': u'toto', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'edits-upassword:X': u'',
+ 'login:X': u'toto', 'edits-login:X': u'',
+ 'upassword:X': u'toto', 'edits-upassword:X': u'',
}
self.assertRaises(ValidationError, self.publish, self.req)
self.req.form = {'__cloned_eid:X': user.eid,
'eid': 'X', '__type:X': 'CWUser',
- 'login:X': u'toto', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'tutu', 'edits-upassword:X': u'',
+ 'login:X': u'toto', 'edits-login:X': u'',
+ 'upassword:X': u'toto', 'upassword-confirm:X': u'tutu', 'edits-upassword:X': u'',
}
self.assertRaises(ValidationError, self.publish, self.req)
@@ -220,7 +220,7 @@
'described_by_test:X': str(feid), 'edits-described_by_test:X': INTERNAL_FIELD_VALUE,
}
self.expect_redirect_publish()
- # should be redirected on the created
+ # should be redirected on the created
#eid = params['rql'].split()[-1]
e = self.execute('Salesterm X').get_entity(0, 0)
self.assertEquals(e.amount, 10)
@@ -273,7 +273,7 @@
self.assertEquals(rset[0][0], 'FOO')
finally:
del CWUser.custom_login_edit
-
+
def test_redirect_apply_button(self):
redirectrql = rql_for_eid(4012) # whatever
self.req.form = {
@@ -354,13 +354,13 @@
'name:'+`eeetypeeid`: u'CWGroup',
'final:'+`eeetypeeid`: False,
'meta:'+`eeetypeeid`: True,
- 'description:'+`eeetypeeid`: u'users group',
+ 'description:'+`eeetypeeid`: u'users group',
'read_permission:'+`eeetypeeid`: groups,
#
'edits-name:'+`eeetypeeid`: u'CWGroup',
'edits-final:'+`eeetypeeid`: False,
'edits-meta:'+`eeetypeeid`: True,
- 'edits-description:'+`eeetypeeid`: u'users group',
+ 'edits-description:'+`eeetypeeid`: u'users group',
'edits-read_permission:'+`eeetypeeid`: basegroups,
}
try:
@@ -372,7 +372,7 @@
# restore
self.execute('SET X read_permission Y WHERE X name "CWGroup", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
self.commit()
-
+
def test_nonregr_eetype_etype_editing(self):
"""non-regression test checking that a manager user can edit a CWEType entity (CWEType)
"""
@@ -386,13 +386,13 @@
'name:'+`eeetypeeid`: u'CWEType',
'final:'+`eeetypeeid`: False,
'meta:'+`eeetypeeid`: True,
- 'description:'+`eeetypeeid`: u'users group',
+ 'description:'+`eeetypeeid`: u'users group',
'read_permission:'+`eeetypeeid`: groups,
'edits-name:'+`eeetypeeid`: u'CWEType',
'edits-final:'+`eeetypeeid`: False,
'edits-meta:'+`eeetypeeid`: True,
- 'edits-description:'+`eeetypeeid`: u'users group',
+ 'edits-description:'+`eeetypeeid`: u'users group',
'edits-read_permission:'+`eeetypeeid`: basegroups,
}
try:
@@ -404,12 +404,12 @@
# 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
- """
+ """
self.req.form = {
'eid': 'A', '__type:A': 'BlogEntry',
'__maineid' : 'A',
@@ -426,16 +426,16 @@
def test_nonregr_multiple_empty_email_addr(self):
gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
self.req.form = {'eid': ['X', 'Y'],
-
+
'__type:X': 'CWUser',
- 'login:X': u'adim', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
- 'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
-
+ 'login:X': u'adim', 'edits-login:X': u'',
+ 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
+ 'in_group:X': `gueid`, 'edits-in_group:X': INTERNAL_FIELD_VALUE,
+
'__type:Y': 'EmailAddress',
'address:Y': u'', 'edits-address:Y': '',
'alias:Y': u'', 'edits-alias:Y': '',
- 'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
+ 'use_email:X': 'Y', 'edits-use_email:X': INTERNAL_FIELD_VALUE,
}
self.assertRaises(ValidationError, self.publish, self.req)
@@ -444,8 +444,8 @@
self.req.form = {'__cloned_eid:X': user.eid,
'eid': 'X', '__type:X': 'CWUser',
'__maineid' : 'X',
- 'login:X': u'toto', 'edits-login:X': u'',
- 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
+ 'login:X': u'toto', 'edits-login:X': u'',
+ 'upassword:X': u'toto', 'upassword-confirm:X': u'toto', 'edits-upassword:X': u'',
}
path, params = self.expect_redirect_publish()
self.assertEquals(path, 'euser/toto')
@@ -465,7 +465,7 @@
{'p' : p.eid, 'e' : e.eid})
self.req.form = {'__cloned_eid:X': p.eid,
'eid': 'X', '__type:X': 'CWUser',
- 'login': u'dodo', 'edits-login': u'dodo',
+ 'login': u'dodo', 'edits-login': u'dodo',
'surname:X': u'Boom', 'edits-surname:X': u'',
'__errorurl' : "whatever but required",
}
@@ -510,7 +510,7 @@
self.login('anon')
req = self.request()
self.assertRaises(Unauthorized, self.env.app.select_controller, 'sendmail', req)
-
+
class JSONControllerTC(EnvBasedTC):
@@ -530,7 +530,7 @@
ctrl = self.ctrl(self.request(rql='CWUser P WHERE P login "John"',
pageid='123'))
self.assertTextEquals(ctrl.publish(),
- xmlize(self.john.view('primary')))
+ xhtml_wrap(self.john.view('primary')))
def test_json_exec(self):
rql = 'Any T,N WHERE T is Tag, T name N'
@@ -544,7 +544,7 @@
['python', 'cubicweb'])
self.assertEquals(self.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.assertUnorderedIterableEquals([tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
@@ -617,7 +617,7 @@
req.remove_pending_operations()
self.assertEquals(req.get_pending_deletes(), [])
self.assertEquals(req.get_pending_inserts(), [])
-
+
def test_add_inserts(self):
res, req = self.remote_call('add_pending_inserts',
@@ -625,7 +625,7 @@
inserts = req.get_pending_inserts()
self.assertEquals(inserts, ['12:tags:13', '12:tags:14'])
req.remove_pending_operations()
-
+
# silly tests
def test_external_resource(self):
@@ -639,8 +639,8 @@
self.assertEquals(self.remote_call('format_date', '"2007-01-01 12:00:00"')[0],
simplejson.dumps('2007/01/01'))
-
+
-
+
if __name__ == '__main__':
unittest_main()