# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1242647368 -7200 # Node ID f4b5c15d114769accdd81f55b452169e74c56218 # Parent 2cdd0d1d38885eb7aa5722169d73953be1800bf7 test and fix #342997: local eid used for absolute_url of external entities diff -r 2cdd0d1d3888 -r f4b5c15d1147 entity.py --- a/entity.py Mon May 18 13:41:53 2009 +0200 +++ b/entity.py Mon May 18 13:49:28 2009 +0200 @@ -284,6 +284,23 @@ 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 @@ 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)""" diff -r 2cdd0d1d3888 -r f4b5c15d1147 server/test/data/sources_multi --- a/server/test/data/sources_multi Mon May 18 13:41:53 2009 +0200 +++ b/server/test/data/sources_multi Mon May 18 13:49:28 2009 +0200 @@ -14,6 +14,7 @@ cubicweb-user = admin cubicweb-password = gingkow mapping-file = extern_mapping.py +base-url=http://extern.org/ [extern-multi] adapter = pyrorql diff -r 2cdd0d1d3888 -r f4b5c15d1147 server/test/unittest_multisources.py --- a/server/test/unittest_multisources.py Mon May 18 13:41:53 2009 +0200 +++ b/server/test/unittest_multisources.py Mon May 18 13:49:28 2009 +0200 @@ -235,9 +235,21 @@ 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 @@ 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})