Commit 33d0e6d6 authored by sylvain.thenault@logilab.fr's avatar sylvain.thenault@logilab.fr
Browse files

test and fix #342997: local eid used for absolute_url of external entities

--HG--
branch : stable
parent 2cdd0d1d3888
......@@ -284,6 +284,23 @@ class Entity(AppRsetObject, dict):
parents.append(cls.vreg.etype_class('Any'))
return parents
@classmethod
@cached
def _rest_attr_info(cls):
mainattr, needcheck = 'eid', True
if cls.rest_attr:
mainattr = cls.rest_attr
needcheck = not cls.e_schema.has_unique_values(mainattr)
else:
for rschema in cls.e_schema.subject_relations():
if rschema.is_final() and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
mainattr = str(rschema)
needcheck = False
break
if mainattr == 'eid':
needcheck = False
return mainattr, needcheck
def __init__(self, req, rset=None, row=None, col=0):
AppRsetObject.__init__(self, req, rset, row, col)
dict.__init__(self)
......@@ -363,46 +380,36 @@ class Entity(AppRsetObject, dict):
if getattr(self.req, 'search_state', ('normal',))[0] == 'normal':
kwargs['base_url'] = self.metainformation()['source'].get('base-url')
if method is None or method == 'view':
kwargs['_restpath'] = self.rest_path()
kwargs['_restpath'] = self.rest_path(kwargs.get('base_url'))
else:
kwargs['rql'] = 'Any X WHERE X eid %s' % self.eid
return self.build_url(method, **kwargs)
def rest_path(self):
def rest_path(self, use_ext_eid=False):
"""returns a REST-like (relative) path for this entity"""
mainattr, needcheck = self._rest_attr_info()
etype = str(self.e_schema)
if mainattr == 'eid':
value = self.eid
else:
path = etype.lower()
if mainattr != 'eid':
value = getattr(self, mainattr)
if value is None:
return '%s/eid/%s' % (etype.lower(), self.eid)
if needcheck:
# make sure url is not ambiguous
rql = 'Any COUNT(X) WHERE X is %s, X %s %%(value)s' % (etype, mainattr)
if value is not None:
nbresults = self.req.execute(rql, {'value' : value})[0][0]
# may an assertion that nbresults is not 0 would be a good idea
if nbresults != 1: # no ambiguity
return '%s/eid/%s' % (etype.lower(), self.eid)
return '%s/%s' % (etype.lower(), self.req.url_quote(value))
@classmethod
def _rest_attr_info(cls):
mainattr, needcheck = 'eid', True
if cls.rest_attr:
mainattr = cls.rest_attr
needcheck = not cls.e_schema.has_unique_values(mainattr)
else:
for rschema in cls.e_schema.subject_relations():
if rschema.is_final() and rschema != 'eid' and cls.e_schema.has_unique_values(rschema):
mainattr = str(rschema)
needcheck = False
break
mainattr = 'eid'
path += '/eid'
elif needcheck:
# make sure url is not ambiguous
rql = 'Any COUNT(X) WHERE X is %s, X %s %%(value)s' % (
etype, mainattr)
if value is not None:
nbresults = self.req.execute(rql, {'value' : value})[0][0]
if nbresults != 1: # ambiguity?
mainattr = 'eid'
path += '/eid'
if mainattr == 'eid':
needcheck = False
return mainattr, needcheck
if use_ext_eid:
value = self.metainformation()['extid']
else:
value = self.eid
return '%s/%s' % (path, self.req.url_quote(value))
def attr_metadata(self, attr, metadata):
"""return a metadata for an attribute (None if unspecified)"""
......
......@@ -14,6 +14,7 @@ pyro-ns-id = extern
cubicweb-user = admin
cubicweb-password = gingkow
mapping-file = extern_mapping.py
base-url=http://extern.org/
[extern-multi]
adapter = pyrorql
......
......@@ -235,9 +235,21 @@ class TwoSourcesTC(RepositoryBasedTC):
states.remove((aff1stateeid, aff1statename))
notstates = set(tuple(x) for x in self.execute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s',
{'x': aff1}, 'x'))
self.set_debug(False)
self.assertSetEquals(notstates, states)
def test_absolute_url_base_url(self):
ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0]
cnx2.commit()
lc = self.execute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0)
self.assertEquals(lc.absolute_url(), 'http://extern.org/card/eid/%s' % ceid)
def test_absolute_url_no_base_url(self):
cu = cnx3.cursor()
ceid = cu.execute('INSERT Card X: X title "without wikiid to get eid based url"')[0][0]
cnx3.commit()
lc = self.execute('Card X WHERE X title "without wikiid to get eid based url"').get_entity(0, 0)
self.assertEquals(lc.absolute_url(), 'http://testing.fr/cubicweb/card/eid/%s' % lc.eid)
def test_nonregr1(self):
ueid = self.session.user.eid
affaire = self.execute('Affaire X WHERE X ref "AFFREF"').get_entity(0, 0)
......@@ -251,7 +263,6 @@ class TwoSourcesTC(RepositoryBasedTC):
self.assertEquals(len(rset), 1)
self.assertEquals(rset.rows[0], [self.session.user.eid])
def test_nonregr3(self):
self.execute('DELETE Card X WHERE X eid %(x)s, NOT X multisource_inlined_rel Y', {'x': self.ic1})
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment