commit | author | age
|
c55903
|
1 |
# -*- coding: utf-8 -*- |
CM |
2 |
|
64aaf0
|
3 |
import datetime |
0393f9
|
4 |
import gc |
64c913
|
5 |
import locale |
b99526
|
6 |
import os |
5a7f9a
|
7 |
import unittest |
CM |
8 |
|
b60bdb
|
9 |
from pyramid.wsgi import wsgiapp |
197f0c
|
10 |
from pyramid.view import view_config |
56d0fe
|
11 |
from pyramid.static import static_view |
b1cad5
|
12 |
from pyramid.testing import skip_on |
f5b9e9
|
13 |
from pyramid.compat import ( |
CM |
14 |
text_, |
|
15 |
url_quote, |
|
16 |
) |
5a7f9a
|
17 |
|
CM |
18 |
from zope.interface import Interface |
684a2c
|
19 |
from webtest import TestApp |
64aaf0
|
20 |
|
CM |
21 |
# 5 years from now (more or less) |
|
22 |
fiveyrsfuture = datetime.datetime.utcnow() + datetime.timedelta(5*365) |
64c913
|
23 |
|
CM |
24 |
defaultlocale = locale.getdefaultlocale()[1] |
5a7f9a
|
25 |
|
CM |
26 |
class INothing(Interface): |
|
27 |
pass |
|
28 |
|
197f0c
|
29 |
@view_config(for_=INothing) |
5a7f9a
|
30 |
@wsgiapp |
CM |
31 |
def wsgiapptest(environ, start_response): |
|
32 |
""" """ |
|
33 |
return '123' |
|
34 |
|
cba2e1
|
35 |
class WGSIAppPlusViewConfigTests(unittest.TestCase): |
5a7f9a
|
36 |
def test_it(self): |
e6fa66
|
37 |
from venusian import ATTACH_ATTR |
5a7f9a
|
38 |
import types |
a1d395
|
39 |
self.assertTrue(getattr(wsgiapptest, ATTACH_ATTR)) |
CM |
40 |
self.assertTrue(type(wsgiapptest) is types.FunctionType) |
5a7f9a
|
41 |
context = DummyContext() |
CM |
42 |
request = DummyRequest() |
|
43 |
result = wsgiapptest(context, request) |
|
44 |
self.assertEqual(result, '123') |
|
45 |
|
58afb3
|
46 |
def test_scanned(self): |
b60bdb
|
47 |
from pyramid.interfaces import IRequest |
CM |
48 |
from pyramid.interfaces import IView |
|
49 |
from pyramid.interfaces import IViewClassifier |
427a02
|
50 |
from pyramid.config import Configurator |
dd3cc8
|
51 |
from . import test_integration |
427a02
|
52 |
config = Configurator() |
2aa86c
|
53 |
config.scan(test_integration) |
c0d4a1
|
54 |
config.commit() |
2aa86c
|
55 |
reg = config.registry |
ff1213
|
56 |
view = reg.adapters.lookup( |
CM |
57 |
(IViewClassifier, IRequest, INothing), IView, name='') |
661ea7
|
58 |
self.assertEqual(view.__original_view__, wsgiapptest) |
5a7f9a
|
59 |
|
a49168
|
60 |
class IntegrationBase(object): |
CM |
61 |
root_factory = None |
|
62 |
package = None |
|
63 |
def setUp(self): |
|
64 |
from pyramid.config import Configurator |
|
65 |
config = Configurator(root_factory=self.root_factory, |
|
66 |
package=self.package) |
|
67 |
config.include(self.package) |
|
68 |
app = config.make_wsgi_app() |
|
69 |
self.testapp = TestApp(app) |
|
70 |
self.config = config |
|
71 |
|
|
72 |
def tearDown(self): |
|
73 |
self.config.end() |
|
74 |
|
b99526
|
75 |
here = os.path.dirname(__file__) |
CM |
76 |
|
061907
|
77 |
class StaticAppBase(IntegrationBase): |
a49168
|
78 |
def test_basic(self): |
b368d7
|
79 |
res = self.testapp.get('/minimal.txt', status=200) |
BJR |
80 |
_assertBody(res.body, os.path.join(here, 'fixtures/minimal.txt')) |
a49168
|
81 |
|
d5dc5d
|
82 |
def test_hidden(self): |
CM |
83 |
res = self.testapp.get('/static/.hiddenfile', status=200) |
a0e8df
|
84 |
_assertBody(res.body, os.path.join(here, 'fixtures/static/.hiddenfile')) |
d5dc5d
|
85 |
|
076060
|
86 |
if defaultlocale is not None: # pragma: no cover |
54105d
|
87 |
# These tests are expected to fail on LANG=C systems due to decode |
CM |
88 |
# errors and on non-Linux systems due to git highchar handling |
|
89 |
# vagaries |
64c913
|
90 |
def test_highchars_in_pathelement(self): |
5d9bf1
|
91 |
path = os.path.join( |
MM |
92 |
here, |
|
93 |
text_('fixtures/static/héhé/index.html', 'utf-8')) |
|
94 |
pathdir = os.path.dirname(path) |
|
95 |
body = b'<html>hehe</html>\n' |
|
96 |
try: |
|
97 |
os.makedirs(pathdir) |
|
98 |
with open(path, 'wb') as fp: |
|
99 |
fp.write(body) |
|
100 |
url = url_quote('/static/héhé/index.html') |
|
101 |
res = self.testapp.get(url, status=200) |
|
102 |
self.assertEqual(res.body, body) |
|
103 |
finally: |
|
104 |
os.unlink(path) |
|
105 |
os.rmdir(pathdir) |
d5dc5d
|
106 |
|
64c913
|
107 |
def test_highchars_in_filename(self): |
5d9bf1
|
108 |
path = os.path.join( |
MM |
109 |
here, |
|
110 |
text_('fixtures/static/héhé.html', 'utf-8')) |
|
111 |
body = b'<html>hehe file</html>\n' |
|
112 |
with open(path, 'wb') as fp: |
|
113 |
fp.write(body) |
|
114 |
try: |
|
115 |
url = url_quote('/static/héhé.html') |
|
116 |
res = self.testapp.get(url, status=200) |
|
117 |
self.assertEqual(res.body, body) |
|
118 |
finally: |
|
119 |
os.unlink(path) |
d5dc5d
|
120 |
|
a49168
|
121 |
def test_not_modified(self): |
CM |
122 |
self.testapp.extra_environ = { |
64aaf0
|
123 |
'HTTP_IF_MODIFIED_SINCE':httpdate(fiveyrsfuture)} |
b368d7
|
124 |
res = self.testapp.get('/minimal.txt', status=304) |
8e606d
|
125 |
self.assertEqual(res.body, b'') |
a49168
|
126 |
|
CM |
127 |
def test_file_in_subdir(self): |
|
128 |
fn = os.path.join(here, 'fixtures/static/index.html') |
|
129 |
res = self.testapp.get('/static/index.html', status=200) |
a0e8df
|
130 |
_assertBody(res.body, fn) |
a49168
|
131 |
|
CM |
132 |
def test_directory_noslash_redir(self): |
|
133 |
res = self.testapp.get('/static', status=301) |
|
134 |
self.assertEqual(res.headers['Location'], 'http://localhost/static/') |
|
135 |
|
|
136 |
def test_directory_noslash_redir_preserves_qs(self): |
|
137 |
res = self.testapp.get('/static?a=1&b=2', status=301) |
|
138 |
self.assertEqual(res.headers['Location'], |
|
139 |
'http://localhost/static/?a=1&b=2') |
|
140 |
|
|
141 |
def test_directory_noslash_redir_with_scriptname(self): |
|
142 |
self.testapp.extra_environ = {'SCRIPT_NAME':'/script_name'} |
|
143 |
res = self.testapp.get('/static', status=301) |
|
144 |
self.assertEqual(res.headers['Location'], |
|
145 |
'http://localhost/script_name/static/') |
|
146 |
|
|
147 |
def test_directory_withslash(self): |
|
148 |
fn = os.path.join(here, 'fixtures/static/index.html') |
|
149 |
res = self.testapp.get('/static/', status=200) |
a0e8df
|
150 |
_assertBody(res.body, fn) |
a49168
|
151 |
|
CM |
152 |
def test_range_inclusive(self): |
|
153 |
self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1-2'} |
|
154 |
res = self.testapp.get('/static/index.html', status=206) |
8e606d
|
155 |
self.assertEqual(res.body, b'ht') |
a49168
|
156 |
|
CM |
157 |
def test_range_tilend(self): |
|
158 |
self.testapp.extra_environ = {'HTTP_RANGE':'bytes=-5'} |
|
159 |
res = self.testapp.get('/static/index.html', status=206) |
80eac7
|
160 |
self.assertEqual(res.body, b'html>') |
a49168
|
161 |
|
CM |
162 |
def test_range_notbytes(self): |
|
163 |
self.testapp.extra_environ = {'HTTP_RANGE':'kHz=-5'} |
|
164 |
res = self.testapp.get('/static/index.html', status=200) |
a0e8df
|
165 |
_assertBody(res.body, |
CM |
166 |
os.path.join(here, 'fixtures/static/index.html')) |
a49168
|
167 |
|
CM |
168 |
def test_range_multiple(self): |
|
169 |
res = self.testapp.get('/static/index.html', |
9bd249
|
170 |
[('HTTP_RANGE', 'bytes=10-11,11-12')], |
a49168
|
171 |
status=200) |
a0e8df
|
172 |
_assertBody(res.body, |
CM |
173 |
os.path.join(here, 'fixtures/static/index.html')) |
a49168
|
174 |
|
CM |
175 |
def test_range_oob(self): |
|
176 |
self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1000-1002'} |
|
177 |
self.testapp.get('/static/index.html', status=416) |
|
178 |
|
|
179 |
def test_notfound(self): |
|
180 |
self.testapp.get('/static/wontbefound.html', status=404) |
|
181 |
|
66fe31
|
182 |
def test_oob_dotdotslash(self): |
a49168
|
183 |
self.testapp.get('/static/../../test_integration.py', status=404) |
66fe31
|
184 |
|
CM |
185 |
def test_oob_dotdotslash_encoded(self): |
|
186 |
self.testapp.get('/static/%2E%2E%2F/test_integration.py', status=404) |
a49168
|
187 |
|
CM |
188 |
def test_oob_slash(self): |
|
189 |
self.testapp.get('/%2F/test_integration.py', status=404) |
66fe31
|
190 |
|
d91dc7
|
191 |
class TestEventOnlySubscribers(IntegrationBase, unittest.TestCase): |
dd3cc8
|
192 |
package = 'tests.pkgs.eventonly' |
d91dc7
|
193 |
|
CM |
194 |
def test_sendfoo(self): |
|
195 |
res = self.testapp.get('/sendfoo', status=200) |
f55f9b
|
196 |
self.assertEqual(sorted(res.body.split()), [b'foo', b'fooyup']) |
d91dc7
|
197 |
|
CM |
198 |
def test_sendfoobar(self): |
|
199 |
res = self.testapp.get('/sendfoobar', status=200) |
|
200 |
self.assertEqual(sorted(res.body.split()), |
f55f9b
|
201 |
[b'foobar', b'foobar2', b'foobaryup', b'foobaryup2']) |
d91dc7
|
202 |
|
061907
|
203 |
class TestStaticAppUsingAbsPath(StaticAppBase, unittest.TestCase): |
dd3cc8
|
204 |
package = 'tests.pkgs.static_abspath' |
a49168
|
205 |
|
061907
|
206 |
class TestStaticAppUsingAssetSpec(StaticAppBase, unittest.TestCase): |
dd3cc8
|
207 |
package = 'tests.pkgs.static_assetspec' |
a49168
|
208 |
|
CM |
209 |
class TestStaticAppNoSubpath(unittest.TestCase): |
|
210 |
staticapp = static_view(os.path.join(here, 'fixtures'), use_subpath=False) |
c7446c
|
211 |
def _makeRequest(self, extra): |
f2ef79
|
212 |
from pyramid.request import Request |
8e606d
|
213 |
from io import BytesIO |
f2ef79
|
214 |
kw = {'PATH_INFO':'', |
CM |
215 |
'SCRIPT_NAME':'', |
|
216 |
'SERVER_NAME':'localhost', |
|
217 |
'SERVER_PORT':'80', |
|
218 |
'REQUEST_METHOD':'GET', |
|
219 |
'wsgi.version':(1,0), |
|
220 |
'wsgi.url_scheme':'http', |
8e606d
|
221 |
'wsgi.input':BytesIO()} |
f2ef79
|
222 |
kw.update(extra) |
CM |
223 |
request = Request(kw) |
|
224 |
return request |
|
225 |
|
|
226 |
def test_basic(self): |
b368d7
|
227 |
request = self._makeRequest({'PATH_INFO':'/minimal.txt'}) |
f2ef79
|
228 |
context = DummyContext() |
CM |
229 |
result = self.staticapp(context, request) |
|
230 |
self.assertEqual(result.status, '200 OK') |
b368d7
|
231 |
_assertBody(result.body, os.path.join(here, 'fixtures/minimal.txt')) |
29a850
|
232 |
|
bc9357
|
233 |
class TestStaticAppWithRoutePrefix(IntegrationBase, unittest.TestCase): |
dd3cc8
|
234 |
package = 'tests.pkgs.static_routeprefix' |
bc9357
|
235 |
|
CM |
236 |
def test_includelevel1(self): |
b368d7
|
237 |
res = self.testapp.get('/static/minimal.txt', status=200) |
a0e8df
|
238 |
_assertBody(res.body, |
b368d7
|
239 |
os.path.join(here, 'fixtures/minimal.txt')) |
bc9357
|
240 |
|
CM |
241 |
def test_includelevel2(self): |
|
242 |
res = self.testapp.get('/prefix/static/index.html', status=200) |
a0e8df
|
243 |
_assertBody(res.body, |
CM |
244 |
os.path.join(here, 'fixtures/static/index.html')) |
bc9357
|
245 |
|
CM |
246 |
|
a49168
|
247 |
class TestFixtureApp(IntegrationBase, unittest.TestCase): |
dd3cc8
|
248 |
package = 'tests.pkgs.fixtureapp' |
dbaa08
|
249 |
def test_another(self): |
CM |
250 |
res = self.testapp.get('/another.html', status=200) |
8e606d
|
251 |
self.assertEqual(res.body, b'fixture') |
1dc390
|
252 |
|
dbaa08
|
253 |
def test_root(self): |
CM |
254 |
res = self.testapp.get('/', status=200) |
8e606d
|
255 |
self.assertEqual(res.body, b'fixture') |
dbaa08
|
256 |
|
CM |
257 |
def test_dummyskin(self): |
|
258 |
self.testapp.get('/dummyskin.html', status=404) |
|
259 |
|
|
260 |
def test_error(self): |
|
261 |
res = self.testapp.get('/error.html', status=200) |
8e606d
|
262 |
self.assertEqual(res.body, b'supressed') |
dbaa08
|
263 |
|
CM |
264 |
def test_protected(self): |
a05353
|
265 |
self.testapp.get('/protected.html', status=403) |
dbaa08
|
266 |
|
a49168
|
267 |
class TestStaticPermApp(IntegrationBase, unittest.TestCase): |
dd3cc8
|
268 |
package = 'tests.pkgs.staticpermapp' |
MM |
269 |
root_factory = 'tests.pkgs.staticpermapp:RootFactory' |
0b2629
|
270 |
def test_allowed(self): |
CM |
271 |
result = self.testapp.get('/allowed/index.html', status=200) |
5dd253
|
272 |
_assertBody(result.body, |
CM |
273 |
os.path.join(here, 'fixtures/static/index.html')) |
0b2629
|
274 |
|
CM |
275 |
def test_denied_via_acl_global_root_factory(self): |
|
276 |
self.testapp.extra_environ = {'REMOTE_USER':'bob'} |
|
277 |
self.testapp.get('/protected/index.html', status=403) |
|
278 |
|
|
279 |
def test_allowed_via_acl_global_root_factory(self): |
|
280 |
self.testapp.extra_environ = {'REMOTE_USER':'fred'} |
|
281 |
result = self.testapp.get('/protected/index.html', status=200) |
5dd253
|
282 |
_assertBody(result.body, |
CM |
283 |
os.path.join(here, 'fixtures/static/index.html')) |
0b2629
|
284 |
|
CM |
285 |
def test_denied_via_acl_local_root_factory(self): |
|
286 |
self.testapp.extra_environ = {'REMOTE_USER':'fred'} |
|
287 |
self.testapp.get('/factory_protected/index.html', status=403) |
|
288 |
|
|
289 |
def test_allowed_via_acl_local_root_factory(self): |
|
290 |
self.testapp.extra_environ = {'REMOTE_USER':'bob'} |
|
291 |
result = self.testapp.get('/factory_protected/index.html', status=200) |
5dd253
|
292 |
_assertBody(result.body, |
CM |
293 |
os.path.join(here, 'fixtures/static/index.html')) |
0b2629
|
294 |
|
a49168
|
295 |
class TestCCBug(IntegrationBase, unittest.TestCase): |
74a8f6
|
296 |
# "unordered" as reported in IRC by author of |
CM |
297 |
# http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ |
dd3cc8
|
298 |
package = 'tests.pkgs.ccbugapp' |
dbaa08
|
299 |
def test_rdf(self): |
CM |
300 |
res = self.testapp.get('/licenses/1/v1/rdf', status=200) |
8e606d
|
301 |
self.assertEqual(res.body, b'rdf') |
74a8f6
|
302 |
|
dbaa08
|
303 |
def test_juri(self): |
CM |
304 |
res = self.testapp.get('/licenses/1/v1/juri', status=200) |
8e606d
|
305 |
self.assertEqual(res.body, b'juri') |
dbaa08
|
306 |
|
a49168
|
307 |
class TestHybridApp(IntegrationBase, unittest.TestCase): |
333bd0
|
308 |
# make sure views registered for a route "win" over views registered |
CM |
309 |
# without one, even though the context of the non-route view may |
|
310 |
# be more specific than the route view. |
dd3cc8
|
311 |
package = 'tests.pkgs.hybridapp' |
dbaa08
|
312 |
def test_root(self): |
CM |
313 |
res = self.testapp.get('/', status=200) |
8e606d
|
314 |
self.assertEqual(res.body, b'global') |
333bd0
|
315 |
|
dbaa08
|
316 |
def test_abc(self): |
CM |
317 |
res = self.testapp.get('/abc', status=200) |
8e606d
|
318 |
self.assertEqual(res.body, b'route') |
dbaa08
|
319 |
|
CM |
320 |
def test_def(self): |
|
321 |
res = self.testapp.get('/def', status=200) |
8e606d
|
322 |
self.assertEqual(res.body, b'route2') |
dbaa08
|
323 |
|
CM |
324 |
def test_ghi(self): |
|
325 |
res = self.testapp.get('/ghi', status=200) |
8e606d
|
326 |
self.assertEqual(res.body, b'global') |
dbaa08
|
327 |
|
CM |
328 |
def test_jkl(self): |
|
329 |
self.testapp.get('/jkl', status=404) |
|
330 |
|
|
331 |
def test_mno(self): |
|
332 |
self.testapp.get('/mno', status=404) |
|
333 |
|
|
334 |
def test_pqr_global2(self): |
|
335 |
res = self.testapp.get('/pqr/global2', status=200) |
8e606d
|
336 |
self.assertEqual(res.body, b'global2') |
dbaa08
|
337 |
|
CM |
338 |
def test_error(self): |
|
339 |
res = self.testapp.get('/error', status=200) |
8e606d
|
340 |
self.assertEqual(res.body, b'supressed') |
dbaa08
|
341 |
|
CM |
342 |
def test_error2(self): |
|
343 |
res = self.testapp.get('/error2', status=200) |
8e606d
|
344 |
self.assertEqual(res.body, b'supressed2') |
dbaa08
|
345 |
|
CM |
346 |
def test_error_sub(self): |
|
347 |
res = self.testapp.get('/error_sub', status=200) |
8e606d
|
348 |
self.assertEqual(res.body, b'supressed2') |
dbaa08
|
349 |
|
a49168
|
350 |
class TestRestBugApp(IntegrationBase, unittest.TestCase): |
98e0d0
|
351 |
# test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515) |
dd3cc8
|
352 |
package = 'tests.pkgs.restbugapp' |
98e0d0
|
353 |
def test_it(self): |
dbaa08
|
354 |
res = self.testapp.get('/pet', status=200) |
8e606d
|
355 |
self.assertEqual(res.body, b'gotten') |
98e0d0
|
356 |
|
a49168
|
357 |
class TestForbiddenAppHasResult(IntegrationBase, unittest.TestCase): |
b32552
|
358 |
# test that forbidden exception has ACLDenied result attached |
dd3cc8
|
359 |
package = 'tests.pkgs.forbiddenapp' |
b32552
|
360 |
def test_it(self): |
CM |
361 |
res = self.testapp.get('/x', status=403) |
8e606d
|
362 |
message, result = [x.strip() for x in res.body.split(b'\n')] |
CM |
363 |
self.assertTrue(message.endswith(b'failed permission check')) |
a1d395
|
364 |
self.assertTrue( |
8e606d
|
365 |
result.startswith(b"ACLDenied permission 'private' via ACE " |
CM |
366 |
b"'<default deny>' in ACL " |
|
367 |
b"'<No ACL found on any object in resource " |
|
368 |
b"lineage>' on context")) |
a1d395
|
369 |
self.assertTrue( |
8e606d
|
370 |
result.endswith(b"for principals ['system.Everyone']")) |
b32552
|
371 |
|
a49168
|
372 |
class TestViewDecoratorApp(IntegrationBase, unittest.TestCase): |
dd3cc8
|
373 |
package = 'tests.pkgs.viewdecoratorapp' |
89968d
|
374 |
|
dbaa08
|
375 |
def test_first(self): |
CM |
376 |
res = self.testapp.get('/first', status=200) |
8e606d
|
377 |
self.assertTrue(b'OK' in res.body) |
89968d
|
378 |
|
dbaa08
|
379 |
def test_second(self): |
CM |
380 |
res = self.testapp.get('/second', status=200) |
8e606d
|
381 |
self.assertTrue(b'OK2' in res.body) |
dbaa08
|
382 |
|
0db4a1
|
383 |
class TestNotFoundView(IntegrationBase, unittest.TestCase): |
dd3cc8
|
384 |
package = 'tests.pkgs.notfoundview' |
0db4a1
|
385 |
|
CM |
386 |
def test_it(self): |
|
387 |
res = self.testapp.get('/wontbefound', status=200) |
|
388 |
self.assertTrue(b'generic_notfound' in res.body) |
b5422e
|
389 |
res = self.testapp.get('/bar', status=307) |
0db4a1
|
390 |
self.assertEqual(res.location, 'http://localhost/bar/') |
CM |
391 |
res = self.testapp.get('/bar/', status=200) |
|
392 |
self.assertTrue(b'OK bar' in res.body) |
b5422e
|
393 |
res = self.testapp.get('/foo', status=307) |
0db4a1
|
394 |
self.assertEqual(res.location, 'http://localhost/foo/') |
CM |
395 |
res = self.testapp.get('/foo/', status=200) |
|
396 |
self.assertTrue(b'OK foo2' in res.body) |
|
397 |
res = self.testapp.get('/baz', status=200) |
|
398 |
self.assertTrue(b'baz_notfound' in res.body) |
a7fe30
|
399 |
|
CM |
400 |
class TestForbiddenView(IntegrationBase, unittest.TestCase): |
dd3cc8
|
401 |
package = 'tests.pkgs.forbiddenview' |
a7fe30
|
402 |
|
CM |
403 |
def test_it(self): |
|
404 |
res = self.testapp.get('/foo', status=200) |
|
405 |
self.assertTrue(b'foo_forbidden' in res.body) |
|
406 |
res = self.testapp.get('/bar', status=200) |
|
407 |
self.assertTrue(b'generic_forbidden' in res.body) |
0db4a1
|
408 |
|
a49168
|
409 |
class TestViewPermissionBug(IntegrationBase, unittest.TestCase): |
bdddc9
|
410 |
# view_execution_permitted bug as reported by Shane at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003603.html |
dd3cc8
|
411 |
package = 'tests.pkgs.permbugapp' |
dbaa08
|
412 |
def test_test(self): |
CM |
413 |
res = self.testapp.get('/test', status=200) |
8e606d
|
414 |
self.assertTrue(b'ACLDenied' in res.body) |
bdddc9
|
415 |
|
dbaa08
|
416 |
def test_x(self): |
a05353
|
417 |
self.testapp.get('/x', status=403) |
dbaa08
|
418 |
|
a49168
|
419 |
class TestDefaultViewPermissionBug(IntegrationBase, unittest.TestCase): |
1ad1db
|
420 |
# default_view_permission bug as reported by Wiggy at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003602.html |
dd3cc8
|
421 |
package = 'tests.pkgs.defpermbugapp' |
dbaa08
|
422 |
def test_x(self): |
a05353
|
423 |
res = self.testapp.get('/x', status=403) |
8e606d
|
424 |
self.assertTrue(b'failed permission check' in res.body) |
dbaa08
|
425 |
|
CM |
426 |
def test_y(self): |
a05353
|
427 |
res = self.testapp.get('/y', status=403) |
8e606d
|
428 |
self.assertTrue(b'failed permission check' in res.body) |
dbaa08
|
429 |
|
CM |
430 |
def test_z(self): |
|
431 |
res = self.testapp.get('/z', status=200) |
8e606d
|
432 |
self.assertTrue(b'public' in res.body) |
1ad1db
|
433 |
|
dd3cc8
|
434 |
from .pkgs.exceptionviewapp.models import AnException, NotAnException |
ff1213
|
435 |
excroot = {'anexception':AnException(), |
CM |
436 |
'notanexception':NotAnException()} |
|
437 |
|
a49168
|
438 |
class TestExceptionViewsApp(IntegrationBase, unittest.TestCase): |
dd3cc8
|
439 |
package = 'tests.pkgs.exceptionviewapp' |
ff1213
|
440 |
root_factory = lambda *arg: excroot |
dbaa08
|
441 |
def test_root(self): |
CM |
442 |
res = self.testapp.get('/', status=200) |
8e606d
|
443 |
self.assertTrue(b'maybe' in res.body) |
ff1213
|
444 |
|
dbaa08
|
445 |
def test_notanexception(self): |
CM |
446 |
res = self.testapp.get('/notanexception', status=200) |
8e606d
|
447 |
self.assertTrue(b'no' in res.body) |
ff1213
|
448 |
|
dbaa08
|
449 |
def test_anexception(self): |
CM |
450 |
res = self.testapp.get('/anexception', status=200) |
8e606d
|
451 |
self.assertTrue(b'yes' in res.body) |
ff1213
|
452 |
|
dbaa08
|
453 |
def test_route_raise_exception(self): |
CM |
454 |
res = self.testapp.get('/route_raise_exception', status=200) |
8e606d
|
455 |
self.assertTrue(b'yes' in res.body) |
ff1213
|
456 |
|
dbaa08
|
457 |
def test_route_raise_exception2(self): |
CM |
458 |
res = self.testapp.get('/route_raise_exception2', status=200) |
8e606d
|
459 |
self.assertTrue(b'yes' in res.body) |
ff1213
|
460 |
|
dbaa08
|
461 |
def test_route_raise_exception3(self): |
CM |
462 |
res = self.testapp.get('/route_raise_exception3', status=200) |
8e606d
|
463 |
self.assertTrue(b'whoa' in res.body) |
dbaa08
|
464 |
|
CM |
465 |
def test_route_raise_exception4(self): |
|
466 |
res = self.testapp.get('/route_raise_exception4', status=200) |
8e606d
|
467 |
self.assertTrue(b'whoa' in res.body) |
ff1213
|
468 |
|
97ed56
|
469 |
def test_raise_httpexception(self): |
CM |
470 |
res = self.testapp.get('/route_raise_httpexception', status=200) |
|
471 |
self.assertTrue(b'caught' in res.body) |
|
472 |
|
b5a3b0
|
473 |
class TestConflictApp(unittest.TestCase): |
dd3cc8
|
474 |
package = 'tests.pkgs.conflictapp' |
b5a3b0
|
475 |
def _makeConfig(self): |
CM |
476 |
from pyramid.config import Configurator |
|
477 |
config = Configurator() |
|
478 |
return config |
|
479 |
|
|
480 |
def test_autoresolved_view(self): |
|
481 |
config = self._makeConfig() |
|
482 |
config.include(self.package) |
|
483 |
app = config.make_wsgi_app() |
|
484 |
self.testapp = TestApp(app) |
|
485 |
res = self.testapp.get('/') |
8e606d
|
486 |
self.assertTrue(b'a view' in res.body) |
b5a3b0
|
487 |
res = self.testapp.get('/route') |
8e606d
|
488 |
self.assertTrue(b'route view' in res.body) |
b5a3b0
|
489 |
|
CM |
490 |
def test_overridden_autoresolved_view(self): |
|
491 |
from pyramid.response import Response |
|
492 |
config = self._makeConfig() |
|
493 |
config.include(self.package) |
|
494 |
def thisview(request): |
|
495 |
return Response('this view') |
|
496 |
config.add_view(thisview) |
|
497 |
app = config.make_wsgi_app() |
|
498 |
self.testapp = TestApp(app) |
|
499 |
res = self.testapp.get('/') |
8e606d
|
500 |
self.assertTrue(b'this view' in res.body) |
b5a3b0
|
501 |
|
CM |
502 |
def test_overridden_route_view(self): |
|
503 |
from pyramid.response import Response |
|
504 |
config = self._makeConfig() |
|
505 |
config.include(self.package) |
|
506 |
def thisview(request): |
|
507 |
return Response('this view') |
|
508 |
config.add_view(thisview, route_name='aroute') |
|
509 |
app = config.make_wsgi_app() |
|
510 |
self.testapp = TestApp(app) |
|
511 |
res = self.testapp.get('/route') |
8e606d
|
512 |
self.assertTrue(b'this view' in res.body) |
b5a3b0
|
513 |
|
CM |
514 |
def test_nonoverridden_authorization_policy(self): |
|
515 |
config = self._makeConfig() |
|
516 |
config.include(self.package) |
|
517 |
app = config.make_wsgi_app() |
|
518 |
self.testapp = TestApp(app) |
|
519 |
res = self.testapp.get('/protected', status=403) |
8e606d
|
520 |
self.assertTrue(b'403 Forbidden' in res.body) |
b5a3b0
|
521 |
|
CM |
522 |
def test_overridden_authorization_policy(self): |
|
523 |
config = self._makeConfig() |
|
524 |
config.include(self.package) |
|
525 |
from pyramid.testing import DummySecurityPolicy |
|
526 |
config.set_authorization_policy(DummySecurityPolicy('fred')) |
|
527 |
config.set_authentication_policy(DummySecurityPolicy(permissive=True)) |
|
528 |
app = config.make_wsgi_app() |
|
529 |
self.testapp = TestApp(app) |
|
530 |
res = self.testapp.get('/protected', status=200) |
|
531 |
self.assertTrue('protected view' in res) |
|
532 |
|
446967
|
533 |
class ImperativeIncludeConfigurationTest(unittest.TestCase): |
CM |
534 |
def setUp(self): |
427a02
|
535 |
from pyramid.config import Configurator |
CM |
536 |
config = Configurator() |
dd3cc8
|
537 |
from .pkgs.includeapp1.root import configure |
446967
|
538 |
configure(config) |
CM |
539 |
app = config.make_wsgi_app() |
|
540 |
self.testapp = TestApp(app) |
|
541 |
self.config = config |
|
542 |
|
|
543 |
def tearDown(self): |
|
544 |
self.config.end() |
|
545 |
|
|
546 |
def test_root(self): |
|
547 |
res = self.testapp.get('/', status=200) |
8e606d
|
548 |
self.assertTrue(b'root' in res.body) |
446967
|
549 |
|
CM |
550 |
def test_two(self): |
|
551 |
res = self.testapp.get('/two', status=200) |
8e606d
|
552 |
self.assertTrue(b'two' in res.body) |
446967
|
553 |
|
CM |
554 |
def test_three(self): |
|
555 |
res = self.testapp.get('/three', status=200) |
8e606d
|
556 |
self.assertTrue(b'three' in res.body) |
446967
|
557 |
|
c5d172
|
558 |
class SelfScanAppTest(unittest.TestCase): |
CM |
559 |
def setUp(self): |
dd3cc8
|
560 |
from .test_config.pkgs.selfscan import main |
c5d172
|
561 |
config = main() |
CM |
562 |
app = config.make_wsgi_app() |
|
563 |
self.testapp = TestApp(app) |
|
564 |
self.config = config |
|
565 |
|
|
566 |
def tearDown(self): |
|
567 |
self.config.end() |
|
568 |
|
|
569 |
def test_root(self): |
|
570 |
res = self.testapp.get('/', status=200) |
8e606d
|
571 |
self.assertTrue(b'root' in res.body) |
c5d172
|
572 |
|
CM |
573 |
def test_two(self): |
|
574 |
res = self.testapp.get('/two', status=200) |
8e606d
|
575 |
self.assertTrue(b'two' in res.body) |
c5d172
|
576 |
|
44494c
|
577 |
class WSGIApp2AppTest(unittest.TestCase): |
CM |
578 |
def setUp(self): |
dd3cc8
|
579 |
from .pkgs.wsgiapp2app import main |
44494c
|
580 |
config = main() |
CM |
581 |
app = config.make_wsgi_app() |
|
582 |
self.testapp = TestApp(app) |
|
583 |
self.config = config |
|
584 |
|
|
585 |
def tearDown(self): |
|
586 |
self.config.end() |
|
587 |
|
|
588 |
def test_hello(self): |
|
589 |
res = self.testapp.get('/hello', status=200) |
8e606d
|
590 |
self.assertTrue(b'Hello' in res.body) |
44494c
|
591 |
|
37d2c2
|
592 |
class SubrequestAppTest(unittest.TestCase): |
CM |
593 |
def setUp(self): |
dd3cc8
|
594 |
from .pkgs.subrequestapp import main |
37d2c2
|
595 |
config = main() |
CM |
596 |
app = config.make_wsgi_app() |
|
597 |
self.testapp = TestApp(app) |
|
598 |
self.config = config |
366a7c
|
599 |
|
37d2c2
|
600 |
def tearDown(self): |
CM |
601 |
self.config.end() |
366a7c
|
602 |
|
7259e7
|
603 |
def test_one(self): |
37d2c2
|
604 |
res = self.testapp.get('/view_one', status=200) |
0bee84
|
605 |
self.assertTrue(b'This came from view_two, foo=bar' in res.body) |
37d2c2
|
606 |
|
7259e7
|
607 |
def test_three(self): |
CM |
608 |
res = self.testapp.get('/view_three', status=500) |
|
609 |
self.assertTrue(b'Bad stuff happened' in res.body) |
|
610 |
|
|
611 |
def test_five(self): |
|
612 |
res = self.testapp.get('/view_five', status=200) |
|
613 |
self.assertTrue(b'Value error raised' in res.body) |
|
614 |
|
37d2c2
|
615 |
class RendererScanAppTest(IntegrationBase, unittest.TestCase): |
dd3cc8
|
616 |
package = 'tests.pkgs.rendererscanapp' |
37d2c2
|
617 |
def test_root(self): |
CM |
618 |
res = self.testapp.get('/one', status=200) |
|
619 |
self.assertTrue(b'One!' in res.body) |
|
620 |
|
|
621 |
def test_two(self): |
|
622 |
res = self.testapp.get('/two', status=200) |
|
623 |
self.assertTrue(b'Two!' in res.body) |
|
624 |
|
|
625 |
def test_rescan(self): |
dd3cc8
|
626 |
self.config.scan('tests.pkgs.rendererscanapp') |
37d2c2
|
627 |
app = self.config.make_wsgi_app() |
CM |
628 |
testapp = TestApp(app) |
|
629 |
res = testapp.get('/one', status=200) |
|
630 |
self.assertTrue(b'One!' in res.body) |
|
631 |
res = testapp.get('/two', status=200) |
|
632 |
self.assertTrue(b'Two!' in res.body) |
33bcf6
|
633 |
|
49bcc8
|
634 |
class UnicodeInURLTest(unittest.TestCase): |
MA |
635 |
def _makeConfig(self): |
|
636 |
from pyramid.config import Configurator |
|
637 |
config = Configurator() |
|
638 |
return config |
|
639 |
|
|
640 |
def _makeTestApp(self, config): |
|
641 |
app = config.make_wsgi_app() |
|
642 |
return TestApp(app) |
|
643 |
|
|
644 |
def test_unicode_in_url_404(self): |
bc87ed
|
645 |
request_path = '/avalia%C3%A7%C3%A3o_participante' |
MA |
646 |
request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') |
49bcc8
|
647 |
|
MA |
648 |
config = self._makeConfig() |
|
649 |
testapp = self._makeTestApp(config) |
|
650 |
|
|
651 |
res = testapp.get(request_path, status=404) |
a99abf
|
652 |
|
MA |
653 |
# Pyramid default 404 handler outputs: |
|
654 |
# u'404 Not Found\n\nThe resource could not be found.\n\n\n' |
|
655 |
# u'/avalia\xe7\xe3o_participante\n\n' |
49bcc8
|
656 |
self.assertTrue(request_path_unicode in res.text) |
MA |
657 |
|
|
658 |
def test_unicode_in_url_200(self): |
0c425d
|
659 |
request_path = '/avalia%C3%A7%C3%A3o_participante' |
bc87ed
|
660 |
request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') |
49bcc8
|
661 |
|
MA |
662 |
def myview(request): |
|
663 |
return 'XXX' |
|
664 |
|
|
665 |
config = self._makeConfig() |
|
666 |
config.add_route('myroute', request_path_unicode) |
|
667 |
config.add_view(myview, route_name='myroute', renderer='json') |
|
668 |
testapp = self._makeTestApp(config) |
|
669 |
|
|
670 |
res = testapp.get(request_path, status=200) |
|
671 |
|
|
672 |
self.assertEqual(res.text, '"XXX"') |
|
673 |
|
|
674 |
|
e10087
|
675 |
class AcceptContentTypeTest(unittest.TestCase): |
684a2c
|
676 |
def _makeConfig(self): |
e10087
|
677 |
def hello_view(request): |
MA |
678 |
return {'message': 'Hello!'} |
|
679 |
from pyramid.config import Configurator |
|
680 |
config = Configurator() |
|
681 |
config.add_route('hello', '/hello') |
684a2c
|
682 |
config.add_view(hello_view, route_name='hello', |
MM |
683 |
accept='text/plain', renderer='string') |
|
684 |
config.add_view(hello_view, route_name='hello', |
|
685 |
accept='application/json', renderer='json') |
|
686 |
def hello_fallback_view(request): |
|
687 |
request.response.content_type = 'text/x-fallback' |
|
688 |
return 'hello fallback' |
|
689 |
config.add_view(hello_fallback_view, route_name='hello', |
|
690 |
renderer='string') |
|
691 |
return config |
|
692 |
|
|
693 |
def _makeTestApp(self, config): |
e10087
|
694 |
app = config.make_wsgi_app() |
684a2c
|
695 |
return TestApp(app) |
e10087
|
696 |
|
061907
|
697 |
def tearDown(self): |
CM |
698 |
import pyramid.config |
684a2c
|
699 |
pyramid.config.global_registries.empty() |
061907
|
700 |
|
684a2c
|
701 |
def test_client_side_ordering(self): |
MM |
702 |
config = self._makeConfig() |
|
703 |
app = self._makeTestApp(config) |
|
704 |
res = app.get('/hello', headers={ |
|
705 |
'Accept': 'application/json; q=1.0, text/plain; q=0.9', |
|
706 |
}, status=200) |
e10087
|
707 |
self.assertEqual(res.content_type, 'application/json') |
684a2c
|
708 |
res = app.get('/hello', headers={ |
MM |
709 |
'Accept': 'text/plain; q=0.9, application/json; q=1.0', |
|
710 |
}, status=200) |
e10087
|
711 |
self.assertEqual(res.content_type, 'application/json') |
684a2c
|
712 |
res = app.get('/hello', headers={'Accept': 'application/*'}, status=200) |
e10087
|
713 |
self.assertEqual(res.content_type, 'application/json') |
684a2c
|
714 |
res = app.get('/hello', headers={'Accept': 'text/*'}, status=200) |
e10087
|
715 |
self.assertEqual(res.content_type, 'text/plain') |
684a2c
|
716 |
res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) |
MM |
717 |
self.assertEqual(res.content_type, 'text/x-fallback') |
e10087
|
718 |
|
684a2c
|
719 |
def test_default_server_side_ordering(self): |
MM |
720 |
config = self._makeConfig() |
|
721 |
app = self._makeTestApp(config) |
|
722 |
res = app.get('/hello', headers={ |
|
723 |
'Accept': 'application/json, text/plain', |
|
724 |
}, status=200) |
a3d3a2
|
725 |
self.assertEqual(res.content_type, 'text/plain') |
684a2c
|
726 |
res = app.get('/hello', headers={ |
MM |
727 |
'Accept': 'text/plain, application/json', |
|
728 |
}, status=200) |
|
729 |
self.assertEqual(res.content_type, 'text/plain') |
|
730 |
res = app.get('/hello', headers={'Accept': '*/*'}, status=200) |
|
731 |
self.assertEqual(res.content_type, 'text/plain') |
|
732 |
res = app.get('/hello', status=200) |
|
733 |
self.assertEqual(res.content_type, 'text/plain') |
|
734 |
res = app.get('/hello', headers={'Accept': 'invalid'}, status=200) |
|
735 |
self.assertEqual(res.content_type, 'text/plain') |
|
736 |
res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) |
|
737 |
self.assertEqual(res.content_type, 'text/x-fallback') |
a3d3a2
|
738 |
|
684a2c
|
739 |
def test_custom_server_side_ordering(self): |
MM |
740 |
config = self._makeConfig() |
|
741 |
config.add_accept_view_order( |
|
742 |
'application/json', weighs_more_than='text/plain') |
|
743 |
app = self._makeTestApp(config) |
|
744 |
res = app.get('/hello', headers={ |
|
745 |
'Accept': 'application/json, text/plain', |
|
746 |
}, status=200) |
|
747 |
self.assertEqual(res.content_type, 'application/json') |
|
748 |
res = app.get('/hello', headers={ |
|
749 |
'Accept': 'text/plain, application/json', |
|
750 |
}, status=200) |
|
751 |
self.assertEqual(res.content_type, 'application/json') |
|
752 |
res = app.get('/hello', headers={'Accept': '*/*'}, status=200) |
|
753 |
self.assertEqual(res.content_type, 'application/json') |
|
754 |
res = app.get('/hello', status=200) |
|
755 |
self.assertEqual(res.content_type, 'application/json') |
|
756 |
res = app.get('/hello', headers={'Accept': 'invalid'}, status=200) |
|
757 |
self.assertEqual(res.content_type, 'application/json') |
|
758 |
res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) |
|
759 |
self.assertEqual(res.content_type, 'text/x-fallback') |
a3d3a2
|
760 |
|
4a9f4f
|
761 |
def test_deprecated_ranges_in_route_predicate(self): |
MM |
762 |
config = self._makeConfig() |
|
763 |
config.add_route('foo', '/foo', accept='text/*') |
|
764 |
config.add_view(lambda r: 'OK', route_name='foo', renderer='string') |
|
765 |
app = self._makeTestApp(config) |
|
766 |
res = app.get('/foo', headers={ |
|
767 |
'Accept': 'application/json; q=1.0, text/plain; q=0.9', |
|
768 |
}, status=200) |
a3d3a2
|
769 |
self.assertEqual(res.content_type, 'text/plain') |
4a9f4f
|
770 |
self.assertEqual(res.body, b'OK') |
MM |
771 |
res = app.get('/foo', headers={ |
|
772 |
'Accept': 'application/json', |
|
773 |
}, status=404) |
|
774 |
self.assertEqual(res.content_type, 'application/json') |
a3d3a2
|
775 |
|
4a9f4f
|
776 |
def test_deprecated_ranges_in_view_predicate(self): |
MM |
777 |
config = self._makeConfig() |
|
778 |
config.add_route('foo', '/foo') |
|
779 |
config.add_view(lambda r: 'OK', route_name='foo', |
|
780 |
accept='text/*', renderer='string') |
|
781 |
app = self._makeTestApp(config) |
|
782 |
res = app.get('/foo', headers={ |
|
783 |
'Accept': 'application/json; q=1.0, text/plain; q=0.9', |
|
784 |
}, status=200) |
a3d3a2
|
785 |
self.assertEqual(res.content_type, 'text/plain') |
4a9f4f
|
786 |
self.assertEqual(res.body, b'OK') |
MM |
787 |
res = app.get('/foo', headers={ |
|
788 |
'Accept': 'application/json', |
|
789 |
}, status=404) |
|
790 |
self.assertEqual(res.content_type, 'application/json') |
a3d3a2
|
791 |
|
e10087
|
792 |
|
e46105
|
793 |
class DummyContext(object): |
5a7f9a
|
794 |
pass |
CM |
795 |
|
|
796 |
class DummyRequest: |
|
797 |
subpath = ('__init__.py',) |
d1209e
|
798 |
traversed = None |
5a7f9a
|
799 |
environ = {'REQUEST_METHOD':'GET', 'wsgi.version':(1,0)} |
CM |
800 |
def get_response(self, application): |
|
801 |
return application(None, None) |
|
802 |
|
a49168
|
803 |
def httpdate(ts): |
CM |
804 |
return ts.strftime("%a, %d %b %Y %H:%M:%S GMT") |
a0e8df
|
805 |
|
CM |
806 |
def read_(filename): |
5dd253
|
807 |
with open(filename, 'rb') as fp: |
a0e8df
|
808 |
val = fp.read() |
CM |
809 |
return val |
|
810 |
|
|
811 |
def _assertBody(body, filename): |
f5b9e9
|
812 |
if defaultlocale is None: # pragma: no cover |
64c913
|
813 |
# If system locale does not have an encoding then default to utf-8 |
CM |
814 |
filename = filename.encode('utf-8') |
5dd253
|
815 |
# strip both \n and \r for windows |
956b99
|
816 |
body = body.replace(b'\r', b'') |
CM |
817 |
body = body.replace(b'\n', b'') |
5dd253
|
818 |
data = read_(filename) |
956b99
|
819 |
data = data.replace(b'\r', b'') |
CM |
820 |
data = data.replace(b'\n', b'') |
5dd253
|
821 |
assert(body == data) |
0393f9
|
822 |
|
KK |
823 |
|
|
824 |
class MemoryLeaksTest(unittest.TestCase): |
|
825 |
|
|
826 |
def tearDown(self): |
|
827 |
import pyramid.config |
|
828 |
pyramid.config.global_registries.empty() |
|
829 |
|
|
830 |
def get_gc_count(self): |
|
831 |
last_collected = 0 |
|
832 |
while True: |
|
833 |
collected = gc.collect() |
|
834 |
if collected == last_collected: |
|
835 |
break |
|
836 |
last_collected = collected |
|
837 |
return len(gc.get_objects()) |
|
838 |
|
b1cad5
|
839 |
@skip_on('pypy') |
0393f9
|
840 |
def test_memory_leaks(self): |
KK |
841 |
from pyramid.config import Configurator |
|
842 |
Configurator().make_wsgi_app() # Initialize all global objects |
|
843 |
|
|
844 |
initial_count = self.get_gc_count() |
|
845 |
Configurator().make_wsgi_app() |
|
846 |
current_count = self.get_gc_count() |
|
847 |
self.assertEqual(current_count, initial_count) |