You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2015/11/25 20:37:59 UTC

[05/17] allura git commit: [#7999] ticket:861 Improve url parsing logic

[#7999] ticket:861 Improve url parsing logic


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/9fd62fba
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/9fd62fba
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/9fd62fba

Branch: refs/heads/master
Commit: 9fd62fba77798b97e1aa292634303397d704dd84
Parents: f1d134f
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Nov 18 13:54:58 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Nov 25 14:37:42 2015 -0500

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py        | 27 ++++++++++++-----
 Allura/allura/tests/test_plugin.py | 52 +++++++++++++++++++++++++++------
 2 files changed, 63 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/9fd62fba/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 91c926f..f100ad2 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -1049,18 +1049,31 @@ class ProjectRegistrationProvider(object):
         ]
 
     def project_from_url(self, url):
-        '''Return pair where (n, p) parsed from project url
-        where n is neighborhood's url_prefix and p is project's shortname
+        '''Returns a tuple (project, error).
 
-        Return None if url can't be parsed
+        Where project is the Project instane parsed from url or None if project
+        can't be parsed. In that case error will be a string describing the error.
         '''
+        from allura.model import Project, Neighborhood
         if url is None:
-            return None
+            return None, u'Empty url'
         url = urlparse(url)
         url = [u for u in url.path.split('/') if u]
-        if len(url) < 2:
-            return None
-        return (u'/{}/'.format(url[0]), url[1])
+        if len(url) == 0:
+            return None, u'Empty url'
+        if len(url) == 1:
+            q = Project.query.find(dict(shortname=url[0]))
+            cnt = q.count()
+            if cnt == 0:
+                return None, u'Project not found'
+            if cnt == 1:
+                return q.first(), None
+            return None, u'Too many matches for project: {}'.format(cnt)
+        n = Neighborhood.query.get(url_prefix=u'/{}/'.format(url[0]))
+        if not n:
+            return None, u'Neighborhood not found'
+        p = Project.query.get(neighborhood_id=n._id, shortname=url[1])
+        return (p, u'Project not found' if p is None else None)
 
 
 class ThemeProvider(object):

http://git-wip-us.apache.org/repos/asf/allura/blob/9fd62fba/Allura/allura/tests/test_plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index ec20288..b9ee17c 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -89,15 +89,48 @@ class TestProjectRegistrationProvider(object):
         Project.query.get.return_value = Mock()
         assert_raises(ProjectConflict, v, 'thisislegit', neighborhood=nbhd)
 
-    def test_project_from_url(self):
-        parse = self.provider.project_from_url
-        assert_is_none(parse(None))
-        assert_is_none(parse(''))
-        assert_is_none(parse('/p/'))
-        assert_equal(('/p/', 'test'), parse('/p/test/'))
-        assert_equal(('/p/', 'test'), parse('/p/test/tickets/1'))
-        assert_equal(('/adobe/', 'adobe-1'), parse('/adobe/adobe-1'))
-        assert_equal(('/p/', 'test'), parse('http://localhost:8080/p/test/wiki'))
+
+class TestProjectRegistrationProviderParseProjectFromUrl(object):
+
+    def setUp(self):
+        setup_basic_test()
+        ThreadLocalORMSession.close_all()
+        setup_global_objects()
+        self.provider = ProjectRegistrationProvider()
+        self.parse = self.provider.project_from_url
+
+    def test_empty_url(self):
+        assert_equal((None, u'Empty url'), self.parse(None))
+        assert_equal((None, u'Empty url'), self.parse(''))
+        assert_equal((None, u'Empty url'), self.parse('/'))
+
+    def test_neighborhood_not_found(self):
+        assert_equal((None, u'Neighborhood not found'), self.parse('/nbhd/project'))
+
+    def test_project_not_found(self):
+        assert_equal((None, u'Project not found'), self.parse('/p/project'))
+        assert_equal((None, u'Project not found'), self.parse('project'))
+
+    def test_ok_full(self):
+        p = M.Project.query.get(shortname='test')
+        adobe = M.Project.query.get(shortname='adobe-1')
+        assert_equal((p, None), self.parse('p/test'))
+        assert_equal((p, None), self.parse('/p/test'))
+        assert_equal((p, None), self.parse('/p/test/tickets/1'))
+        assert_equal((p, None), self.parse('http://localhost:8080/p/test/tickets/1'))
+        assert_equal((adobe, None), self.parse('/adobe/adobe-1/'))
+
+    def test_only_shortname_multiple_projects_matched(self):
+        adobe_n = M.Neighborhood.query.get(url_prefix='/adobe/')
+        M.Project(shortname='test', neighborhood_id=adobe_n._id)
+        ThreadLocalORMSession.flush_all()
+        assert_equal((None, u'Too many matches for project: 2'), self.parse('test'))
+
+    def test_only_shortname_ok(self):
+        p = M.Project.query.get(shortname='test')
+        adobe = M.Project.query.get(shortname='adobe-1')
+        assert_equal((p, None), self.parse('test'))
+        assert_equal((adobe, None), self.parse('adobe-1'))
 
 
 class UserMock(object):
@@ -395,6 +428,7 @@ class TestLocalAuthenticationProvider(object):
             ThreadLocalORMSession.flush_all()
         assert_equal(user.disabled, True)
 
+
 class TestAuthenticationProvider(object):
 
     def setUp(self):