예제 #1
0
    def test_shared_data_middleware(self):
        def null_application(environ, start_response):
            start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
            yield b'NOT FOUND'

        with TemporaryDirectory() as test_dir:
            test_file_name = path.join(test_dir, 'äöü').encode()
            with open(test_file_name, 'w') as test_file:
                test_file.write('FOUND')

            app = wsgi.SharedDataMiddleware(null_application, {
                '/': path.join(path.dirname(__file__), 'resources'),
                '/sources': path.join(path.dirname(__file__), 'resources'),
                '/foo': test_dir
            })

            for p in '/test.txt', '/sources/test.txt', '/foo/äöü':
                with self.subTest(path=p):
                    app_iter, status, headers = run_wsgi_app(
                        app, create_environ(p)
                    )
                    self.assertEqual(status, '200 OK')
                    with closing(app_iter) as app_iter:
                        data = b''.join(app_iter).strip()
                    self.assertEqual(data, b'FOUND')

            app_iter, status, headers = run_wsgi_app(
                app, create_environ('/missing'))
            self.assertEqual(status, '404 NOT FOUND')
            self.assertEqual(b''.join(app_iter).strip(), b'NOT FOUND')
예제 #2
0
    def test_dispatchermiddleware(self):
        def null_application(environ, start_response):
            start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
            yield b'NOT FOUND'

        def dummy_application(environ, start_response):
            start_response('200 OK', [('Content-Type', 'text/plain')])
            yield to_bytes(environ['SCRIPT_NAME'])

        app = wsgi.DispatcherMiddleware(null_application, {
            '/test1': dummy_application,
            '/test2/very': dummy_application,
        })
        tests = {
            '/test1': ('/test1', '/test1/asfd', '/test1/very'),
            '/test2/very':
            ('/test2/very', '/test2/very/long/path/after/script/name'),
        }
        for name, urls in tests.items():
            for p in urls:
                environ = create_environ(p)
                app_iter, status, headers = run_wsgi_app(app, environ)
                self.assertEqual(status, '200 OK')
                self.assertEqual(b''.join(app_iter).strip(), to_bytes(name))

        app_iter, status, headers = run_wsgi_app(app,
                                                 create_environ('/missing'))
        self.assertEqual(status, '404 NOT FOUND')
        self.assertEqual(b''.join(app_iter).strip(), b'NOT FOUND')
예제 #3
0
    def test_dispatchermiddleware(self):
        def null_application(environ, start_response):
            start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
            yield b'NOT FOUND'

        def dummy_application(environ, start_response):
            start_response('200 OK', [('Content-Type', 'text/plain')])
            yield environ['SCRIPT_NAME'].encode('ascii')

        app = wsgi.DispatcherMiddleware(null_application, {
            '/test1': dummy_application,
            '/test2/very': dummy_application,
        })
        tests = {
            '/test1': ('/test1', '/test1/asfd', '/test1/very'),
            '/test2/very': (
                '/test2/very', '/test2/very/long/path/after/script/name'
            ),
        }
        for name, urls in tests.items():
            for p in urls:
                environ = create_environ(p)
                app_iter, status, headers = run_wsgi_app(app, environ)
                self.assertEqual(status, '200 OK')
                self.assertEqual(
                    b''.join(app_iter).strip(), name.encode('ascii')
                )

        app_iter, status, headers = run_wsgi_app(
            app, create_environ('/missing'))
        self.assertEqual(status, '404 NOT FOUND')
        self.assertEqual(b''.join(app_iter).strip(), b'NOT FOUND')
예제 #4
0
    def test_path_info_extraction(self):
        x = wsgi.extract_path_info('http://example.com/app', '/app/hello')
        self.assertEqual(x, '/hello')
        x = wsgi.extract_path_info('http://example.com/app',
                                   'https://example.com/app/hello')
        self.assertEqual(x, '/hello')
        x = wsgi.extract_path_info('http://example.com/app/',
                                   'https://example.com/app/hello')
        self.assertEqual(x, '/hello')
        x = wsgi.extract_path_info('http://example.com/app/',
                                   'https://example.com/app')
        self.assertEqual(x, '/')
        x = wsgi.extract_path_info('http://☃.net/', '/fööbär')
        self.assertEqual(x, '/fööbär')
        x = wsgi.extract_path_info('http://☃.net/x', 'http://☃.net/x/fööbär')
        self.assertEqual(x, '/fööbär')

        env = create_environ('/fööbär', 'http://☃.net/x/')
        x = wsgi.extract_path_info(env, 'http://☃.net/x/fööbär')
        self.assertEqual(x, '/fööbär')

        x = wsgi.extract_path_info('http://example.com/app/',
                                   'https://example.com/a/hello')
        self.assertIsNone(x)
        x = wsgi.extract_path_info('http://example.com/app/',
                                   'https://example.com/app/hello',
                                   collapse_http_schemes=False)
        self.assertIsNone(x)
예제 #5
0
 def test_get_current_url_unicode(self):
     env = create_environ()
     env['QUERY_STRING'] = 'foo=bar&baz=blah&meh=\xcf'
     rv = wsgi.get_current_url(env)
     self.assertEqual(
         rv, 'http://localhost/?foo=bar&baz=blah&meh=\ufffd'
     )
예제 #6
0
 def test_external_building_with_port_bind_to_environ_bad_servername(self):
     map = r.URLMap([
         r.Route('/', endpoint='index'),
     ])
     environ = create_environ('/', 'http://example.org:5000/')
     adapter = map.bind_to_environ(environ, server_name="example.org")
     self.assertEqual(adapter.subdomain, '<invalid>')
예제 #7
0
 def test_get_current_url_unicode(self):
     env = create_environ()
     env['QUERY_STRING'] = 'foo=bar&baz=blah&meh=\xcf'
     rv = wsgi.get_current_url(env)
     self.assertEqual(
         rv, 'http://localhost/?foo=bar&baz=blah&meh=\ufffd'
     )
예제 #8
0
    def test_is_resource_modified(self):
        env = create_environ()

        # ignore POST
        env['REQUEST_METHOD'] = 'POST'
        self.assertFalse(http.is_resource_modified(env, etag='testing'))
        env['REQUEST_METHOD'] = 'GET'

        # etagify from data
        self.assertRaises(
            TypeError, http.is_resource_modified, env, data='42', etag='23'
        )
        env['HTTP_IF_NONE_MATCH'] = http.generate_etag(b'awesome')
        self.assertFalse(http.is_resource_modified(env, data=b'awesome'))

        env['HTTP_IF_MODIFIED_SINCE'] = http.http_date(
            datetime(2008, 1, 1, 12, 30)
        )
        self.assertFalse(
            http.is_resource_modified(
                env, last_modified=datetime(2008, 1, 1, 12, 00)
            )
        )
        self.assertTrue(
            http.is_resource_modified(
                env, last_modified=datetime(2008, 1, 1, 13, 00)
            )
        )
예제 #9
0
 def test_path_info_and_script_name_fetching(self):
     env = create_environ('/\N{SNOWMAN}', 'http://example.com/\N{COMET}/')
     self.assertEqual(wsgi.get_path_info(env), '/\N{SNOWMAN}')
     self.assertEqual(wsgi.get_path_info(env, charset=None),
                      '/\N{SNOWMAN}'.encode('utf-8'))
     self.assertEqual(wsgi.get_script_name(env), '/\N{COMET}')
     self.assertEqual(wsgi.get_script_name(env, charset=None),
                      '/\N{COMET}'.encode('utf-8'))
예제 #10
0
    def test_base_response(self):
        # unicode
        response = BaseResponse(u'öäü')
        self.assertEqual(response.get_data(), u'öäü'.encode('utf-8'))

        # writing
        response = Response('foo')
        response.stream.write('bar')
        self.assertEqual(response.get_data(), b'foobar')

        # set cookie
        response = BaseResponse()
        response.set_cookie('foo', 'bar', 60, 0, '/blub', 'example.org')
        self.assertEqual(response.headers.to_wsgi_list(), [
            ('Content-Type', 'text/plain; charset=utf-8'),
            ('Set-Cookie', 'foo=bar; Domain=example.org; Expires=Thu, '
             '01-Jan-1970 00:00:00 GMT; Max-Age=60; Path=/blub')
        ])

        # delete cookie
        response = BaseResponse()
        response.delete_cookie('foo')
        self.assertEqual(response.headers.to_wsgi_list(), [
            ('Content-Type', 'text/plain; charset=utf-8'),
            ('Set-Cookie', 'foo=; Expires=Thu, 01-Jan-1970 00:00:00 GMT; '
                           'Max-Age=0; Path=/'),
        ])

        # close call forwarding
        closed = []

        class Iterable(object):

            def __next__(self):
                raise StopIteration()

            def __iter__(self):
                return self

            def close(self):
                closed.append(True)
        response = BaseResponse(Iterable())
        response.call_on_close(lambda: closed.append(True))
        app_iter, status, headers = run_wsgi_app(response,
                                                 create_environ(),
                                                 buffered=True)
        self.assertEqual(status, '200 OK')
        self.assertEqual(''.join(app_iter), '')
        self.assertEqual(len(closed), 2)

        # with statement
        del closed[:]
        response = BaseResponse(Iterable())
        with response:
            pass
        self.assertEqual(len(closed), 1)
예제 #11
0
 def test_environ_nonascii_pathinfo(self):
     environ = create_environ(u'/лошадь')
     m = r.URLMap([
         r.Route(u'/', endpoint='index'),
         r.Route(u'/лошадь', endpoint='horse')
     ])
     a = m.bind_to_environ(environ)
     self.assertEqual(a.match(u'/'), ('index', {}))
     self.assertEqual(a.match(u'/лошадь'), ('horse', {}))
     self.assertRaises(r.NotFound, a.match, u'/барсук')
예제 #12
0
 def test_external_building_with_port_bind_to_environ(self):
     map = r.URLMap([
         r.Route('/', endpoint='index'),
     ])
     adapter = map.bind_to_environ(
         create_environ('/', 'http://example.org:5000/'),
         server_name="example.org:5000"
     )
     built_url = adapter.build('index', {}, force_external=True)
     self.assertEqual(built_url, 'http://example.org:5000/', built_url)
예제 #13
0
 def test_get_host(self):
     env = {
         'HTTP_X_FORWARDED_HOST': 'example.org',
         'SERVER_NAME': 'bullshit', 'HOST_NAME': 'ignore me dammit',
     }
     self.assertEqual(wsgi.get_host(env), 'example.org')
     self.assertEqual(
         wsgi.get_host(create_environ('/', 'http://example.org')),
         'example.org'
     )
예제 #14
0
 def test_get_host(self):
     env = {
         'HTTP_X_FORWARDED_HOST': 'example.org',
         'SERVER_NAME': 'bullshit',
         'HOST_NAME': 'ignore me dammit',
     }
     self.assertEqual(wsgi.get_host(env), 'example.org')
     self.assertEqual(
         wsgi.get_host(create_environ('/', 'http://example.org')),
         'example.org')
예제 #15
0
 def test_environ_defaults(self):
     environ = create_environ("/foo")
     self.assertEqual(environ["PATH_INFO"], '/foo')
     m = r.URLMap([
         r.Route("/foo", endpoint="foo"),
         r.Route("/bar", endpoint="bar"),
     ])
     a = m.bind_to_environ(environ)
     self.assertEqual(a.match("/foo"), ('foo', {}))
     self.assertEqual(a.match(), ('foo', {}))
     self.assertEqual(a.match("/bar"), ('bar', {}))
     self.assertRaises(r.NotFound, a.match, "/bars")
예제 #16
0
    def test_server_name_casing(self):
        m = r.URLMap([
            r.Route('/', endpoint='index', subdomain='foo')
        ])

        env = create_environ()
        env['SERVER_NAME'] = env['HTTP_HOST'] = 'FOO.EXAMPLE.COM'
        a = m.bind_to_environ(env, server_name='example.com')
        self.assertEqual(a.match('/'), ('index', {}))

        env = create_environ()
        env['SERVER_NAME'] = '127.0.0.1'
        env['SERVER_PORT'] = '5000'
        del env['HTTP_HOST']
        a = m.bind_to_environ(env, server_name='example.com')
        try:
            a.match()
        except r.NotFound:
            pass
        else:  # pragma: no cover
            self.fail('Expected not found exception')
예제 #17
0
 def test_urlfication(self):
     resp = Response()
     resp.headers['Location'] = u'http://üser:pässword@☃.net/påth'
     resp.headers['Content-Location'] = u'http://☃.net/'
     headers = resp.get_wsgi_headers(create_environ())
     self.assertEqual(
         headers['location'],
         'http://%C3%BCser:p%C3%[email protected]/p%C3%A5th'
     )
     self.assertEqual(
         headers['content-location'],
         'http://xn--n3h.net/'
     )
예제 #18
0
 def test_urlfication(self):
     resp = Response()
     resp.headers['Location'] = u'http://üser:pässword@☃.net/påth'
     resp.headers['Content-Location'] = u'http://☃.net/'
     headers = resp.get_wsgi_headers(create_environ())
     self.assertEqual(
         headers['location'],
         'http://%C3%BCser:p%C3%[email protected]/p%C3%A5th'
     )
     self.assertEqual(
         headers['content-location'],
         'http://xn--n3h.net/'
     )
예제 #19
0
    def test_location_header_autocorrect(self):
        env = create_environ()

        class MyResponse(Response):
            autocorrect_location_header = False
        resp = MyResponse('Hello World!')
        resp.headers['Location'] = '/test'
        self.assertEqual(resp.get_wsgi_headers(env)['Location'], '/test')

        resp = Response('Hello World!')
        resp.headers['Location'] = '/test'
        self.assertEqual(
            resp.get_wsgi_headers(env)['Location'], 'http://localhost/test'
        )
예제 #20
0
    def test_location_header_autocorrect(self):
        env = create_environ()

        class MyResponse(Response):
            autocorrect_location_header = False
        resp = MyResponse('Hello World!')
        resp.headers['Location'] = '/test'
        self.assertEqual(resp.get_wsgi_headers(env)['Location'], '/test')

        resp = Response('Hello World!')
        resp.headers['Location'] = '/test'
        self.assertEqual(
            resp.get_wsgi_headers(env)['Location'], 'http://localhost/test'
        )
예제 #21
0
    def test_shared_data_middleware(self):
        def null_application(environ, start_response):
            start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
            yield b'NOT FOUND'

        with TemporaryDirectory() as test_dir:
            test_file_name = path.join(test_dir, 'äöü').encode()
            with open(test_file_name, 'w') as test_file:
                test_file.write('FOUND')

            app = wsgi.SharedDataMiddleware(
                null_application, {
                    '/': path.join(path.dirname(__file__), 'resources'),
                    '/sources': path.join(path.dirname(__file__), 'resources'),
                    '/pkg': ('werkzeug.debug', 'shared'),
                    '/foo': test_dir
                })

            for p in '/test.txt', '/sources/test.txt', '/foo/äöü':
                with self.subTest(path=p):
                    app_iter, status, headers = run_wsgi_app(
                        app, create_environ(p))
                    self.assertEqual(status, '200 OK')
                    with closing(app_iter) as app_iter:
                        data = b''.join(app_iter).strip()
                    self.assertEqual(data, b'FOUND')

            app_iter, status, headers = run_wsgi_app(
                app, create_environ('/pkg/debugger.js'))
            with closing(app_iter) as app_iter:
                contents = b''.join(app_iter)
            self.assertIn(b'$(function() {', contents)

            app_iter, status, headers = run_wsgi_app(
                app, create_environ('/missing'))
            self.assertEqual(status, '404 NOT FOUND')
            self.assertEqual(b''.join(app_iter).strip(), b'NOT FOUND')
예제 #22
0
    def test_server_name_interpolation(self):
        server_name = 'example.invalid'
        map = r.URLMap([
            r.Route('/', endpoint='index'),
            r.Route('/', endpoint='alt', subdomain='alt'),
        ])

        env = create_environ('/', 'http://%s/' % server_name)
        adapter = map.bind_to_environ(env, server_name=server_name)
        self.assertEqual(
            adapter.match(),
            ('index', {})
        )

        env = create_environ('/', 'http://alt.%s/' % server_name)
        adapter = map.bind_to_environ(env, server_name=server_name)
        self.assertEqual(
            adapter.match(),
            ('alt', {})
        )

        env = create_environ('/', 'http://%s/' % server_name)
        adapter = map.bind_to_environ(env, server_name='foo')
        self.assertEqual(adapter.subdomain, '<invalid>')
예제 #23
0
 def test_path_info_and_script_name_fetching(self):
     env = create_environ('/\N{SNOWMAN}', 'http://example.com/\N{COMET}/')
     self.assertEqual(
         wsgi.get_path_info(env),
         '/\N{SNOWMAN}'
     )
     self.assertEqual(
         wsgi.get_path_info(env, charset=None),
         '/\N{SNOWMAN}'.encode('utf-8')
     )
     self.assertEqual(
         wsgi.get_script_name(env),
         '/\N{COMET}'
     )
     self.assertEqual(
         wsgi.get_script_name(env, charset=None),
         '/\N{COMET}'.encode('utf-8')
     )
예제 #24
0
    def test_etag_response_mixin(self):
        response = Response('Hello World')
        self.assertEqual(response.get_etag(), (None, None))
        response.add_etag()
        self.assertEqual(
            response.get_etag(), ('b10a8db164e0754105b7a99be72e3fe5', False)
        )
        self.assertFalse(response.cache_control)
        response.cache_control.must_revalidate = True
        response.cache_control.max_age = 60
        response.headers['Content-Length'] = len(response.get_data())
        self.assertIn(
            response.headers['Cache-Control'],
            ('must-revalidate, max-age=60', 'max-age=60, must-revalidate')
        )

        self.assertNotIn('date', response.headers)
        env = create_environ()
        env.update({
            'REQUEST_METHOD':       'GET',
            'HTTP_IF_NONE_MATCH':   response.get_etag()[0]
        })
        response.make_conditional(env)
        self.assertIn('date', response.headers)

        # after the thing is invoked by the server as wsgi application
        # (we're emulating this here), there must not be any entity
        # headers left and the status code would have to be 304
        resp = Response.from_app(response, env)
        self.assertEqual(resp.status_code, 304)
        self.assertNotIn('content-length', resp.headers)

        # make sure date is not overriden
        response = Response('Hello World')
        response.date = 1337
        d = response.date
        response.make_conditional(env)
        self.assertEqual(response.date, d)

        # make sure content length is only set if missing
        response = Response('Hello World')
        response.content_length = 999
        response.make_conditional(env)
        self.assertEqual(response.content_length, 999)
예제 #25
0
    def test_etag_response_mixin(self):
        response = Response('Hello World')
        self.assertEqual(response.get_etag(), (None, None))
        response.add_etag()
        self.assertEqual(
            response.get_etag(), ('b10a8db164e0754105b7a99be72e3fe5', False)
        )
        self.assertFalse(response.cache_control)
        response.cache_control.must_revalidate = True
        response.cache_control.max_age = 60
        response.headers['Content-Length'] = len(response.get_data())
        self.assertIn(
            response.headers['Cache-Control'],
            ('must-revalidate, max-age=60', 'max-age=60, must-revalidate')
        )

        self.assertNotIn('date', response.headers)
        env = create_environ()
        env.update({
            'REQUEST_METHOD': 'GET',
            'HTTP_IF_NONE_MATCH': response.get_etag()[0]
        })
        response.make_conditional(env)
        self.assertIn('date', response.headers)

        # after the thing is invoked by the server as wsgi application
        # (we're emulating this here), there must not be any entity
        # headers left and the status code would have to be 304
        resp = Response.from_app(response, env)
        self.assertEqual(resp.status_code, 304)
        self.assertNotIn('content-length', resp.headers)

        # make sure date is not overriden
        response = Response('Hello World')
        response.date = 1337
        d = response.date
        response.make_conditional(env)
        self.assertEqual(response.date, d)

        # make sure content length is only set if missing
        response = Response('Hello World')
        response.content_length = 999
        response.make_conditional(env)
        self.assertEqual(response.content_length, 999)
예제 #26
0
    def test_base_response(self):
        # unicode
        response = BaseResponse(u'öäü')
        self.assertEqual(response.get_data(), u'öäü'.encode('utf-8'))

        # writing
        response = Response('foo')
        response.stream.write('bar')
        self.assertEqual(response.get_data(), b'foobar')

        # set cookie
        response = BaseResponse()
        response.set_cookie('foo', 'bar', 60, 0, '/blub', 'example.org')
        self.assertEqual(response.headers.to_wsgi_list(), [
            ('Content-Type', 'text/plain; charset=utf-8'),
            ('Set-Cookie', (
                'foo=bar; '
                'Domain=example.org; '
                'Expires=Thu, 01-Jan-1970 00:00:00 GMT; '
                'Max-Age=60; '
                'Path=/blub'
            )),
        ])

        # delete cookie
        response = BaseResponse()
        response.delete_cookie('foo')
        self.assertEqual(response.headers.to_wsgi_list(), [
            ('Content-Type', 'text/plain; charset=utf-8'),
            ('Set-Cookie', (
                'foo=; '
                'Expires=Thu, 01-Jan-1970 00:00:00 GMT; '
                'Max-Age=0; '
                'Path=/'
            )),
        ])

        # close call forwarding
        closed = []

        class Iterable(object):

            def __next__(self):
                raise StopIteration()

            def __iter__(self):
                return self

            def close(self):
                closed.append(True)
        response = BaseResponse(Iterable())
        response.call_on_close(lambda: closed.append(True))
        app_iter, status, headers = run_wsgi_app(
            response, create_environ(), buffered=True,
        )
        self.assertEqual(status, '200 OK')
        self.assertEqual(''.join(app_iter), '')
        self.assertEqual(len(closed), 2)

        # with statement
        del closed[:]
        response = BaseResponse(Iterable())
        with response:
            pass
        self.assertEqual(len(closed), 1)
예제 #27
0
    def test_basic_routing(self):
        map = r.URLMap([
            r.Route('/', endpoint='index'),
            r.Route('/foo', endpoint='foo'),
            r.Route('/bar/', endpoint='bar')
        ])
        adapter = map.bind('example.org', '/')
        self.assertEqual(
            adapter.match('/'),
            ('index', {})
        )
        self.assertEqual(
            adapter.match('/foo'),
            ('foo', {})
        )
        self.assertEqual(
            adapter.match('/bar/'),
            ('bar', {})
        )
        self.assertRaises(r.RequestRedirect, lambda: adapter.match('/bar'))
        self.assertRaises(r.NotFound, lambda: adapter.match('/blub'))

        adapter = map.bind('example.org', '/test')
        try:
            adapter.match('/bar')
        except r.RequestRedirect as e:
            self.assertEqual(e.new_url, 'http://example.org/test/bar/')
        else:  # pragma: no cover
            self.fail('Expected request redirect')

        adapter = map.bind('example.org', '/')
        try:
            adapter.match('/bar')
        except r.RequestRedirect as e:
            self.assertEqual(e.new_url, 'http://example.org/bar/')
        else:  # pragma: no cover
            self.fail('Expected request redirect')

        adapter = map.bind('example.org', '/')
        try:
            adapter.match('/bar', query_args={'aha': 'muhaha'})
        except r.RequestRedirect as e:
            self.assertEqual(e.new_url, 'http://example.org/bar/?aha=muhaha')
        else:  # pragma: no cover
            self.fail('Expected request redirect')

        adapter = map.bind('example.org', '/')
        try:
            adapter.match('/bar', query_args='aha=muhaha')
        except r.RequestRedirect as e:
            self.assertEqual(e.new_url, 'http://example.org/bar/?aha=muhaha')
        else:  # pragma: no cover
            self.fail('Expected request redirect')

        adapter = map.bind_to_environ(create_environ('/bar?foo=bar',
                                                     'http://example.org/'))
        try:
            adapter.match()
        except r.RequestRedirect as e:
            self.assertEqual(e.new_url, 'http://example.org/bar/?foo=bar')
        else:  # pragma: no cover
            self.fail('Expected request redirect')
예제 #28
0
 def test_response_304_no_content_length(self):
     resp = Response('Test', status=304)
     env = create_environ()
     self.assertNotIn('content-length', resp.get_wsgi_headers(env))
예제 #29
0
 def test_query_string_fetching(self):
     env = create_environ('/?\N{SNOWMAN}=\N{COMET}')
     qs = wsgi.get_query_string(env)
     self.assertEqual(qs, '%E2%98%83=%E2%98%84')
예제 #30
0
 def test_response_304_no_content_length(self):
     resp = Response('Test', status=304)
     env = create_environ()
     self.assertNotIn('content-length', resp.get_wsgi_headers(env))
예제 #31
0
 def test_query_string_fetching(self):
     env = create_environ('/?\N{SNOWMAN}=\N{COMET}')
     qs = wsgi.get_query_string(env)
     self.assertEqual(qs, '%E2%98%83=%E2%98%84')