|
1 # -*- coding: utf-8 -*- |
|
2 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
3 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
4 # |
|
5 # This file is part of CubicWeb. |
|
6 # |
|
7 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
8 # terms of the GNU Lesser General Public License as published by the Free |
|
9 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
10 # any later version. |
|
11 # |
|
12 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
13 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
14 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
15 # details. |
|
16 # |
|
17 # You should have received a copy of the GNU Lesser General Public License along |
|
18 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
19 """Unit tests for url publishing service""" |
|
20 |
|
21 import re |
|
22 |
|
23 from logilab.common.testlib import unittest_main |
|
24 |
|
25 from cubicweb.rset import ResultSet |
|
26 from cubicweb.devtools.testlib import CubicWebTC |
|
27 from cubicweb.devtools.fake import FakeRequest |
|
28 from cubicweb.web import NotFound, Redirect, views |
|
29 from cubicweb.web.views.urlrewrite import SimpleReqRewriter |
|
30 |
|
31 |
|
32 class URLPublisherTC(CubicWebTC): |
|
33 """test suite for QSPreProcessor""" |
|
34 |
|
35 def setup_database(self): |
|
36 with self.admin_access.repo_cnx() as cnx: |
|
37 self.create_user(cnx, u'ÿsaÿe') |
|
38 b = cnx.create_entity('BlogEntry', title=u'hell\'o', content=u'blabla') |
|
39 # take care: Tag's name normalized to lower case |
|
40 c = cnx.create_entity('Tag', name=u'yo') |
|
41 cnx.execute('SET C tags B WHERE C eid %(c)s, B eid %(b)s', |
|
42 {'c':c.eid, 'b':b.eid}) |
|
43 cnx.commit() |
|
44 |
|
45 def process(self, req, url): |
|
46 return self.app.url_resolver.process(req, url) |
|
47 |
|
48 def test_raw_path(self): |
|
49 """tests raw path resolution'""" |
|
50 with self.admin_access.web_request() as req: |
|
51 self.assertEqual(self.process(req, 'view'), ('view', None)) |
|
52 self.assertEqual(self.process(req, 'edit'), ('edit', None)) |
|
53 self.assertRaises(NotFound, self.process, req, 'whatever') |
|
54 |
|
55 def test_eid_path(self): |
|
56 """tests eid path resolution""" |
|
57 with self.admin_access.web_request() as req: |
|
58 self.assertIsInstance(self.process(req, '123')[1], ResultSet) |
|
59 self.assertEqual(len(self.process(req, '123')[1]), 1) |
|
60 self.assertRaises(NotFound, self.process, req, '123/345') |
|
61 self.assertRaises(NotFound, self.process, req, 'not_eid') |
|
62 |
|
63 def test_rest_path_etype(self): |
|
64 """tests the rest path resolution""" |
|
65 with self.admin_access.web_request() as req: |
|
66 ctrl, rset = self.process(req, 'CWEType') |
|
67 self.assertEqual(ctrl, 'view') |
|
68 self.assertEqual(rset.description[0][0], 'CWEType') |
|
69 self.assertEqual("Any X,AA,AB ORDERBY AB WHERE X is_instance_of CWEType, " |
|
70 "X modification_date AA, X name AB", |
|
71 rset.printable_rql()) |
|
72 self.assertEqual(req.form['vid'], 'sameetypelist') |
|
73 |
|
74 def test_rest_path_by_attr(self): |
|
75 with self.admin_access.web_request() as req: |
|
76 ctrl, rset = self.process(req, 'CWUser/login/admin') |
|
77 self.assertEqual(ctrl, 'view') |
|
78 self.assertEqual(len(rset), 1) |
|
79 self.assertEqual(rset.description[0][0], 'CWUser') |
|
80 self.assertEqual('Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, ' |
|
81 'X firstname AA, X login AB, X modification_date AC, ' |
|
82 'X surname AD, X login "admin"', |
|
83 rset.printable_rql()) |
|
84 |
|
85 def test_rest_path_unique_attr(self): |
|
86 with self.admin_access.web_request() as req: |
|
87 ctrl, rset = self.process(req, 'cwuser/admin') |
|
88 self.assertEqual(ctrl, 'view') |
|
89 self.assertEqual(len(rset), 1) |
|
90 self.assertEqual(rset.description[0][0], 'CWUser') |
|
91 self.assertEqual('Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, ' |
|
92 'X firstname AA, X login AB, X modification_date AC, ' |
|
93 'X surname AD, X login "admin"', |
|
94 rset.printable_rql()) |
|
95 self.assertEqual(req.form['vid'], 'primary') |
|
96 |
|
97 def test_rest_path_eid(self): |
|
98 with self.admin_access.web_request() as req: |
|
99 ctrl, rset = self.process(req, 'cwuser/eid/%s' % req.user.eid) |
|
100 self.assertEqual(ctrl, 'view') |
|
101 self.assertEqual(len(rset), 1) |
|
102 self.assertEqual(rset.description[0][0], 'CWUser') |
|
103 self.assertEqual('Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, ' |
|
104 'X firstname AA, X login AB, X modification_date AC, ' |
|
105 'X surname AD, X eid %s' % rset[0][0], |
|
106 rset.printable_rql()) |
|
107 |
|
108 def test_rest_path_non_ascii_paths(self): |
|
109 with self.admin_access.web_request() as req: |
|
110 ctrl, rset = self.process(req, 'CWUser/login/%C3%BFsa%C3%BFe') |
|
111 self.assertEqual(ctrl, 'view') |
|
112 self.assertEqual(len(rset), 1) |
|
113 self.assertEqual(rset.description[0][0], 'CWUser') |
|
114 self.assertEqual(u'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, ' |
|
115 u'X firstname AA, X login AB, X modification_date AC, ' |
|
116 u'X surname AD, X login "\xffsa\xffe"', |
|
117 rset.printable_rql()) |
|
118 |
|
119 def test_rest_path_quoted_paths(self): |
|
120 with self.admin_access.web_request() as req: |
|
121 ctrl, rset = self.process(req, 'BlogEntry/title/hell%27o') |
|
122 self.assertEqual(ctrl, 'view') |
|
123 self.assertEqual(len(rset), 1) |
|
124 self.assertEqual(rset.description[0][0], 'BlogEntry') |
|
125 self.assertEqual(u'Any X,AA,AB,AC WHERE X is_instance_of BlogEntry, ' |
|
126 'X creation_date AA, X modification_date AB, X title AC, ' |
|
127 'X title "hell\'o"', |
|
128 rset.printable_rql()) |
|
129 |
|
130 def test_rest_path_use_vid_from_rset(self): |
|
131 with self.admin_access.web_request(headers={'Accept': 'application/rdf+xml'}) as req: |
|
132 views.VID_BY_MIMETYPE['application/rdf+xml'] = 'rdf' |
|
133 try: |
|
134 ctrl, rset = self.process(req, 'CWEType') |
|
135 finally: |
|
136 views.VID_BY_MIMETYPE.pop('application/rdf+xml') |
|
137 self.assertEqual(req.form['vid'], 'rdf') |
|
138 |
|
139 def test_rest_path_errors(self): |
|
140 with self.admin_access.web_request() as req: |
|
141 self.assertRaises(NotFound, self.process, req, 'CWUser/eid/30000') |
|
142 self.assertRaises(NotFound, self.process, req, 'Workcases') |
|
143 self.assertRaises(NotFound, self.process, req, 'CWUser/inexistant_attribute/joe') |
|
144 |
|
145 def test_action_path(self): |
|
146 """tests the action path resolution""" |
|
147 with self.admin_access.web_request() as req: |
|
148 self.assertRaises(Redirect, self.process, req, '1/edit') |
|
149 self.assertRaises(Redirect, self.process, req, 'Tag/name/yo/edit') |
|
150 self.assertRaises(Redirect, self.process, req, 'Tag/yo/edit') |
|
151 self.assertRaises(NotFound, self.process, req, 'view/edit') |
|
152 self.assertRaises(NotFound, self.process, req, '1/non_action') |
|
153 self.assertRaises(NotFound, self.process, req, 'CWUser/login/admin/non_action') |
|
154 |
|
155 def test_regexp_path(self): |
|
156 """tests the regexp path resolution""" |
|
157 with self.admin_access.web_request() as req: |
|
158 ctrl, rset = self.process(req, 'add/Task') |
|
159 self.assertEqual(ctrl, 'view') |
|
160 self.assertEqual(rset, None) |
|
161 self.assertEqual(req.form, {'etype': "Task", 'vid': "creation"}) |
|
162 self.assertRaises(NotFound, self.process, req, 'add/foo/bar') |
|
163 |
|
164 def test_nonascii_path(self): |
|
165 oldrules = SimpleReqRewriter.rules |
|
166 SimpleReqRewriter.rules = [(re.compile('/\w+', re.U), dict(vid='foo'))] |
|
167 with self.admin_access.web_request() as req: |
|
168 try: |
|
169 path = str(FakeRequest().url_quote(u'été')) |
|
170 ctrl, rset = self.process(req, path) |
|
171 self.assertEqual(rset, None) |
|
172 self.assertEqual(req.form, {'vid': "foo"}) |
|
173 finally: |
|
174 SimpleReqRewriter.rules = oldrules |
|
175 |
|
176 |
|
177 if __name__ == '__main__': |
|
178 unittest_main() |