def test_cors_supported_methods(self): foo = Service(name='foo', path='/foo', cors_enabled=True) foo.add_view('GET', _stub) self.assertIn('GET', foo.cors_supported_methods) foo.add_view('POST', _stub) self.assertIn('POST', foo.cors_supported_methods)
def test_cors_headers_for_method(self): # defining headers in the view should work. service = Service('coconuts', '/migrate') service.add_view('GET', _stub, cors_headers=('X-Header-Foobar')) service.add_view('POST', _stub, cors_headers=('X-Header-Barbaz')) get_headers = service.cors_supported_headers_for(method='GET') self.assertNotIn('X-Header-Barbaz', get_headers)
def test_cors_headers_for_method(self): # defining headers in the view should work. service = Service("coconuts", "/migrate") service.add_view("GET", _stub, cors_headers=("X-Header-Foobar")) service.add_view("POST", _stub, cors_headers=("X-Header-Barbaz")) get_headers = service.cors_supported_headers_for(method="GET") self.assertNotIn("X-Header-Barbaz", get_headers)
def test_cors_supported_methods(self): foo = Service(name="foo", path="/foo", cors_enabled=True) foo.add_view("GET", _stub) self.assertIn("GET", foo.cors_supported_methods) foo.add_view("POST", _stub) self.assertIn("POST", foo.cors_supported_methods)
def test_schemas_for(self): schema = validationapp.FooBarSchema service = Service("color", "/favorite-color") service.add_view("GET", lambda x: "red", schema=schema) self.assertEquals(len(service.schemas_for("GET")), 1) service.add_view("GET", lambda x: "red", validators=_validator, schema=schema) self.assertEquals(len(service.schemas_for("GET")), 2)
def test_disabling_cors_for_one_method(self): foo = Service(name='foo', path='/foo', cors_enabled=True) foo.add_view('GET', _stub) self.assertIn('GET', foo.cors_supported_methods) foo.add_view('POST', _stub, cors_enabled=False) self.assertIn('GET', foo.cors_supported_methods) self.assertFalse('POST' in foo.cors_supported_methods)
def test_cors_headers_for_service_instanciation(self): # When definining services, it's possible to add headers. This tests # it is possible to list all the headers supported by a service. service = Service("coconuts", "/migrate", cors_headers=("X-Header-Coconut")) self.assertNotIn("X-Header-Coconut", service.cors_supported_headers_for()) service.add_view("POST", _stub) self.assertIn("X-Header-Coconut", service.cors_supported_headers_for())
def test_cors_headers_for_method_are_deduplicated(self): # defining headers in the view should work. service = Service("coconuts", "/migrate") service.cors_headers = ("X-Header-Foobar",) service.add_view("GET", _stub, cors_headers=("X-Header-Foobar", "X-Header-Barbaz")) get_headers = service.cors_supported_headers_for(method="GET") expected = set(["X-Header-Foobar", "X-Header-Barbaz"]) self.assertEqual(expected, get_headers)
def test_disabling_cors_for_one_method(self): foo = Service(name="foo", path="/foo", cors_enabled=True) foo.add_view("GET", _stub) self.assertIn("GET", foo.cors_supported_methods) foo.add_view("POST", _stub, cors_enabled=False) self.assertIn("GET", foo.cors_supported_methods) self.assertFalse("POST" in foo.cors_supported_methods)
def test_cors_supported_origins(self): foo = Service(name="foo", path="/foo", cors_origins=("mozilla.org",)) foo.add_view("GET", _stub, cors_origins=("notmyidea.org", "lolnet.org")) self.assertIn("mozilla.org", foo.cors_supported_origins) self.assertIn("notmyidea.org", foo.cors_supported_origins) self.assertIn("lolnet.org", foo.cors_supported_origins)
def test_cors_headers_for_method_are_deduplicated(self): # defining headers in the view should work. service = Service('coconuts', '/migrate') service.cors_headers = ('X-Header-Foobar',) service.add_view('GET', _stub, cors_headers=('X-Header-Foobar', 'X-Header-Barbaz')) get_headers = service.cors_supported_headers_for(method='GET') expected = set(['X-Header-Foobar', 'X-Header-Barbaz']) self.assertEqual(expected, get_headers)
def test_per_method_supported_origins(self): foo = Service(name="foo", path="/foo", cors_origins=("mozilla.org",)) foo.add_view("GET", _stub, cors_origins=("lolnet.org",)) self.assertTrue("mozilla.org" in foo.cors_origins_for("GET")) self.assertTrue("lolnet.org" in foo.cors_origins_for("GET")) foo.add_view("POST", _stub) self.assertFalse("lolnet.org" in foo.cors_origins_for("POST"))
def test_cors_headers_for_service_instanciation(self): # When definining services, it's possible to add headers. This tests # it is possible to list all the headers supported by a service. service = Service('coconuts', '/migrate', cors_headers=('X-Header-Coconut')) self.assertNotIn('X-Header-Coconut', service.cors_supported_headers) service.add_view('POST', _stub) self.assertIn('X-Header-Coconut', service.cors_supported_headers)
def test_cors_supported_origins(self): foo = Service( name='foo', path='/foo', cors_origins=('mozilla.org',)) foo.add_view('GET', _stub, cors_origins=('notmyidea.org', 'lolnet.org')) self.assertIn('mozilla.org', foo.cors_supported_origins) self.assertIn('notmyidea.org', foo.cors_supported_origins) self.assertIn('lolnet.org', foo.cors_supported_origins)
def test_per_method_supported_origins(self): foo = Service( name='foo', path='/foo', cors_origins=('mozilla.org',)) foo.add_view('GET', _stub, cors_origins=('lolnet.org',)) self.assertTrue('mozilla.org' in foo.cors_origins_for('GET')) self.assertTrue('lolnet.org' in foo.cors_origins_for('GET')) foo.add_view('POST', _stub) self.assertFalse('lolnet.org' in foo.cors_origins_for('POST'))
def test_get_acceptable(self): # defining a service with different "accept" headers, we should be able # to retrieve this information easily service = Service("color", "/favorite-color") service.add_view("GET", lambda x: "blue", accept="text/plain") self.assertEquals(service.get_acceptable("GET"), ['text/plain']) service.add_view("GET", lambda x: "blue", accept="application/json") self.assertEquals(service.get_acceptable("GET"), ['text/plain', 'application/json']) # adding a view for the POST method should not break everything :-) service.add_view("POST", lambda x: "ok", accept=('foo/bar')) self.assertEquals(service.get_acceptable("GET"), ['text/plain', 'application/json']) # and of course the list of accepted content-types should be available # for the "POST" as well. self.assertEquals(service.get_acceptable("POST"), ['foo/bar']) # it is possible to give acceptable content-types dynamically at # run-time. You don't always want to have the callables when retrieving # all the acceptable content-types service.add_view("POST", lambda x: "ok", accept=lambda r: "text/json") self.assertEquals(len(service.get_acceptable("POST")), 2) self.assertEquals(len(service.get_acceptable("POST", True)), 1)
def test_summary_docstrings_with_klass(self): class TemperatureCooler(object): def put_view(self): """Put it.""" pass service = Service("TemperatureCooler", "/freshair", klass=TemperatureCooler) service.add_view("put", "put_view") CorniceSwagger.services = [service] self.swagger = CorniceSwagger() self.spec = self.swagger.generate() validate(self.spec)
def test_view_registration(self): # registering a new view should make it available in the list. # The methods list is populated service = Service("color", "/favorite-color") def view(request): pass service.add_view("post", view, validators=(_validator,)) self.assertEquals(len(service.definitions), 1) method, _view, _ = service.definitions[0] # the view had been registered. we also test here that the method had # been inserted capitalized (POST instead of post) self.assertEquals(("POST", view), (method, _view))
def test_get_contenttypes(self): # defining a service with different "content_type" headers, we should # be able to retrieve this information easily service = Service("color", "/favorite-color") service.add_view("GET", lambda x: "blue", content_type="text/plain") self.assertEquals(service.get_contenttypes("GET"), ['text/plain']) service.add_view("GET", lambda x: "blue", content_type="application/json") self.assertEquals(service.get_contenttypes("GET"), ['text/plain', 'application/json']) # adding a view for the POST method should not break everything :-) service.add_view("POST", lambda x: "ok", content_type=('foo/bar')) self.assertEquals(service.get_contenttypes("GET"), ['text/plain', 'application/json']) # and of course the list of supported ingress content-types should be # available for the "POST" as well. self.assertEquals(service.get_contenttypes("POST"), ['foo/bar']) # it is possible to give supported ingress content-types dynamically at # run-time. You don't always want to have the callables when retrieving # all the supported content-types service.add_view("POST", lambda x: "ok", content_type=lambda r: "text/json") self.assertEquals(len(service.get_contenttypes("POST")), 2) self.assertEquals(len(service.get_contenttypes("POST", True)), 1)
def test_default_validators(self): old_validators = Service.default_validators old_filters = Service.default_filters try: def custom_validator(request): pass def custom_filter(request): pass def freshair(request): pass # the default validators should be used when registering a service Service.default_validators = [custom_validator, ] Service.default_filters = [custom_filter, ] service = Service("TemperatureCooler", "/freshair") service.add_view("get", freshair) method, view, args = service.definitions[0] self.assertIn(custom_validator, args['validators']) self.assertIn(custom_filter, args['filters']) # defining a service with additional filters / validators should # work as well def another_validator(request): pass def another_filter(request): pass def groove_em_all(request): pass service2 = Service('FunkyGroovy', '/funky-groovy', validators=[another_validator], filters=[another_filter]) service2.add_view("get", groove_em_all) method, view, args = service2.definitions[0] self.assertIn(custom_validator, args['validators']) self.assertIn(another_validator, args['validators']) self.assertIn(custom_filter, args['filters']) self.assertIn(another_filter, args['filters']) finally: Service.default_validators = old_validators Service.default_filters = old_filters
def test_imperative(self): service = Service("TemperatureCooler", "/freshair") class TemperatureCooler(object): """Temp class docstring""" def view_get(self, request): """Temp view docstring""" return "red" service.add_view("get", TemperatureCooler.view_get, validators=(colander_validator, ), schema=RequestSchema()) ret = _generate_swagger([service]) if PY3: self.assertEqual(ret["tags"], [{ 'name': 'freshair', 'description': '' }]) else: self.assertEqual(ret["tags"], [{ 'name': 'freshair', 'description': 'Temp class docstring' }]) self.assertEqual(ret["paths"]["/freshair"]["get"]["summary"], 'Temp view docstring') params = ret["paths"]["/freshair"]["get"]['parameters'] self.assertEqual(len(params), 3) self.assertEqual(sorted(x["in"] for x in params), ["body", "query", "query"]) self.assertEqual(sorted(x["name"] for x in params), ["body", "mau", "yeah"]) self.assertEqual([x.get("required") for x in params], [True, True, None]) self.assertEqual([x.get("type") for x in params], ["string", "string", None]) self.assertEqual([x.get("schema") for x in params], [None, None, { '$ref': '#/definitions/Body' }]) self.assertListEqual( sorted([x.get("description") for x in params], key=lambda x: x or ""), [ None, "Defines a cornice body schema", "Defines querystring yeah" ]) self.assertEqual(sorted(ret["definitions"]['Body']["required"]), ['bar', 'foo'])
def test_default_validators(self): old_validators = Service.default_validators old_filters = Service.default_filters try: def custom_validator(request): pass def custom_filter(request): pass def freshair(request): pass # the default validators should be used when registering a service Service.default_validators = [custom_validator, ] Service.default_filters = [custom_filter, ] service = Service("TemperatureCooler", "/freshair") service.add_view("GET", freshair) method, view, args = service.definitions[0] self.assertIn(custom_validator, args['validators']) self.assertIn(custom_filter, args['filters']) # defining a service with additional filters / validators should # work as well def another_validator(request): pass def another_filter(request): pass def groove_em_all(request): pass service2 = Service('FunkyGroovy', '/funky-groovy', validators=[another_validator], filters=[another_filter]) service2.add_view("GET", groove_em_all) method, view, args = service2.definitions[0] self.assertIn(custom_validator, args['validators']) self.assertIn(another_validator, args['validators']) self.assertIn(custom_filter, args['filters']) self.assertIn(another_filter, args['filters']) finally: Service.default_validators = old_validators Service.default_filters = old_filters
def test_class_parameters(self): # when passing a "klass" argument, it gets registered. It also tests # that the view argument can be a string and not a callable. class TemperatureCooler(object): def get_fresh_air(self): pass service = Service("TemperatureCooler", "/freshair", klass=TemperatureCooler) service.add_view("get", "get_fresh_air") self.assertEqual(len(service.definitions), 2) method, view, args = service.definitions[0] self.assertEqual(view, "get_fresh_air") self.assertEqual(args["klass"], TemperatureCooler)
def test_get_validators(self): # defining different validators for the same services, even with # different calls to add_view should make them available in the # get_validators method def validator(request): """Super validator""" pass def validator2(request): pass service = Service("/color", "/favorite-color") service.add_view("GET", lambda x: "ok", validators=(validator, validator)) service.add_view("GET", lambda x: "ok", validators=(validator2)) self.assertEqual(service.get_validators("GET"), [validator, validator2])
def test_get_validators(self): # defining different validators for the same services, even with # different calls to add_view should make them available in the # get_validators method def validator(request): """Super validator""" pass def validator2(request): pass service = Service('/color', '/favorite-color') service.add_view('GET', lambda x: 'ok', validators=(validator, validator)) service.add_view('GET', lambda x: 'ok', validators=(validator2)) self.assertEqual(service.get_validators('GET'), [validator, validator2])
def test_cors_headers_extension(self): # definining headers in the service and in the view service = Service('coconuts', '/migrate', cors_headers=('X-Header-Foobar')) service.add_view('POST', _stub, cors_headers=('X-Header-Barbaz')) self.assertIn('X-Header-Foobar', service.cors_supported_headers_for()) self.assertIn('X-Header-Barbaz', service.cors_supported_headers_for()) # check that adding the same header twice doesn't make bad things # happen service.add_view( 'POST', _stub, cors_headers=('X-Header-Foobar'), ) self.assertEqual(len(service.cors_supported_headers_for()), 2) # check that adding a header on a cors disabled method doesn't # change anything service.add_view('put', _stub, cors_headers=('X-Another-Header', ), cors_enabled=False) self.assertNotIn('X-Another-Header', service.cors_supported_headers_for())
def test_max_age_can_be_different_dependeing_methods(self): foo = Service(name="foo", path="/foo", cors_max_age=42) foo.add_view("GET", _stub) foo.add_view("POST", _stub, cors_max_age=32) foo.add_view("PUT", _stub, cors_max_age=7) self.assertEqual(foo.cors_max_age_for("GET"), 42) self.assertEqual(foo.cors_max_age_for("POST"), 32) self.assertEqual(foo.cors_max_age_for("PUT"), 7)
def test_max_age_can_be_different_dependeing_methods(self): foo = Service(name='foo', path='/foo', cors_max_age=42) foo.add_view('GET', _stub) foo.add_view('POST', _stub, cors_max_age=32) foo.add_view('PUT', _stub, cors_max_age=7) self.assertEqual(foo.cors_max_age_for('GET'), 42) self.assertEqual(foo.cors_max_age_for('POST'), 32) self.assertEqual(foo.cors_max_age_for('PUT'), 7)
def test_get_contenttypes(self): # defining a service with different "content_type" headers, we should # be able to retrieve this information easily service = Service("color", "/favorite-color") service.add_view("GET", lambda x: "blue", content_type="text/plain") self.assertEquals(service.get_contenttypes("GET"), ["text/plain"]) service.add_view("GET", lambda x: "blue", content_type="application/json") self.assertEquals(service.get_contenttypes("GET"), ["text/plain", "application/json"]) # adding a view for the POST method should not break everything :-) service.add_view("POST", lambda x: "ok", content_type=("foo/bar")) self.assertEquals(service.get_contenttypes("GET"), ["text/plain", "application/json"]) # and of course the list of supported ingress content-types should be # available for the "POST" as well. self.assertEquals(service.get_contenttypes("POST"), ["foo/bar"]) # it is possible to give supported ingress content-types dynamically at # run-time. You don't always want to have the callables when retrieving # all the supported content-types service.add_view("POST", lambda x: "ok", content_type=lambda r: "text/json") self.assertEquals(len(service.get_contenttypes("POST")), 2) self.assertEquals(len(service.get_contenttypes("POST", True)), 1)
def test_cors_headers_extension(self): # definining headers in the service and in the view service = Service("coconuts", "/migrate", cors_headers=("X-Header-Foobar")) service.add_view("POST", _stub, cors_headers=("X-Header-Barbaz")) self.assertIn("X-Header-Foobar", service.cors_supported_headers_for()) self.assertIn("X-Header-Barbaz", service.cors_supported_headers_for()) # check that adding the same header twice doesn't make bad things # happen service.add_view("POST", _stub, cors_headers=("X-Header-Foobar")) self.assertEqual(len(service.cors_supported_headers_for()), 2) # check that adding a header on a cors disabled method doesn't # change anything service.add_view("put", _stub, cors_headers=("X-Another-Header",), cors_enabled=False) self.assertNotIn("X-Another-Header", service.cors_supported_headers_for())
def test_cors_headers_extension(self): # definining headers in the service and in the view service = Service('coconuts', '/migrate', cors_headers=('X-Header-Foobar')) service.add_view('POST', _stub, cors_headers=('X-Header-Barbaz')) self.assertIn('X-Header-Foobar', service.cors_supported_headers) self.assertIn('X-Header-Barbaz', service.cors_supported_headers) # check that adding the same header twice doesn't make bad things # happen service.add_view('POST', _stub, cors_headers=('X-Header-Foobar'),) self.assertEquals(len(service.cors_supported_headers), 2) # check that adding a header on a cors disabled method doesn't # change anything service.add_view('put', _stub, cors_headers=('X-Another-Header',), cors_enabled=False) self.assertFalse('X-Another-Header' in service.cors_supported_headers)
def test_per_method_credential_support(self): foo = Service(name='foo', path='/foo') foo.add_view('GET', _stub, cors_credentials=True) foo.add_view('POST', _stub) self.assertTrue(foo.cors_support_credentials_for('GET')) self.assertFalse(foo.cors_support_credentials_for('POST'))
def test_max_age_can_be_defined(self): foo = Service(name="foo", path="/foo", cors_max_age=42) foo.add_view("POST", _stub) self.assertEqual(foo.cors_max_age_for(), 42)
def test_max_age_is_none_if_undefined(self): foo = Service(name="foo", path="/foo") foo.add_view("POST", _stub) self.assertIsNone(foo.cors_max_age_for("POST"))
def test_method_takes_precendence_for_credential_support(self): foo = Service(name="foo", path="/foo", cors_credentials=True) foo.add_view("GET", _stub, cors_credentials=False) self.assertFalse(foo.cors_support_credentials_for("GET"))
def test_per_method_credential_support(self): foo = Service(name="foo", path="/foo") foo.add_view("GET", _stub, cors_credentials=True) foo.add_view("POST", _stub) self.assertTrue(foo.cors_support_credentials_for("GET")) self.assertFalse(foo.cors_support_credentials_for("POST"))
def test_credential_support_is_disabled_by_default(self): foo = Service(name="foo", path="/foo") foo.add_view("POST", _stub) self.assertFalse(foo.cors_support_credentials_for())
def test_max_age_is_none_if_undefined(self): foo = Service(name='foo', path='/foo') foo.add_view('POST', _stub) self.assertIsNone(foo.cors_max_age_for('POST'))
def test_max_age_can_be_defined(self): foo = Service(name='foo', path='/foo', cors_max_age=42) foo.add_view('POST', _stub) self.assertEqual(foo.cors_max_age_for(), 42)
def test_credential_support_is_disabled_by_default(self): foo = Service(name='foo', path='/foo') foo.add_view('POST', _stub) self.assertFalse(foo.cors_support_credentials_for())
def test_credential_support_can_be_enabled(self): foo = Service(name='foo', path='/foo', cors_credentials=True) foo.add_view('POST', _stub) self.assertTrue(foo.cors_support_credentials_for())
def test_cors_headers_for_view_definition(self): # defining headers in the view should work. service = Service('coconuts', '/migrate') service.add_view('POST', _stub, cors_headers=('X-Header-Foobar')) self.assertIn('X-Header-Foobar', service.cors_supported_headers_for())
Class implementation of a service """ def __init__(self, request): self.request = request def post(self): return "moar squirels (take care)" cors_policy = {'origins': ('*', ), 'enabled': True, 'credentials': True} cors_klass = Service(name='cors_klass', path='/cors_klass', klass=Klass, cors_policy=cors_policy) cors_klass.add_view('post', 'post') @squirel.get(cors_origins=('notmyidea.org', ), cors_headers=('X-My-Header', )) def get_squirel(request): return "squirels" @squirel.post(cors_enabled=False, cors_headers=('X-Another-Header')) def post_squirel(request): return "moar squirels (take care)" @squirel.put() def put_squirel(request): return "squirels!"
def test_method_takes_precendence_for_credential_support(self): foo = Service(name='foo', path='/foo', cors_credentials=True) foo.add_view('GET', _stub, cors_credentials=False) self.assertFalse(foo.cors_support_credentials_for('GET'))