def test_type_hints_and_converters(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self, d): self.d = d from datetime import date @app.path(model=Model, path='', converters=dict(d=date)) def get_model(d): return Model(d) @app.view(model=Model) def default(self, request): return "View: %s" % self.d @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('/?d=20140120') assert response.data == "View: 2014-01-20" response = c.get('/link?d=20140120') assert response.data == '/?d=20140120'
class TestXyvio(unittest.TestCase): def setUp(self): self.client = Client(app, BaseResponse) def test_base36_encode(self): self.assertEqual('1', base36_encode(1)) self.assertEqual('a', base36_encode(10)) self.assertEqual('10', base36_encode(36)) self.assertEqual('20', base36_encode(72)) def test_new_url(self): resp = self.client.get('/') self.assertEqual(200, resp.status_code) def test_follow_short_link(self): resp = self.client.get('/some_other_random') self.assertEqual(404, resp.status_code) resp = self.client.get('/1') self.assertEqual(302, resp.status_code) def test_short_link_details(self): resp = self.client.get('/+') self.assertEqual(404, resp.status_code) resp = self.client.get('/1+') self.assertEqual(200, resp.status_code) def test_is_valid_url(self): pass def tearDown(self): pass
def test_simple_CORS(): app = CORSMiddleware(hello_world, hosts=[ "https://example.tld/", "http://example.tld/", "http://example.tld", ]) client = Client(app, Response) rv = client.get("/", headers={"ORIGIN": "https://example.tld"}) assert rv.headers["Access-Control-Allow-Origin"] == "https://example.tld" assert rv.headers["Access-Control-Allow-Headers"] == "Origin, Content-Type" assert rv.headers["Access-Control-Allow-Credentials"] == "true" assert rv.headers["Access-Control-Allow-Methods"] == "GET, POST, PUT, DELETE" assert rv.headers["Access-Control-Expose-Headers"] == "X-Set-Cookie" a = client.get("/", headers={"ORIGIN": "http://example.tld/"}) assert a.headers["Access-Control-Allow-Origin"] == "http://example.tld" b = client.get("/", headers={"ORIGIN": "http://example.tld"}) assert a.headers["Access-Control-Allow-Origin"] == "http://example.tld" c = client.get("/", headers={"ORIGIN": "http://foo.other/"}) assert a.headers["Access-Control-Allow-Origin"] == "http://example.tld"
class ServerTestCase(BaseTestCase): def setUp(self): super(ServerTestCase, self).setUp() self.app = FlaskApp(__name__) self.app.route('/', methods=['POST', 'GET'])(hello_world) ctx = self.app.test_request_context() ctx.push() self.addCleanup(ctx.pop) self.client = Client(self.app, response_wrapper=Response) def test_trace_generated(self): response = self.client.get('/') self.assertEqual(response.status_code, 200) self.assertIn(TRACE_HEADER, response.headers.keys()) def test_trace_is_unique_per_request(self): response = self.client.get('/') value1 = response.headers[TRACE_HEADER] response = self.client.get('/') value2 = response.headers[TRACE_HEADER] self.assertNotEqual(value1, value2) def test_trace_prefixing(self): response = self.client.get('/') value = response.headers[TRACE_HEADER] self.assertTrue(value.startswith(TRACE_PREFIX), value) def test_multiple_requests_appended(self): headers = {TRACE_HEADER: 'Trace123'} response = self.client.get('/', headers=headers) value = response.headers[TRACE_HEADER] self.assertTrue(value.startswith('Trace123,' + TRACE_PREFIX))
def test_mount_context(): app = morepath.App('app') mounted = morepath.App('mounted') class MountedRoot(object): def __init__(self, mount_id): self.mount_id = mount_id def root_default(request, model): return "The root for mount id: %s" % model.mount_id def get_context(id): return { 'mount_id': id } c = setup() c.configurable(app) c.configurable(mounted) c.action(app.mount(path='{id}', app=mounted), get_context) c.action(mounted.root(), MountedRoot) c.action(mounted.view(model=MountedRoot), root_default) c.commit() c = Client(app, Response) response = c.get('/foo') assert response.data == 'The root for mount id: foo' response = c.get('/bar') assert response.data == 'The root for mount id: bar'
class TestPurgeComments(unittest.TestCase): def setUp(self): fd, self.path = tempfile.mkstemp() conf = core.Config.load(None) conf.set("general", "dbpath", self.path) conf.set("moderation", "enabled", "true") conf.set("guard", "enabled", "off") class App(Isso, core.Mixin): pass self.app = App(conf) self.app.wsgi_app = FakeIP(self.app.wsgi_app) self.client = Client(self.app, Response) def testPurgeDoesNoHarm(self): self.client.post('/new?uri=test', data=json.dumps({"text": "..."})) self.app.db.comments.activate(1) self.app.db.comments.purge(0) assert self.client.get('/?uri=test').status_code == 200 def testPurgeWorks(self): self.client.post('/new?uri=test', data=json.dumps({"text": "..."})) self.app.db.comments.purge(0) assert self.client.get('/id/1').status_code == 404 self.client.post('/new?uri=test', data=json.dumps({"text": "..."})) self.app.db.comments.purge(3600) assert self.client.get('/id/1').status_code == 200
def test_url_parameter_implicit_converter(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self, id): self.id = id @app.path(model=Model, path='/') def get_model(id=0): return Model(id) @app.view(model=Model) def default(self, request): return "View: %s (%s)" % (self.id, type(self.id)) @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('/?id=1') assert response.data == "View: 1 (<type 'int'>)" response = c.get('/link?id=1') assert response.data == '/?id=1' response = c.get('/?id=broken') assert response.status == '400 BAD REQUEST' response = c.get('/') assert response.data == "View: 0 (<type 'int'>)"
def test_variable_path_parameter_required_with_default(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self, id): self.id = id @app.path(model=Model, path='', required=['id']) def get_model(id='b'): return Model(id) @app.view(model=Model) def default(self, request): return "View: %s" % self.id @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('/?id=a') assert response.data == "View: a" response = c.get('/') assert response.status == '400 BAD REQUEST'
class TestAlternativeChoice(unittest.TestCase): def setUp(self): self.app = create_app() self.client = Client(self.app, BaseResponse) def test_bots_get_winner_otherwise_control(self): e = Experiment.find_or_create("bots-get-winner", ["one", "two"], self.app.redis) # control at first for i in range(3): data = json.loads(self.client.get("/participate?experiment=bots-get-winner&alternatives=one&alternatives=two&user_agent=GoogleBot&client_id=rand").data) self.assertEqual(data['alternative']['name'], 'one') # winner once one is set e.set_winner("two") for i in range(3): data = json.loads(self.client.get("/participate?experiment=bots-get-winner&alternatives=one&alternatives=two&user_agent=GoogleBot&client_id=rand").data) self.assertEqual(data['alternative']['name'], 'two') def test_force_param_always_wins(self): alts = ["one", "two", "three"] e = Experiment.find_or_create("force-param-always-wins", alts, self.app.redis) def test_force(): for f in alts: data = json.loads(self.client.get("/participate?experiment=force-param-always-wins&alternatives=one&alternatives=two&alternatives=three&client_id=rand&force={0}".format(f)).data) self.assertEqual(data['alternative']['name'], f) # before a winner test_force() e.set_winner("three") # after a winner test_force()
def test_variable_path_two_variables(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self, name, version): self.name = name self.version = version @app.path(model=Model, path='{name}-{version}') def get_model(name, version): return Model(name, version) @app.view(model=Model) def default(self, request): return "View: %s %s" % (self.name, self.version) @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('foo-one') assert response.data == 'View: foo one' response = c.get('/foo-one/link') assert response.data == '/foo-one'
class TestFieldLimiter(TestCase): def setUp(self): app = FieldLimiter(dummy_json_app) self.client = Client(app, BaseResponse) def test_no_limiting(self): resp = self.client.get("/") self.assertEqual(json_resp(resp), test_data) def test_limit_one(self): resp = self.client.get("/?field=message") self.assertEqual(json_resp(resp), {"message": test_data["message"]}) def test_limit_multi(self): fields = ("message", "errors") resp = self.client.get("/?field={}&field={}".format(*fields)) expecting = {k: v for k, v in test_data.items() if k in fields} self.assertEqual(json_resp(resp), expecting) def test_limit_bad(self): with self.assertRaises(BadRequest): resp = self.client.get("/?field=nonexistentfield") def test_list_limit(self): def app(environ, start_response): """Stupid app that sends a deep message: hello world""" response = BaseResponse(json.dumps([test_data] * 2), mimetype="application/json") return response(environ, start_response) wrapped = FieldLimiter(app) c = Client(wrapped, BaseResponse) resp = c.get("/?field=message") self.assertEqual(json_resp(resp), [{"message": test_data["message"]}] * 2)
def test_error_render_count(): class AccumErrorHandler(ErrorHandler): def render_error(self, _error, request, error_list, **kwargs): if 'reraise' in request.path: raise _error if 'badgateway' in request.path: _error = BadGateway() error_list.append(_error) return _error rt = Route('/<number:int>/<option?>', odd_endpoint, render_basic) error_list = [] rsrc = {'error_list': error_list} app = Application([rt], rsrc, error_handler=AccumErrorHandler()) cl = Client(app, BaseResponse) err_resp = cl.get('/39') yield eq_, err_resp.status_code, 200 err_resp = cl.get('/2') yield eq_, err_resp.status_code, 500 yield eq_, len(error_list), 1 # reraising means the error will be handled by the default # handler, so no length change should occur err_resp = cl.get('/4/reraise') yield eq_, err_resp.status_code, 500 yield eq_, len(error_list), 1 err_resp = cl.get('/6/badgateway') #if err_resp.status_code != 502: # import pdb;pdb.set_trace() yield eq_, err_resp.status_code, 502 yield eq_, len(error_list), 2
def test_overrides_model(): config = setup() app = App(testing_config=config) overriding = App(extends=[app], testing_config=config) @app.path(path='users/{username}') class User(object): def __init__(self, username): self.username = username @app.view(model=User) def render_user(self, request): return "User: %s" % self.username @overriding.path(model=User, path='users/{username}') def get_user(username): if username != 'bar': return None return User(username) config.commit() cl = Client(app, Response) response = cl.get('/users/foo') assert response.data == 'User: foo' response = cl.get('/users/bar') assert response.data == 'User: bar' cl = Client(overriding, Response) response = cl.get('/users/foo') assert response.status == '404 NOT FOUND' response = cl.get('/users/bar') assert response.data == 'User: bar'
class WebsiteTest(TestCase): SQLALCHEMY_DATABASE_URI = 'sqlite://' TESTING = True def create_app(self): return application def setUp(self): db.create_all() self.client = Client(application, BaseResponse) def tearDown(self): db.session.remove() db.drop_all() def test_home_page_status_code(self): response = self.client.get('/') self.assertEqual(response.status_code, 200) def test_manage_page_status_code(self): response = self.client.get('/manage') self.assertEqual(response.status_code, 200)
def test_extends(): config = setup() app = App(testing_config=config) extending = App(extends=[app], testing_config=config) @app.path(path='users/{username}') class User(object): def __init__(self, username): self.username = username @app.view(model=User) def render_user(self, request): return "User: %s" % self.username @extending.view(model=User, name='edit') def edit_user(self, request): return "Edit user: %s" % self.username config.commit() cl = Client(app, Response) response = cl.get('/users/foo') assert response.data == 'User: foo' response = cl.get('/users/foo/edit') assert response.status == '404 NOT FOUND' cl = Client(extending, Response) response = cl.get('/users/foo') assert response.data == 'User: foo' response = cl.get('/users/foo/edit') assert response.data == 'Edit user: foo'
def test_overrides_view(): config = setup() app = App(testing_config=config) overriding = App(extends=[app], testing_config=config) @app.path(path='users/{username}') class User(object): def __init__(self, username): self.username = username @app.view(model=User) def render_user(self, request): return "User: %s" % self.username @overriding.view(model=User) def render_user2(self, request): return "USER: %s" % self.username config.commit() cl = Client(app, Response) response = cl.get('/users/foo') assert response.data == 'User: foo' cl = Client(overriding, Response) response = cl.get('/users/foo') assert response.data == 'USER: foo'
def test_mount_empty_context(): app = morepath.App('app') mounted = morepath.App('mounted') class MountedRoot(object): pass def root_default(request, model): return "The root" def root_link(request, model): return request.link(model) def get_context(): pass c = setup() c.configurable(app) c.configurable(mounted) c.action(app.mount(path='{id}', app=mounted), get_context) c.action(mounted.root(), MountedRoot) c.action(mounted.view(model=MountedRoot), root_default) c.action(mounted.view(model=MountedRoot, name='link'), root_link) c.commit() c = Client(app, Response) response = c.get('/foo') assert response.data == 'The root' response = c.get('/foo/link') assert response.data == 'foo'
class TestModeratedComments(unittest.TestCase): def setUp(self): fd, self.path = tempfile.mkstemp() conf = core.Config.load(None) conf.set("general", "dbpath", self.path) conf.set("moderation", "enabled", "true") conf.set("guard", "enabled", "off") class App(Isso, core.Mixin): pass self.app = App(conf) self.app.wsgi_app = FakeIP(self.app.wsgi_app) self.client = Client(self.app, Response) def tearDown(self): os.unlink(self.path) def testAddComment(self): rv = self.client.post('/new?uri=test', data=json.dumps({"text": "..."})) assert rv.status_code == 202 assert self.client.get('/id/1').status_code == 200 assert self.client.get('/?uri=test').status_code == 404 self.app.db.comments.activate(1) assert self.client.get('/?uri=test').status_code == 200
def test_full_flow(self, satosa_config_dict, account_linking_module_config): api_url = "https://alservice.example.com/api" redirect_url = "https://alservice.examle.com/redirect" account_linking_module_config["config"]["api_url"] = api_url account_linking_module_config["config"]["redirect_url"] = redirect_url satosa_config_dict["MICRO_SERVICES"].insert(0, account_linking_module_config) # application test_client = Client(make_app(SATOSAConfig(satosa_config_dict)), BaseResponse) # incoming auth req http_resp = test_client.get("/{}/{}/request".format(satosa_config_dict["BACKEND_MODULES"][0]["name"], satosa_config_dict["FRONTEND_MODULES"][0]["name"])) assert http_resp.status_code == 200 with responses.RequestsMock() as rsps: # fake no previous account linking rsps.add(responses.GET, "{}/get_id".format(api_url), "test_ticket", status=404) # incoming auth resp http_resp = test_client.get("/{}/response".format(satosa_config_dict["BACKEND_MODULES"][0]["name"])) assert http_resp.status_code == 302 assert http_resp.headers["Location"].startswith(redirect_url) with responses.RequestsMock() as rsps: # fake previous account linking rsps.add(responses.GET, "{}/get_id".format(api_url), "test_userid", status=200) # incoming account linking response http_resp = test_client.get("/account_linking/handle_account_linking") assert http_resp.status_code == 200
def test_default_render(): app = Application([('/', hello_world_ctx, render_basic), ('/<name>/', hello_world_ctx, render_basic), ('/text/<name>/', hello_world_str, render_basic), ('/html/<name>/', hello_world_html, render_basic), ('/beta/<name>/', complex_context, render_basic)]) yield ok_, callable(app.routes[0]._execute) yield ok_, callable(app.routes[0]._render) c = Client(app, BaseResponse) resp = c.get('/') # test simple json with endpoint default yield eq_, resp.status_code, 200 resp_data = json.loads(resp.data) yield eq_, resp_data['name'], 'world' resp = c.get('/Kurt/') # test simple json with url param yield eq_, resp.status_code, 200 resp_data = json.loads(resp.data) yield eq_, resp_data['name'], 'Kurt' resp = c.get('/beta/Rajkumar/') # test fancy json yield eq_, resp.status_code, 200 resp_data = json.loads(resp.data) yield eq_, resp_data['name'], 'Rajkumar' yield ok_, resp_data['date'] yield ok_, len(resp_data) > 4 resp = c.get('/text/Noam/') # test text yield eq_, resp.status_code, 200 yield eq_, resp.data, 'Hello, Noam!' resp = c.get('/html/Asia/') # test basic html yield eq_, resp.status_code, 200 yield ok_, 'text/html' in resp.headers['Content-Type']
class TestWSGI(unittest.TestCase): def setUp(self): module_path = os.path.dirname(os.path.abspath(__file__)) self.test_project = os.path.join(module_path, 'testproject') self.app = shortstack.wsgi.Shortstack('shortstack', instance_path=self.test_project) self.client = Client(self.app, BaseResponse) def test_render_through_app(self): look_for = "This text only exists in the base template" response_implied_index = self.client.get('/') response_explicit_index = self.client.get('/index.html') self.assertIn(look_for, str(response_implied_index.data)) self.assertEqual(response_implied_index.data, response_explicit_index.data) def test_build_search_path(self): search_path = self.app.build_search_path('/foo/bar/baz/index.html') first_item_should_be = os.path.join(self.test_project,'foo/bar/baz/') self.assertEqual(first_item_should_be, search_path[0]) self.assertEqual(self.test_project, os.path.normpath(search_path[-1])) def test_add_slash(self): response = self.client.get('/foo') self.assertEqual(response.status_code, 302) self.assertIn('Location', response.headers) self.assertEqual(response.headers['Location'], "http://localhost/foo/")
def test_json_render(render_json=None): if render_json is None: render_json = JSONRender(dev_mode=True) app = Application([('/', hello_world_ctx, render_json), ('/<name>/', hello_world_ctx, render_json), ('/beta/<name>/', complex_context, render_json)]) yield ok_, callable(app.routes[0]._execute) yield ok_, callable(app.routes[0]._render) c = Client(app, BaseResponse) resp = c.get('/') yield eq_, resp.status_code, 200 resp_data = json.loads(resp.data) yield eq_, resp_data['name'], 'world' resp = c.get('/Kurt/') yield eq_, resp.status_code, 200 resp_data = json.loads(resp.data) yield eq_, resp_data['name'], 'Kurt' resp = c.get('/beta/Rajkumar/') yield eq_, resp.status_code, 200 resp_data = json.loads(resp.data) yield eq_, resp_data['name'], 'Rajkumar' yield ok_, resp_data['date'] yield ok_, len(resp_data) > 4
class WebIntegrationTest(unittest.TestCase): def setUp(self): super(WebIntegrationTest, self).setUp() container = mock.Mock() container.debug = False self.interface = Web(container) self.http_client = Client(self.interface.application, BaseResponse) def test_dispatch_rule_with_string_endpoint(self): response = self.http_client.get("/test/") self.assertEqual(response.data.decode("utf8"), "method test") self.assertEqual(response.status_code, 200) def test_dispatch_rule_with_callable_endpoint(self): response = self.http_client.get("/foo/") self.assertEqual(response.data.decode("utf8"), "Rule Handler") self.assertEqual(response.status_code, 200) def test_dispatch_handled_rule(self): response = self.http_client.get("/bar/") self.assertEqual(response.data.decode("utf8"), "Handled Rule Handler") self.assertEqual(response.status_code, 200) def test_dispatch_failing_rule_to_500(self): response = self.http_client.get("/fail/") self.assertEqual(response.data.decode("utf8"), "") self.assertEqual(response.status_code, 500) def test_dispatch_failing_endpoint_to_500(self): response = self.http_client.get("/fail-wrong-endpoint/") self.assertEqual(response.data.decode("utf8"), "") self.assertEqual(response.status_code, 500)
def test_simple(self): app = CORSMiddleware(hello_world, origin=origin([ "https://example.tld/", "http://example.tld/", ]), allowed=("Foo", "Bar"), exposed=("Spam", )) client = Client(app, Response) rv = client.get("/", headers={"Origin": "https://example.tld"}) self.assertEqual( rv.headers["Access-Control-Allow-Origin"], "https://example.tld") self.assertEqual( rv.headers["Access-Control-Allow-Credentials"], "true") self.assertEqual( rv.headers["Access-Control-Allow-Methods"], "HEAD, GET, POST, PUT, DELETE") self.assertEqual( rv.headers["Access-Control-Allow-Headers"], "Foo, Bar") self.assertEqual(rv.headers["Access-Control-Expose-Headers"], "Spam") a = client.get("/", headers={"Origin": "http://example.tld"}) self.assertEqual( a.headers["Access-Control-Allow-Origin"], "http://example.tld") b = client.get("/", headers={"Origin": "http://example.tld"}) self.assertEqual( b.headers["Access-Control-Allow-Origin"], "http://example.tld") c = client.get("/", headers={"Origin": "http://foo.other"}) self.assertEqual( c.headers["Access-Control-Allow-Origin"], "https://example.tld")
def test_auth_unique_uri(self): from rest_api_framework.pagination import Pagination ressources = [{"id": "azerty"}] authentication = ApiKeyAuthentication( PythonListDataStore(ressources, ApiModel) ) class ApiAppAuth(ApiApp): controller = { "list_verbs": ["GET", "POST"], "unique_verbs": ["GET", "PUT", "DElETE"], "options": {"pagination": Pagination(20), "authentication": authentication, "authorization": ApiKeyAuthorization } } client = Client( WSGIDispatcher([ApiAppAuth]), response_wrapper=BaseResponse) resp = client.get("/address/1/?apikey=azerty") self.assertEqual(resp.status_code, 200) resp = client.get("/address/1/?apikey=querty") self.assertEqual(resp.status_code, 401)
def test_variable_path_explicit_trumps_implicit(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self, id): self.id = id @app.path(model=Model, path='{id}', converters=dict(id=Converter(int))) def get_model(id='foo'): return Model(id) @app.view(model=Model) def default(self, request): return "View: %s (%s)" % (self.id, type(self.id)) @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('1') assert response.data == "View: 1 (<type 'int'>)" response = c.get('/1/link') assert response.data == '/1' response = c.get('broken') assert response.status == '404 NOT FOUND'
def test_variable_path_one_step(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self, name): self.name = name @app.path(model=Model, path='{name}') def get_model(name): return Model(name) @app.view(model=Model) def default(self, request): return "View: %s" % self.name @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('/foo') assert response.data == 'View: foo' response = c.get('/foo/link') assert response.data == '/foo'
def test_simple_path_two_steps(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self): pass @app.path(model=Model, path='one/two') def get_model(): return Model() @app.view(model=Model) def default(self, request): return "View" @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('/one/two') assert response.data == 'View' response = c.get('/one/two/link') assert response.data == '/one/two'
def test_wsgi_sass_middleware(self): css_dir = tempfile.mkdtemp() src_dir = os.path.join(css_dir, 'src') shutil.copytree('test', src_dir) try: app = SassMiddleware(self.sample_wsgi_app, { __name__: (src_dir, css_dir, '/static') }) client = Client(app, Response) r = client.get('/asdf') self.assertEqual(200, r.status_code) self.assert_bytes_equal(b'/asdf', r.data) self.assertEqual('text/plain', r.mimetype) r = client.get('/static/a.scss.css') self.assertEqual(200, r.status_code) src_path = normalize_path(os.path.join(src_dir, 'a.scss')) self.assert_bytes_equal( b(A_EXPECTED_CSS_WITH_MAP.replace('SOURCE', src_path)), r.data ) self.assertEqual('text/css', r.mimetype) r = client.get('/static/not-exists.sass.css') self.assertEqual(200, r.status_code) self.assert_bytes_equal(b'/static/not-exists.sass.css', r.data) self.assertEqual('text/plain', r.mimetype) finally: shutil.rmtree(css_dir)
def test_link_for_none_means_no_parameter(): config = setup() app = morepath.App(testing_config=config) class Model(object): def __init__(self, id): self.id = id @app.path(model=Model, path='') def get_model(id): return Model(id) @app.view(model=Model) def default(self, request): return "View: %s" % self.id @app.view(model=Model, name='link') def link(self, request): return request.link(self) config.commit() c = Client(app, Response) response = c.get('/') assert response.data == "View: None" response = c.get('/link') assert response.data == '/'
def test_base_pagination_count_offset(self): client = Client(WSGIDispatcher([SQLiteApp]), response_wrapper=BaseResponse) for i in range(100): client.post("/address/", data=json.dumps({ "name": "bob", "age": 34 })) resp = client.get("/address/?count=2&offset=4") self.assertEqual(len(json.loads(resp.data)), 2) self.assertEqual(json.loads(resp.data)["object_list"][0]['id'], 4) os.remove("test.db")
def test_redirect_mutate_environ(): @Request.application def app(request): if request.path == "/first": return redirect("/prefix/second") return Response(request.path) def middleware(environ, start_response): # modify the environ in place, shouldn't propagate to redirect request pop_path_info(environ) return app(environ, start_response) c = Client(middleware) rv = c.get("/prefix/first", follow_redirects=True) # if modified environ was used by client, this would be / assert rv.data == b"/second"
def test_custom_error_handler(app): class CustomException(Exception): pass def raise_error(): raise CustomException('bad') func = MagicMock(testfunc, side_effect=raise_error) app.route('/foobar')(func) app.add_exception(CustomException) client = Client(app.create_app(), response_wrapper=Response) response = client.get('/foobar') assert response.status_code == 400 assert response.data == b'"bad"' assert response.content_type == 'application/json'
def test_base_request(): client = Client(request_demo_app, RequestTestResponse) # get requests response = client.get("/?foo=bar&foo=hehe") strict_eq(response["args"], MultiDict([("foo", u"bar"), ("foo", u"hehe")])) strict_eq(response["args_as_list"], [("foo", [u"bar", u"hehe"])]) strict_eq(response["form"], MultiDict()) strict_eq(response["form_as_list"], []) strict_eq(response["data"], b"") assert_environ(response["environ"], "GET") # post requests with form data response = client.post( "/?blub=blah", data="foo=blub+hehe&blah=42", content_type="application/x-www-form-urlencoded", ) strict_eq(response["args"], MultiDict([("blub", u"blah")])) strict_eq(response["args_as_list"], [("blub", [u"blah"])]) strict_eq(response["form"], MultiDict([("foo", u"blub hehe"), ("blah", u"42")])) strict_eq(response["data"], b"") # currently we do not guarantee that the values are ordered correctly # for post data. # strict_eq(response['form_as_list'], [('foo', ['blub hehe']), ('blah', ['42'])]) assert_environ(response["environ"], "POST") # patch requests with form data response = client.patch( "/?blub=blah", data="foo=blub+hehe&blah=42", content_type="application/x-www-form-urlencoded", ) strict_eq(response["args"], MultiDict([("blub", u"blah")])) strict_eq(response["args_as_list"], [("blub", [u"blah"])]) strict_eq(response["form"], MultiDict([("foo", u"blub hehe"), ("blah", u"42")])) strict_eq(response["data"], b"") assert_environ(response["environ"], "PATCH") # post requests with json data json = b'{"foo": "bar", "blub": "blah"}' response = client.post("/?a=b", data=json, content_type="application/json") strict_eq(response["data"], json) strict_eq(response["args"], MultiDict([("a", u"b")])) strict_eq(response["form"], MultiDict())
def runtest(self): fs = self._prepareMockFs() url = self.spec.get('url') if url is None: raise Exception("Missing URL in test spec.") expected_status = self.spec.get('status', 200) expected_headers = self.spec.get('headers') expected_output = self.spec.get('out') expected_contains = self.spec.get('out_contains') from werkzeug.test import Client from werkzeug.wrappers import BaseResponse from piecrust.app import PieCrustFactory from piecrust.serving.server import PieCrustServer with mock_fs_scope(fs, keep=self.mock_debug): appfactory = PieCrustFactory(fs.path('/kitchen'), theme_site=self.is_theme_site) server = PieCrustServer(appfactory) client = Client(server, BaseResponse) resp = client.get(url) if expected_status != resp.status_code: raise UnexpectedChefServingError( url, "Expected HTTP status '%s', got '%s'" % (expected_status, resp.status_code), resp) cctx = CompareContext() if expected_headers: for k, v in expected_headers.items(): cmpres = _compare_str(v, resp.headers.get(k), cctx) if cmpres: raise UnexpectedChefServingOutput(cmpres) actual = resp.data.decode('utf8').rstrip() if expected_output: cmpres = _compare_str(expected_output.rstrip(), actual, cctx) if cmpres: raise UnexpectedChefServingOutput(cmpres) if expected_contains: assert expected_contains.rstrip() in actual
def test_base_request(): client = Client(request_demo_app) # get requests response = client.get("/?foo=bar&foo=hehe") request = response.request assert request.args == MultiDict([("foo", "bar"), ("foo", "hehe")]) assert request.form == MultiDict() assert request.data == b"" assert_environ(request.environ, "GET") # post requests with form data response = client.post( "/?blub=blah", data="foo=blub+hehe&blah=42", content_type="application/x-www-form-urlencoded", ) request = response.request assert request.args == MultiDict([("blub", "blah")]) assert request.form == MultiDict([("foo", "blub hehe"), ("blah", "42")]) assert request.data == b"" # currently we do not guarantee that the values are ordered correctly # for post data. # assert response['form_as_list'] == [('foo', ['blub hehe']), ('blah', ['42'])] assert_environ(request.environ, "POST") # patch requests with form data response = client.patch( "/?blub=blah", data="foo=blub+hehe&blah=42", content_type="application/x-www-form-urlencoded", ) request = response.request assert request.args == MultiDict([("blub", "blah")]) assert request.form == MultiDict([("foo", "blub hehe"), ("blah", "42")]) assert request.data == b"" assert_environ(request.environ, "PATCH") # post requests with json data json = b'{"foo": "bar", "blub": "blah"}' response = client.post("/?a=b", data=json, content_type="application/json") request = response.request assert request.data == json assert request.args == MultiDict([("a", "b")]) assert request.form == MultiDict()
def test_exc_divider_found_on_chained_exception(self): @Request.application def app(request): def do_something(): raise ValueError("inner") try: do_something() except ValueError: raise KeyError("outer") # noqa: B904 debugged = DebuggedApplication(app) client = Client(debugged) response = client.get("/") data = response.get_data(as_text=True) assert 'raise ValueError("inner")' in data assert '<div class="exc-divider">' in data assert 'raise KeyError("outer")' in data
def test_get_pipeline(): db = get_db()() pl = random_pipeline() db.add(pl) db.commit() app = make_app() c = Client(app, Resp) url = unwrap_app(app).url( 'pipeline_detail', dict( service_name=pl.service.name, pipeline_name=pl.name, )) resp = c.get(url) assert resp.status_code == 200 data = resp.json() assert data['name'] == pl.name assert data['service_id'] == pl.service.id
class AuthTestCase(unittest.TestCase): def setUp(self): from klangbecken.api import klangbecken_api with mock.patch("klangbecken.api.DEFAULT_UPLOAD_ANALYZERS", [lambda *args: []]), mock.patch( "klangbecken.api.DEFAULT_UPDATE_ANALYZERS", [lambda *args: []]), mock.patch( "klangbecken.api.DEFAULT_PROCESSORS", [lambda *args: None]): app = klangbecken_api( "very secret", "inexistent_dir", "nix.sock", ) self.client = Client(app) def testFailingAuth(self): resp = self.client.post("/playlist/music/") self.assertEqual(resp.status_code, 401) resp = self.client.put("/playlist/jingles/" + str(uuid.uuid4()) + ".mp3") self.assertEqual(resp.status_code, 401) resp = self.client.delete("/playlist/music/" + str(uuid.uuid4()) + ".ogg") self.assertEqual(resp.status_code, 401) def testFailingLogin(self): resp = self.client.get("/auth/login/") self.assertEqual(resp.status_code, 401) self.assertNotIn("Set-Cookie", resp.headers) resp = self.client.post("/auth/login/") self.assertEqual(resp.status_code, 401) self.assertNotIn("Set-Cookie", resp.headers) def testLogin(self): resp = self.client.post("/auth/login/", environ_base={"REMOTE_USER": "******"}) self.assertEqual(resp.status_code, 200) response_data = json.loads(resp.data) self.assertIn("token", response_data) self.assertRegex(response_data["token"], r"([a-zA-Z0-9_-]+\.){2}[a-zA-Z0-9_-]+")
def test_base_request(): client = Client(request_demo_app, RequestTestResponse) # get requests response = client.get('/?foo=bar&foo=hehe') strict_eq(response['args'], MultiDict([('foo', u'bar'), ('foo', u'hehe')])) strict_eq(response['args_as_list'], [('foo', [u'bar', u'hehe'])]) strict_eq(response['form'], MultiDict()) strict_eq(response['form_as_list'], []) strict_eq(response['data'], b'') assert_environ(response['environ'], 'GET') # post requests with form data response = client.post('/?blub=blah', data='foo=blub+hehe&blah=42', content_type='application/x-www-form-urlencoded') strict_eq(response['args'], MultiDict([('blub', u'blah')])) strict_eq(response['args_as_list'], [('blub', [u'blah'])]) strict_eq(response['form'], MultiDict([('foo', u'blub hehe'), ('blah', u'42')])) strict_eq(response['data'], b'') # currently we do not guarantee that the values are ordered correctly # for post data. # strict_eq(response['form_as_list'], [('foo', ['blub hehe']), ('blah', ['42'])]) assert_environ(response['environ'], 'POST') # patch requests with form data response = client.patch('/?blub=blah', data='foo=blub+hehe&blah=42', content_type='application/x-www-form-urlencoded') strict_eq(response['args'], MultiDict([('blub', u'blah')])) strict_eq(response['args_as_list'], [('blub', [u'blah'])]) strict_eq(response['form'], MultiDict([('foo', u'blub hehe'), ('blah', u'42')])) strict_eq(response['data'], b'') assert_environ(response['environ'], 'PATCH') # post requests with json data json = b'{"foo": "bar", "blub": "blah"}' response = client.post('/?a=b', data=json, content_type='application/json') strict_eq(response['data'], json) strict_eq(response['args'], MultiDict([('a', u'b')])) strict_eq(response['form'], MultiDict())
def build(writer='default', config=configfile, force=False, source='default'): from warnings import catch_warnings from werkzeug.test import Client from werkzeug.wrappers import BaseResponse cfg = load_config(config, source) scan(cfg) client = Client(cfg.application, BaseResponse) with catch_warnings(record=True) as warnings: with cfg.writers[writer] as w: for url in find_all(cfg): w.write_file(url, client.get(url, base_url=w.base_url).data) for w in warnings: print("{}: {}".format(w.category.__name__, w.message)) if not force and warnings: quit(1)
def test_vote_gating(*, authenticated_client: Client, conference: Conference, user: User) -> None: """Test that votes are gated correctly for a category.""" talk1 = Talk(title="", length=1, is_anonymized=True) talk2 = Talk(title="", length=1, is_anonymized=True) category = Category(conference=conference, name="") vote = Vote(talk=talk1, user=user) category.talks.append(talk1) category.talks.append(talk2) db.session.add_all((category, talk1, talk2, vote)) db.session.commit() public_id = str(vote.public_id) resp = authenticated_client.get(f"/vote/category/{category.category_id}") assert resp.status_code == 302 assert resp.headers["Location"].endswith(f"/vote/cast/{public_id}") assert Vote.query.count() == 1 assert Vote.query.filter_by(talk_id=2).count() == 0
def from_wsgi( schema_path: str, app: Any, *, base_url: Optional[str] = None, method: Optional[Filter] = None, endpoint: Optional[Filter] = None, tag: Optional[Filter] = None, operation_id: Optional[Filter] = None, skip_deprecated_operations: bool = False, validate_schema: bool = True, force_schema_version: Optional[str] = None, data_generation_methods: DataGenerationMethodInput = DEFAULT_DATA_GENERATION_METHODS, code_sample_style: str = CodeSampleStyle.default().name, **kwargs: Any, ) -> BaseOpenAPISchema: """Load Open API schema from a WSGI app. :param str schema_path: An in-app relative URL to the schema. :param app: A WSGI app instance. """ require_relative_url(schema_path) setup_headers(kwargs) client = Client(app, WSGIResponse) response = client.get(schema_path, **kwargs) HTTPError.check_response(response, schema_path) return from_file( response.data, app=app, base_url=base_url, method=method, endpoint=endpoint, tag=tag, operation_id=operation_id, skip_deprecated_operations=skip_deprecated_operations, validate_schema=validate_schema, force_schema_version=force_schema_version, data_generation_methods=data_generation_methods, code_sample_style=code_sample_style, location=schema_path, )
def test_that_ctfd_can_be_deployed_in_subdir(): """Test that CTFd can be deployed in a subdirectory""" # This test is quite complicated. I do not suggest modifying it haphazardly. # Flask is automatically inserting the APPLICATION_ROOT into the # test urls which means when we hit /setup we hit /ctf/setup. # You can use the raw Werkzeug client to bypass this as we do below. app = create_ctfd(setup=False, application_root="/ctf") with app.app_context(): with app.test_client() as client: r = client.get("/") assert r.status_code == 302 assert r.location == "http://localhost/ctf/setup" r = client.get("/setup") with client.session_transaction() as sess: data = { "ctf_name": "CTFd", "ctf_description": "CTF description", "name": "admin", "email": "*****@*****.**", "password": "******", "user_mode": "users", "nonce": sess.get("nonce"), } r = client.post("/setup", data=data) assert r.status_code == 302 assert r.location == "http://localhost/ctf/" c = Client(app) app_iter, status, headers = c.get("/") headers = dict(headers) assert status == "302 FOUND" assert headers["Location"] == "http://localhost/ctf/" r = client.get("/challenges") assert r.status_code == 200 assert "Challenges" in r.get_data(as_text=True) r = client.get("/scoreboard") assert r.status_code == 200 assert "Scoreboard" in r.get_data(as_text=True) destroy_ctfd(app)
class TestSQLTapMiddleware(TestSQLTap): def setUp(self): super(TestSQLTapMiddleware, self).setUp() from werkzeug.testapp import test_app self.app = sqltap.wsgi.SQLTapMiddleware(app=test_app) self.client = Client(self.app, BaseResponse) def test_can_construct_wsgi_wrapper(self): """ Only verifies that the imports and __init__ work, not a real Test. """ sqltap.wsgi.SQLTapMiddleware(self.app) def test_wsgi_get_request(self): """Verify we can get the middleware path""" response = self.client.get(self.app.path) assert response.status_code == 200 assert 'text/html' in response.headers['content-type'] def test_wsgi_post_turn_on(self): """Verify we can POST turn=on to middleware""" response = self.client.post(self.app.path, data='turn=on') assert response.status_code == 200 assert 'text/html' in response.headers['content-type'] def test_wsgi_post_turn_off(self): """Verify we can POST turn=off to middleware""" response = self.client.post(self.app.path, data='turn=off') assert response.status_code == 200 assert 'text/html' in response.headers['content-type'] def test_wsgi_post_turn_400(self): """Verify we POSTing and invalid turn value returns a 400""" response = self.client.post(self.app.path, data='turn=invalid_string') assert response.status_code == 400 assert 'text/plain' in response.headers['content-type'] def test_wsgi_post_clear(self): """Verify we can POST clean=1 works""" response = self.client.post(self.app.path, data='clear=1') assert response.status_code == 200 assert 'text/html' in response.headers['content-type']
def test_wsgi_sass_middleware_without_extension(self): with tempdir() as css_dir: src_dir = os.path.join(css_dir, 'src') shutil.copytree('test', src_dir) app = SassMiddleware( self.sample_wsgi_app, { __name__: { 'sass_path': src_dir, 'css_path': css_dir, 'wsgi_path': '/static', 'strip_extension': True, }, }, ) client = Client(app, Response) r = client.get('/static/a.css') assert r.status_code == 200 expected = A_EXPECTED_CSS_WITH_MAP.replace('.scss.css', '.css') self.assertEqual(expected.encode(), r.data) assert r.mimetype == 'text/css'
def test_script_name(self): self.middleware_called = False router = Router() @router.pipe('/img') def images(req, res, next): self.middleware_called = True self.assertEqual(req.environ['SCRIPT_NAME'], '/flower/') return next(req, res) @router.get('/img/flower') def index(req, res): res.set_data('Flower') return res c = Client(router.build(), Response) res = c.get('/img/flower') self.assertEqual(res.data, b'Flower') self.assertTrue(self.middleware_called)
def test_prompt_for_demographic_survey(client: Client, user: User) -> None: client.get("/test-login/{}".format(user.user_id)) resp = client.get("/talks") assert_html_response_doesnt_contain(resp, "demographic survey") talk = Talk(title="My Talk", length=25) talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(talk) db.session.commit() client.get("/test-login/{}".format(user.user_id)) resp = client.get("/talks") assert_html_response_contains(resp, "demographic_survey")
def test_json_filter_good_1(): dealer = Chapter_12.ch12_r01.DealCards(hand_size=6, seed=42) json_wrapper = Chapter_12.ch12_r01.JSON_Filter(dealer) client = Client(json_wrapper) response, status, headers = client.get( headers={"Accept": "application/json"}) assert status == "200 OK" assert dict(headers) == {"Content-Type": "application/json;charset=utf-8"} response = b"".join(response) assert json.loads(response) == [ { "__class__": "Card", "rank": 3, "suit": "♡" }, { "__class__": "Card", "rank": 6, "suit": "♣" }, { "__class__": "Card", "rank": 7, "suit": "♡" }, { "__class__": "Card", "rank": 1, "suit": "♣" }, { "__class__": "Card", "rank": 6, "suit": "♡" }, { "__class__": "Card", "rank": 10, "suit": "♢" }, ]
def test_basic_static_serve(): static_app = StaticApplication(_CUR_DIR) app = Application([('/static/', static_app)]) c = Client(app, Response) resp = c.get('/static/test_static.py') yield eq_, resp.mimetype, 'text/x-python' resp = c.get('/static/test_static.pyc') yield eq_, resp.mimetype, 'application/x-python-code' resp = c.get('/static/does_not_exist.txt') yield eq_, resp.status_code, 404 resp = c.get('/static/../core.py') yield eq_, resp.status_code, 403 resp = c.get('/static/_ashes_tmpls/basic_template.html') yield eq_, resp.status_code, 200 resp = c.get('/static/_ashes_tmpls/../../core.py') yield eq_, resp.status_code, 403 resp = c.get('/static//etc/hosts') yield eq_, resp.status_code, 403
def test_one_error_handler_called(self): """Test an error handler is called with the app, the request and the exception.""" app = TrytondWSGI() spy = Mock() @app.error_handler def _handler(*args, **kwargs): spy(*args, **kwargs) exception = self.TestException('foo') @app.route('/willfail') def _route(request): sentinel.request = request raise exception client = Client(app) _ = client.get('/willfail') spy.assert_called_once_with(app, sentinel.request, exception)
def test_error_handlers_last_response(self): "Test last handler response is used" app = TrytondWSGI() @app.error_handler def _handler1(*args, **kwargs): return Response(b'bar') @app.error_handler def _handler2(*args, **kwargs): return Response(b'baz', status=418) @app.route('/willfail') def _route(request): raise self.TestException('foo') client = Client(app) response = client.get('/willfail') self.assertEqual(next(response.response), b'baz') self.assertEqual(response.status, "418 I'M A TEAPOT")
def test_get_bot_ims(internal_client: Client, mocker: MockerFixture): get_ims = mocker.patch("omnibot.services.slack.get_ims") mock_im = { "id": "TEST_IM_ID", "created": 0, "is_im": True, "is_org_shared": True, "user": "******", "is_user_deleted": False, "priority": 0, } mock_ims_value = [( "TEST_IM_ID", json.dumps(mock_im), )] get_ims.return_value = mock_ims_value resp: Response = internal_client.get( "/api/v1/slack/get_ims/test-team-name/TEST_OMNIBOT_NAME") assert resp.status_code == 200 assert resp.json == {"ims": [mock_im]} get_ims.assert_called_once_with(get_test_bot())
def test_get_user_v2_user_found(internal_client: Client, mocker: MockerFixture): get_user_by_email = mocker.patch( "omnibot.services.slack.get_user_by_email") get_user_by_email.return_value = { "profile": { "display_name": "testuser" }, "id": "test_user_id", } resp: Response = internal_client.get( "/api/v1/slack/get_user/test-team-name/TEST_OMNIBOT_NAME/[email protected]" ) assert resp.status_code == 200 user_resp = resp.json["user"] assert user_resp["email"] == "*****@*****.**" assert user_resp["name"] == "testuser" assert user_resp["team_id"] == "TEST_TEAM_ID" assert user_resp["user_id"] == "test_user_id" get_user_by_email.assert_called_once_with(get_test_bot(), "*****@*****.**")
def test_fields(api: Client): def get_items(): return api.get("/entries").get_json()["_items"] # Add a valid entry assert 201 == api.post("/entries", json={"a": "foo"}).status_code items = get_items() assert len(items) == 1 item = items[0] assert S({ "a": "foo", "id": str, "created_at": str, "updated_at": str }) == item # Retrieve the single item and check that it is identical response = api.get("/entries/{}".format(item["id"])) assert 200 == response.status_code assert item == response.get_json()
def test_choose_vote(*, authenticated_client: Client, conference: Conference, user: User) -> None: """Test that votes are created correctly for a category.""" talk1 = Talk(title="", length=1, is_anonymized=True) category1 = Category(conference=conference, name="1") category1.talks.append(talk1) talk2 = Talk(title="", length=1, is_anonymized=True) category2 = Category(conference=conference, name="2") category2.talks.append(talk2) db.session.add_all((talk1, talk2, category1, category2)) db.session.commit() resp = authenticated_client.get(f"/vote/category/{category2.category_id}") vote = Vote.query.filter_by(talk_id=2).first() assert resp.status_code == 302 assert resp.headers["Location"].endswith(f"/vote/cast/{vote.public_id}") assert Vote.query.filter_by(talk_id=1).count() == 0 assert Vote.query.filter_by(talk_id=2).count() == 1
def test_send(self): c = Client(application, BaseResponse) resp = c.post("/send", data=b'{"user":"******","message":"Hello, world!"}', content_type='application/json') payload = resp.data.splitlines()[0] self.assertEqual(payload, b'Message received and being processed') resp = c.get("/messages?user=Dmitrii&last_seen=-1") payload = resp.data.splitlines()[0] payload_dict = json.loads(payload) self.assertTrue('messages' in payload_dict) self.assertTrue('last_seen' in payload_dict) messages = payload_dict['messages'] last_seen = payload_dict['last_seen'] self.assertTrue(isinstance(messages, list)) self.assertTrue(isinstance(last_seen, int)) self.assertEqual(len(messages), 2) self.assertEqual(last_seen, 1) self.assertEqual(messages[0], "Hello, world!") self.assertTrue("[BOT]" in messages[1])
def test_talks_list_page_shows_proposed_and_withdrawn_talks( client: Client, user: User ) -> None: in_talk = Talk(title="In Talk", length=25) in_talk.add_speaker(user, InvitationStatus.CONFIRMED) out_talk = Talk(title="Out Talk", length=40, state=TalkStatus.WITHDRAWN) out_talk.add_speaker(user, InvitationStatus.CONFIRMED) db.session.add(in_talk) db.session.add(out_talk) db.session.commit() client.get("/test-login/{}".format(user.user_id)) resp = client.get("/talks") body = assert_html_response(resp) soup = bs4.BeautifulSoup(body, "html.parser") talks = soup.find_all("div", class_="talk") assert len(talks) == 2 talk_row_texts = [ re.sub(r"\s+", " ", talk.parent.get_text()).strip() for talk in talks ] talk_row_texts.sort() assert re.match("In Talk.*Withdraw", talk_row_texts[0]) assert re.match("Out Talk.*Re-Submit", talk_row_texts[1]) # lazy: also test withdraw/resubmit here in the same test client.get(f"/talks/1/withdraw") client.get(f"/talks/2/resubmit") resp = client.get("/talks") body = assert_html_response(resp) soup = bs4.BeautifulSoup(body, "html.parser") talks = soup.find_all("div", class_="talk") assert len(talks) == 2 talk_row_texts = [ re.sub(r"\s+", " ", talk.parent.get_text()).strip() for talk in talks ] talk_row_texts.sort() assert re.match("In Talk.*Re-Submit", talk_row_texts[0]) assert re.match("Out Talk.*Withdraw", talk_row_texts[1])
def test_follow_redirect_exhaust_intermediate(): class Middleware: def __init__(self, app): self.app = app self.active = 0 def __call__(self, environ, start_response): # Test client must exhaust response stream, otherwise the # cleanup code that decrements this won't have run by the # time the next request is started. assert not self.active self.active += 1 try: yield from self.app(environ, start_response) finally: self.active -= 1 app = Middleware(redirect_with_get_app) client = Client(Middleware(redirect_with_get_app)) response = client.get("/", follow_redirects=True, buffered=False) assert response.data == b"current url: http://localhost/some/redirect/" assert not app.active
def from_wsgi( schema_path: str, app: Any, base_url: Optional[str] = None, method: Optional[Filter] = None, endpoint: Optional[Filter] = None, tag: Optional[Filter] = None, ) -> BaseSchema: client = Client(app, WSGIResponse) response = client.get(schema_path, headers={"User-Agent": USER_AGENT}) # type: ignore # Raising exception to provide unified behavior # E.g. it will be handled in CLI - a proper error message will be shown if 400 <= response.status_code < 600: raise HTTPError(response=response, url=schema_path) return from_file(response.data, location=schema_path, base_url=base_url, method=method, endpoint=endpoint, tag=tag, app=app)