1 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 """unittests for cw.devtools.testlib module""" |
|
19 |
|
20 from io import BytesIO, StringIO |
|
21 from unittest import TextTestRunner |
|
22 |
|
23 from six import PY2 |
|
24 |
|
25 from logilab.common.testlib import TestSuite, TestCase, unittest_main |
|
26 from logilab.common.registry import yes |
|
27 |
|
28 from cubicweb.devtools import htmlparser |
|
29 from cubicweb.devtools.testlib import CubicWebTC |
|
30 from cubicweb.pytestconf import clean_repo_test_cls |
|
31 |
|
32 class FakeFormTC(TestCase): |
|
33 def test_fake_form(self): |
|
34 class entity: |
|
35 cw_etype = 'Entity' |
|
36 eid = 0 |
|
37 sio = BytesIO(b'hop\n') |
|
38 form = CubicWebTC.fake_form('import', |
|
39 {'file': ('filename.txt', sio), |
|
40 'encoding': u'utf-8', |
|
41 }, [(entity, {'field': 'value'})]) |
|
42 self.assertEqual(form, {'__form_id': 'import', |
|
43 '__maineid': 0, |
|
44 '__type:0': 'Entity', |
|
45 '_cw_entity_fields:0': '__type,field', |
|
46 '_cw_fields': 'encoding,file', |
|
47 'eid': [0], |
|
48 'encoding': u'utf-8', |
|
49 'field:0': 'value', |
|
50 'file': ('filename.txt', sio)}) |
|
51 |
|
52 class WebTestTC(TestCase): |
|
53 |
|
54 def setUp(self): |
|
55 output = BytesIO() if PY2 else StringIO() |
|
56 self.runner = TextTestRunner(stream=output) |
|
57 |
|
58 def test_error_raised(self): |
|
59 class MyWebTest(CubicWebTC): |
|
60 |
|
61 def test_error_view(self): |
|
62 with self.admin_access.web_request() as req: |
|
63 req.create_entity('Bug', title=u"bt") |
|
64 self.view('raising', req.execute('Bug B'), template=None, req=req) |
|
65 |
|
66 def test_correct_view(self): |
|
67 with self.admin_access.web_request() as req: |
|
68 self.view('primary', req.execute('CWUser U'), template=None, req=req) |
|
69 |
|
70 tests = [MyWebTest('test_error_view'), MyWebTest('test_correct_view')] |
|
71 result = self.runner.run(TestSuite(tests)) |
|
72 self.assertEqual(result.testsRun, 2) |
|
73 self.assertEqual(len(result.errors), 0) |
|
74 self.assertEqual(len(result.failures), 1) |
|
75 clean_repo_test_cls(MyWebTest) |
|
76 |
|
77 |
|
78 class RepoInstancesConsistencyTC(CubicWebTC): |
|
79 test_db_id = 'RepoInstancesConsistencyTC' |
|
80 |
|
81 def pre_setup_database(self, cnx, config): |
|
82 self.assertIs(cnx.repo, config.repository()) |
|
83 |
|
84 def test_pre_setup(self): |
|
85 pass |
|
86 |
|
87 |
|
88 HTML_PAGE = u"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
89 <html> |
|
90 <head><title>need a title</title></head> |
|
91 <body> |
|
92 <h1>Hello World !</h1> |
|
93 </body> |
|
94 </html> |
|
95 """ |
|
96 |
|
97 HTML_PAGE2 = u"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
98 <html> |
|
99 <head><title>need a title</title></head> |
|
100 <body> |
|
101 <h1>Test</h1> |
|
102 <h1>Hello <a href="http://www.google.com">world</a> !</h1> |
|
103 <h2>h2 title</h2> |
|
104 <h3>h3 title</h3> |
|
105 <h2>antoher h2 title</h2> |
|
106 <h4>h4 title</h4> |
|
107 <p><a href="http://www.logilab.org">Logilab</a> introduces CW !</p> |
|
108 </body> |
|
109 </html> |
|
110 """ |
|
111 |
|
112 HTML_PAGE_ERROR = u"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
113 <html> |
|
114 <head><title>need a title</title></head> |
|
115 <body> |
|
116 Logilab</a> introduces CW ! |
|
117 </body> |
|
118 </html> |
|
119 """ |
|
120 |
|
121 HTML_NON_STRICT = u"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
122 <html> |
|
123 <head><title>need a title</title></head> |
|
124 <body> |
|
125 <h1><a href="something.com">title</h1> |
|
126 </body> |
|
127 </html> |
|
128 """ |
|
129 |
|
130 |
|
131 class HTMLPageInfoTC(TestCase): |
|
132 """test cases for PageInfo""" |
|
133 |
|
134 def setUp(self): |
|
135 parser = htmlparser.HTMLValidator() |
|
136 # disable cleanup that would remove doctype |
|
137 parser.preprocess_data = lambda data: data |
|
138 self.page_info = parser.parse_string(HTML_PAGE2) |
|
139 |
|
140 def test_source1(self): |
|
141 """make sure source is stored correctly""" |
|
142 self.assertEqual(self.page_info.source, HTML_PAGE2) |
|
143 |
|
144 def test_source2(self): |
|
145 """make sure source is stored correctly - raise exception""" |
|
146 parser = htmlparser.DTDValidator() |
|
147 self.assertRaises(AssertionError, parser.parse_string, HTML_PAGE_ERROR) |
|
148 |
|
149 def test_has_title_no_level(self): |
|
150 """tests h? tags information""" |
|
151 self.assertEqual(self.page_info.has_title('Test'), True) |
|
152 self.assertEqual(self.page_info.has_title('Test '), False) |
|
153 self.assertEqual(self.page_info.has_title('Tes'), False) |
|
154 self.assertEqual(self.page_info.has_title('Hello world !'), True) |
|
155 |
|
156 def test_has_title_level(self): |
|
157 """tests h? tags information""" |
|
158 self.assertEqual(self.page_info.has_title('Test', level = 1), True) |
|
159 self.assertEqual(self.page_info.has_title('Test', level = 2), False) |
|
160 self.assertEqual(self.page_info.has_title('Test', level = 3), False) |
|
161 self.assertEqual(self.page_info.has_title('Test', level = 4), False) |
|
162 self.assertRaises(IndexError, self.page_info.has_title, 'Test', level = 5) |
|
163 |
|
164 def test_has_title_regexp_no_level(self): |
|
165 """tests has_title_regexp() with no particular level specified""" |
|
166 self.assertEqual(self.page_info.has_title_regexp('h[23] title'), True) |
|
167 |
|
168 def test_has_title_regexp_level(self): |
|
169 """tests has_title_regexp() with a particular level specified""" |
|
170 self.assertEqual(self.page_info.has_title_regexp('h[23] title', 2), True) |
|
171 self.assertEqual(self.page_info.has_title_regexp('h[23] title', 3), True) |
|
172 self.assertEqual(self.page_info.has_title_regexp('h[23] title', 4), False) |
|
173 |
|
174 def test_appears(self): |
|
175 """tests PageInfo.appears()""" |
|
176 self.assertEqual(self.page_info.appears('CW'), True) |
|
177 self.assertEqual(self.page_info.appears('Logilab'), True) |
|
178 self.assertEqual(self.page_info.appears('Logilab introduces'), True) |
|
179 self.assertEqual(self.page_info.appears('H2 title'), False) |
|
180 |
|
181 def test_has_link(self): |
|
182 """tests has_link()""" |
|
183 self.assertEqual(self.page_info.has_link('Logilab'), True) |
|
184 self.assertEqual(self.page_info.has_link('logilab'), False) |
|
185 self.assertEqual(self.page_info.has_link('Logilab', 'http://www.logilab.org'), True) |
|
186 self.assertEqual(self.page_info.has_link('Logilab', 'http://www.google.com'), False) |
|
187 |
|
188 def test_has_link_regexp(self): |
|
189 """test has_link_regexp()""" |
|
190 self.assertEqual(self.page_info.has_link_regexp('L[oi]gilab'), True) |
|
191 self.assertEqual(self.page_info.has_link_regexp('L[ai]gilab'), False) |
|
192 |
|
193 |
|
194 class CWUtilitiesTC(CubicWebTC): |
|
195 |
|
196 def test_temporary_permissions_eschema(self): |
|
197 eschema = self.schema['CWUser'] |
|
198 with self.temporary_permissions(CWUser={'read': ()}): |
|
199 self.assertEqual(eschema.permissions['read'], ()) |
|
200 self.assertTrue(eschema.permissions['add']) |
|
201 self.assertTrue(eschema.permissions['read'], ()) |
|
202 |
|
203 def test_temporary_permissions_rdef(self): |
|
204 rdef = self.schema['CWUser'].rdef('in_group') |
|
205 with self.temporary_permissions((rdef, {'read': ()})): |
|
206 self.assertEqual(rdef.permissions['read'], ()) |
|
207 self.assertTrue(rdef.permissions['add']) |
|
208 self.assertTrue(rdef.permissions['read'], ()) |
|
209 |
|
210 def test_temporary_permissions_rdef_with_exception(self): |
|
211 rdef = self.schema['CWUser'].rdef('in_group') |
|
212 try: |
|
213 with self.temporary_permissions((rdef, {'read': ()})): |
|
214 self.assertEqual(rdef.permissions['read'], ()) |
|
215 self.assertTrue(rdef.permissions['add']) |
|
216 raise ValueError('goto') |
|
217 except ValueError: |
|
218 self.assertTrue(rdef.permissions['read'], ()) |
|
219 else: |
|
220 self.fail('exception was caught unexpectedly') |
|
221 |
|
222 def test_temporary_appobjects_registered(self): |
|
223 |
|
224 class AnAppobject(object): |
|
225 __registries__ = ('hip',) |
|
226 __regid__ = 'hop' |
|
227 __select__ = yes() |
|
228 registered = None |
|
229 |
|
230 @classmethod |
|
231 def __registered__(cls, reg): |
|
232 cls.registered = reg |
|
233 |
|
234 with self.temporary_appobjects(AnAppobject): |
|
235 self.assertEqual(self.vreg['hip'], AnAppobject.registered) |
|
236 self.assertIn(AnAppobject, self.vreg['hip']['hop']) |
|
237 self.assertNotIn(AnAppobject, self.vreg['hip']['hop']) |
|
238 |
|
239 def test_login(self): |
|
240 """Calling login should not break hook control""" |
|
241 with self.admin_access.repo_cnx() as cnx: |
|
242 self.hook_executed = False |
|
243 self.create_user(cnx, 'babar') |
|
244 cnx.commit() |
|
245 |
|
246 from cubicweb.server import hook |
|
247 from cubicweb.predicates import is_instance |
|
248 |
|
249 class MyHook(hook.Hook): |
|
250 __regid__ = 'whatever' |
|
251 __select__ = hook.Hook.__select__ & is_instance('CWProperty') |
|
252 category = 'test-hook' |
|
253 events = ('after_add_entity',) |
|
254 test = self |
|
255 |
|
256 def __call__(self): |
|
257 self.test.hook_executed = True |
|
258 |
|
259 with self.new_access('babar').repo_cnx() as cnx: |
|
260 with self.temporary_appobjects(MyHook): |
|
261 with cnx.allow_all_hooks_but('test-hook'): |
|
262 prop = cnx.create_entity('CWProperty', pkey=u'ui.language', value=u'en') |
|
263 cnx.commit() |
|
264 self.assertFalse(self.hook_executed) |
|
265 |
|
266 |
|
267 class RepoAccessTC(CubicWebTC): |
|
268 |
|
269 def test_repo_connection(self): |
|
270 acc = self.new_access('admin') |
|
271 with acc.repo_cnx() as cnx: |
|
272 rset = cnx.execute('Any X WHERE X is CWUser') |
|
273 self.assertTrue(rset) |
|
274 |
|
275 def test_client_connection(self): |
|
276 acc = self.new_access('admin') |
|
277 with acc.client_cnx() as cnx: |
|
278 rset = cnx.execute('Any X WHERE X is CWUser') |
|
279 self.assertTrue(rset) |
|
280 |
|
281 def test_web_request(self): |
|
282 acc = self.new_access('admin') |
|
283 with acc.web_request(elephant='babar') as req: |
|
284 rset = req.execute('Any X WHERE X is CWUser') |
|
285 self.assertTrue(rset) |
|
286 self.assertEqual('babar', req.form['elephant']) |
|
287 |
|
288 def test_close(self): |
|
289 acc = self.new_access('admin') |
|
290 acc.close() |
|
291 |
|
292 def test_admin_access(self): |
|
293 with self.admin_access.client_cnx() as cnx: |
|
294 self.assertEqual('admin', cnx.user.login) |
|
295 |
|
296 |
|
297 if __name__ == '__main__': |
|
298 unittest_main() |
|