test and fix #342997: local eid used for absolute_url of external entities stable
authorsylvain.thenault@logilab.fr
Mon, 18 May 2009 13:49:28 +0200
branchstable
changeset 1840 f4b5c15d1147
parent 1839 2cdd0d1d3888
child 1841 d629a6fc33e5
test and fix #342997: local eid used for absolute_url of external entities
entity.py
server/test/data/sources_multi
server/test/unittest_multisources.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)"""
--- 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
--- 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})