1from .test_errordocument import simple_app
2from paste.fixture import *
3from paste.recursive import RecursiveMiddleware, ForwardRequestException
4
5def error_docs_app(environ, start_response):
6    if environ['PATH_INFO'] == '/not_found':
7        start_response("404 Not found", [('Content-type', 'text/plain')])
8        return [b'Not found']
9    elif environ['PATH_INFO'] == '/error':
10        start_response("200 OK", [('Content-type', 'text/plain')])
11        return [b'Page not found']
12    elif environ['PATH_INFO'] == '/recurse':
13        raise ForwardRequestException('/recurse')
14    else:
15        return simple_app(environ, start_response)
16
17class Middleware(object):
18    def __init__(self, app, url='/error'):
19        self.app = app
20        self.url = url
21    def __call__(self, environ, start_response):
22        raise ForwardRequestException(self.url)
23
24def forward(app):
25    app = TestApp(RecursiveMiddleware(app))
26    res = app.get('')
27    assert res.header('content-type') == 'text/plain'
28    assert res.full_status == '200 OK'
29    assert 'requested page returned' in res
30    res = app.get('/error')
31    assert res.header('content-type') == 'text/plain'
32    assert res.full_status == '200 OK'
33    assert 'Page not found' in res
34    res = app.get('/not_found')
35    assert res.header('content-type') == 'text/plain'
36    assert res.full_status == '200 OK'
37    assert 'Page not found' in res
38    try:
39        res = app.get('/recurse')
40    except AssertionError as e:
41        if str(e).startswith('Forwarding loop detected'):
42            pass
43        else:
44            raise AssertionError('Failed to detect forwarding loop')
45
46def test_ForwardRequest_url():
47    class TestForwardRequestMiddleware(Middleware):
48        def __call__(self, environ, start_response):
49            if environ['PATH_INFO'] != '/not_found':
50                return self.app(environ, start_response)
51            raise ForwardRequestException(self.url)
52    forward(TestForwardRequestMiddleware(error_docs_app))
53
54def test_ForwardRequest_environ():
55    class TestForwardRequestMiddleware(Middleware):
56        def __call__(self, environ, start_response):
57            if environ['PATH_INFO'] != '/not_found':
58                return self.app(environ, start_response)
59            environ['PATH_INFO'] = self.url
60            raise ForwardRequestException(environ=environ)
61    forward(TestForwardRequestMiddleware(error_docs_app))
62
63def test_ForwardRequest_factory():
64
65    from paste.errordocument import StatusKeeper
66
67    class TestForwardRequestMiddleware(Middleware):
68        def __call__(self, environ, start_response):
69            if environ['PATH_INFO'] != '/not_found':
70                return self.app(environ, start_response)
71            environ['PATH_INFO'] = self.url
72            def factory(app):
73                return StatusKeeper(app, status='404 Not Found', url='/error', headers=[])
74            raise ForwardRequestException(factory=factory)
75
76    app = TestForwardRequestMiddleware(error_docs_app)
77    app = TestApp(RecursiveMiddleware(app))
78    res = app.get('')
79    assert res.header('content-type') == 'text/plain'
80    assert res.full_status == '200 OK'
81    assert 'requested page returned' in res
82    res = app.get('/error')
83    assert res.header('content-type') == 'text/plain'
84    assert res.full_status == '200 OK'
85    assert 'Page not found' in res
86    res = app.get('/not_found', status=404)
87    assert res.header('content-type') == 'text/plain'
88    assert res.full_status == '404 Not Found' # Different status
89    assert 'Page not found' in res
90    try:
91        res = app.get('/recurse')
92    except AssertionError as e:
93        if str(e).startswith('Forwarding loop detected'):
94            pass
95        else:
96            raise AssertionError('Failed to detect forwarding loop')
97
98# Test Deprecated Code
99def test_ForwardRequestException():
100    class TestForwardRequestExceptionMiddleware(Middleware):
101        def __call__(self, environ, start_response):
102            if environ['PATH_INFO'] != '/not_found':
103                return self.app(environ, start_response)
104            raise ForwardRequestException(path_info=self.url)
105    forward(TestForwardRequestExceptionMiddleware(error_docs_app))
106