class ImpersonationTest(unittest.TestCase): def setUp(self): self.http_context = Context({}) self.http_context.__enter__() def tearDown(self): self.http_context.__exit__(*sys.exc_info()) def test_impersonation(self): role1 = 'role-1' role2 = 'role-2' role3 = 'role-3' role4 = 'role-4' # Simple test role_1_principal = DummyIdentity(role1) with ImpersonateAs(role_1_principal): self.assertEqual(context.identity, role_1_principal) self.assertTrue(context.identity.is_in_roles(role1)) # Now we change the role role_2_principal = DummyIdentity(role2) with ImpersonateAs(role_2_principal): self.assertFalse(context.identity.is_in_roles(role1)) self.assertTrue(context.identity.is_in_roles(role2)) # Multiple roles role_3_4_principal = DummyIdentity(role3, role4) with ImpersonateAs(role_3_4_principal): self.assertTrue(context.identity.is_in_roles(role3)) self.assertTrue(context.identity.is_in_roles(role4)) self.assertFalse(context.identity.is_in_roles(role1)) self.assertFalse(context.identity.is_in_roles(role2))
def test_stack(self): with Context({}) as parent: context.field1 = 'parent value' with Context({}) as child: context.field1 = 'child value' self.assertEqual(context.field1, 'child value') self.assertIs(Context.get_current(), child) self.assertEqual(context.field1, 'parent value') self.assertIs(Context.get_current(), parent)
def test_ordering_mixin(db): session =db() for i in range(1, 6): obj = OrderingObject( title=f'object {6-i//2}', age=i * 10, ) session.add(obj) session.commit() query = session.query(OrderingObject) # Ascending with Context({'QUERY_STRING': 'sort=id'}): result = OrderingObject.sort_by_request(query).all() assert result[0].id == 1 assert result[-1].id == 5 # Descending with Context({'QUERY_STRING': 'sort=-id'}): result = OrderingObject.sort_by_request(query).all() assert result[0].id == 5 assert result[-1].id == 1 # Sort by Synonym Property with Context({'QUERY_STRING': 'sort=age'}): result = OrderingObject.sort_by_request(query).all() assert result[0].id == 1 assert result[-1].id == 5 # Mutiple sort criteria with Context({'QUERY_STRING': 'sort=title,id'}): result = OrderingObject.sort_by_request(query).all() assert result[0].id == 4 assert result[1].id == 5 assert result[2].id == 2 assert result[3].id == 3 assert result[4].id == 1 # Sort by date with Context({'QUERY_STRING': 'sort=-createdAt'}): result = OrderingObject.sort_by_request(query).all() assert result[0].id == 5 assert result[1].id == 4 assert result[2].id == 3 assert result[3].id == 2 assert result[4].id == 1
def test_session_member(self): with Context(environ={}, application=self.application): principal = self.application.__authenticator__.login( ('*****@*****.**', 'test')) self.assertEqual( self.application.__authenticator__.get_session_member( principal.session_id), 1)
def test_jsonpatch_querystring(): environ = {'REQUEST_METHOD': 'PATCH', 'QUERY_STRING': 'a=10'} with Context(environ): controller = SimpleJsonPatchController() context.form = [{ 'op': 'get', 'path': '/' }, { 'op': 'put', 'path': 'biscuits/1?a=1', 'value': { 'name': 'Ginger Nut' } }, { 'op': 'get', 'path': 'biscuits/2', 'value': { 'name': 'Ginger Nut' } }] result = ujson.loads(controller()) assert len(result) == 3 assert result[1]['a'] == '1' assert 'a' not in result[0] assert 'a' not in result[2]
def test_jsonpatch_rfc6902(self): environ = {'REQUEST_METHOD': 'PATCH'} with Context(environ): controller = SimpleJsonPatchController() context.form = [ { "op": "get", "path": "/" }, { "op": "put", "path": "biscuits/1", "value": { "name": "Ginger Nut" } }, { "op": "get", "path": "biscuits/2", "value": { "name": "Ginger Nut" } }, ] result = ujson.loads(controller()) self.assertEqual(len(result), 3)
def test_jsonpatch_caseinsesitive_verb(): environ = {'REQUEST_METHOD': 'PATCH', 'QUERY_STRING': 'a=10'} with Context(environ): controller = SimpleJsonPatchController() context.form = [ { 'op': 'GET', 'path': '/' }, { 'op': 'PUT', 'path': 'biscuits/1?a=1', 'value': { 'name': 'Ginger Nut' } }, { 'op': 'GET', 'path': 'biscuits/2', 'value': { 'name': 'Ginger Nut' } }, ] result = ujson.loads(controller()) assert len(result) == 3
def test_impersonation(): with Context({}) as ctx: role1 = 'role-1' role2 = 'role-2' role3 = 'role-3' role4 = 'role-4' # Simple test role_1_principal = DummyIdentity(role1) with ImpersonateAs(role_1_principal): assert context.identity == role_1_principal assert context.identity.is_in_roles(role1) # Now we change the role role_2_principal = DummyIdentity(role2) with ImpersonateAs(role_2_principal): assert not context.identity.is_in_roles(role1) assert context.identity.is_in_roles(role2) # Multiple roles role_3_4_principal = DummyIdentity(role3, role4) with ImpersonateAs(role_3_4_principal): assert context.identity.is_in_roles(role3) assert context.identity.is_in_roles(role4) assert not context.identity.is_in_roles(role1) assert not context.identity.is_in_roles(role2)
def test_authenticator(app): _ = app from nanohttp.contexts import Context with Context({}): authenticator = StatefulAuthenticator() member_id = 500 for session_id in ('bla_bla1', 'bla_bla2', 'bla_bla3'): authenticator.register_session(member_id=member_id, session_id=session_id) # Get session info info = authenticator.get_session_info(session_id=session_id) assert 'remoteAddress' in info last_sessions = sessions = authenticator.get_member_sessions(member_id) assert len(sessions) >= 0 authenticator.unregister_session(session_id) sessions = authenticator.get_member_sessions(member_id) assert len(sessions) == len(last_sessions) - 1 authenticator.invalidate_member(member_id) sessions = authenticator.get_member_sessions(member_id) assert len(sessions) == 0
def test_error(self): output_generator = self.error_action() with Context(environ={}) as context: self.assertEqual(next(output_generator), '11\r\nfirst chunk\r\n') self.assertEqual(next(output_generator), 'division by zero') self.assertEqual(next(output_generator), '0\r\n') self.assertEqual(next(output_generator), '\r\n')
def test_isonline(self): with Context(environ={}, application=self.__application__): authenticator = self.__application__.__authenticator__ principal = authenticator.login(('*****@*****.**', 'test')) assert authenticator.isonline(principal.session_id) == True authenticator.logout() assert authenticator.isonline(principal.session_id) == False
def test_trailer(self): output_generator = self.trailer_action() with Context(environ={}) as context: self.assertEqual(next(output_generator), '11\r\nfirst chunk\r\n') self.assertEqual(next(output_generator), '12\r\nsecond chunk\r\n') self.assertEqual(next(output_generator), '0\r\n') self.assertEqual(next(output_generator), 'field: value\r\n') self.assertEqual(next(output_generator), '\r\n') self.assertEqual(context.response_headers['trailer'], 'field')
def test_chunked(self): output_generator = self.chunked_action() with Context(environ={}) as context: self.assertEqual(next(output_generator), '11\r\nfirst chunk\r\n') self.assertEqual(next(output_generator), '12\r\nsecond chunk\r\n') self.assertEqual(next(output_generator), '11\r\nthird chunk\r\n') self.assertEqual(next(output_generator), '0\r\n') self.assertEqual(next(output_generator), '\r\n') self.assertEqual(context.response_headers['transfer-encoding'], 'chunked')
def test_pagination_mixin(self): for i in range(1, 6): # noinspection PyArgumentList obj = PagingObject( title='object %s' % i, ) DBSession.add(obj) DBSession.commit() with Context({'QUERY_STRING': 'take=2&skip=1'}, self.application) as context: self.assertEqual(PagingObject.paginate_by_request().count(), 2) self.assertEqual(context.response_headers['X-Pagination-Take'], '2') self.assertEqual(context.response_headers['X-Pagination-Skip'], '1') self.assertEqual(context.response_headers['X-Pagination-Count'], '5') with Context({'QUERY_STRING': 'take=two&skip=one'}, self.application): self.assertEqual(PagingObject.paginate_by_request().count(), 4) with Context({'QUERY_STRING': 'take=5'}, self.application): self.assertRaises(HttpBadRequest, PagingObject.paginate_by_request)
def test_model(db): session = db() __configuration__ = ''' timezone: ''' settings.merge(__configuration__) with Context({}): author1 = Author(title='author1', email='*****@*****.**', first_name='author 1 first name', last_name='author 1 last name', phone=None, password='******', birth=date(1, 1, 1), weight=1.1) post1 = Post(title='First post', author=author1, tag_time=time(1, 1, 1)) session.add(post1) session.commit() assert post1.id == 1 post1_dict = post1.to_dict() assert { 'author': { 'email': '*****@*****.**', 'firstName': 'author 1 first name', 'id': 1, 'lastName': 'author 1 last name', 'phone': None, 'title': 'author1', 'birth': '0001-01-01', 'weight': 1.100, 'age': 18 }, 'authorId': 1, 'comments': [], 'id': 1, 'tags': [], 'title': 'First post', 'tagTime': '01:01:01', }.items() < post1_dict.items() assert 'createdAt' in post1_dict assert 'modifiedAt' in post1_dict author1_dict = author1.to_dict() assert 'fullName' not in author1_dict
def test_pagination_mixin(db): session = db() for i in range(1, 6): obj = PagingObject(title='object %s' % i, ) session.add(obj) session.commit() query = session.query(PagingObject) with Context({'QUERY_STRING': 'take=2&skip=1'}) as context: assert PagingObject.paginate_by_request(query).count() == 2 assert context.response_headers['X-Pagination-Take'] == '2' assert context.response_headers['X-Pagination-Skip'] == '1' assert context.response_headers['X-Pagination-Count'] == '5' with Context({'QUERY_STRING': 'take=two&skip=one'}), \ pytest.raises(HTTPBadRequest): PagingObject.paginate_by_request(query).count() with Context({'QUERY_STRING': 'take=5'}), pytest.raises(HTTPBadRequest): PagingObject.paginate_by_request(query)
def test_ordering_mixin(self): for i in range(1, 6): # noinspection PyArgumentList obj = OrderableOrderingObject(title='object %s' % i, age=i * 10) DBSession.add(obj) # noinspection PyArgumentList obj = OrderingObject(title='object %s' % i, ) DBSession.add(obj) DBSession.commit() # Default soring with Orderable objects with Context({'QUERY_STRING': ''}, self.application): result = OrderableOrderingObject.sort_by_request().all() self.assertEqual(result[0].id, 1) self.assertEqual(result[-1].id, 5) # Default soring without Orderable objects with Context({'QUERY_STRING': ''}, self.application): result = OrderingObject.sort_by_request().all() self.assertEqual(len(result), 5) # Ascending with Context({'QUERY_STRING': 'sort=id'}, self.application): result = OrderableOrderingObject.sort_by_request().all() self.assertEqual(result[0].id, 1) self.assertEqual(result[-1].id, 5) # Descending with Context({'QUERY_STRING': 'sort=-id'}, self.application): result = OrderableOrderingObject.sort_by_request().all() self.assertEqual(result[0].id, 5) self.assertEqual(result[-1].id, 1) # Sort by Synonym Property with Context({'QUERY_STRING': 'sort=age'}, self.application): result = OrderableOrderingObject.sort_by_request().all() self.assertEqual(result[0].id, 1) self.assertEqual(result[-1].id, 5)
def test_jsonpatch_error(): environ = {'REQUEST_METHOD': 'PATCH'} with Context(environ), pytest.raises(Exception): controller = SimpleJsonPatchController() context.form = [{ 'op': 'put', 'path': 'biscuits/1', 'value': { 'name': 'Ginger Nut' } }, { 'op': 'error', 'path': 'biscuits', 'value': None }] controller()
def test_jsonpatch_error(self): environ = {'REQUEST_METHOD': 'PATCH'} with Context(environ): controller = SimpleJsonPatchController() context.form = [ { "op": "put", "path": "biscuits/1", "value": { "name": "Ginger Nut" } }, { "op": "error", "path": "biscuits", "value": None }, ] self.assertRaises(Exception, controller)
def test_jsonpatch_rfc6902(): environ = {'REQUEST_METHOD': 'PATCH'} with Context(environ): controller = SimpleJsonPatchController() context.form = [{ 'op': 'get', 'path': '/' }, { 'op': 'put', 'path': 'biscuits/1', 'value': { 'name': 'Ginger Nut' } }, { 'op': 'get', 'path': 'biscuits/2', 'value': { 'name': 'Ginger Nut' } }] result = ujson.loads(controller()) assert len(result) == 3
def __call__(self, environ, start_response): """Method that `WSGI <https://www.python.org/dev/peps/pep-0333/#id15>`_ server calls """ # Entering the context context_ = Context(environ, self) context_.__enter__() # Preparing some variables status = '200 OK' buffer = None response_iterable = None try: self._hook('begin_request') # Removing the trailing slash in-place, if exists context_.path = context_.path.rstrip('/') # Removing the heading slash, and query string anyway path = context_.path[1:].split('?')[0] # Splitting the path by slash(es) if any remaining_paths = path.split('/') if path else [] # Calling the controller, actually this will be serve our request response_body = self.__root__(*remaining_paths) if response_body: # The goal is to yield an iterable, to encode and iter over it # at the end of this method. if isinstance(response_body, (str, bytes)): # Mocking the body inside an iterable to prevent # the iteration over the str character by character # For more info check the pull-request # #34, https://github.com/Carrene/nanohttp/pull/34 response_iterable = (response_body, ) elif isinstance(response_body, types.GeneratorType): # Generators are iterable ! response_iterable = response_body # Trying to get at least one element from the generator, # to force the method call till the second # `yield` statement buffer = next(response_iterable) elif isinstance(response_body, Iterable): # Creating an iterator from iterable! response_iterable = iter(response_body) else: raise ValueError( 'Controller\'s action/handler response must be ' 'generator and or iterable') except Exception as ex: return self._handle_exception(ex, start_response) self._hook('begin_response') # Setting cookies in response headers, if any cookie = context_.cookies.output() if cookie: for line in cookie.split('\r\n'): context_.response_headers.add_header(*line.split(': ', 1)) start_response( status, context_.response_headers.items(), ) # It seems we have to transfer a body, so this function should yield # a generator of the body chunks. def _response(): try: if buffer is not None: yield context_.encode_response(buffer) if response_iterable: # noinspection PyTypeChecker for chunk in response_iterable: yield context_.encode_response(chunk) else: yield b'' except Exception as ex_: self.__logger__.exception( 'Exception while serving the response.') if settings.debug: yield str(ex_).encode() raise ex_ finally: self._hook('end_response') context.__exit__(*sys.exc_info()) return _response()
from nanohttp.contexts import Context from restfulpy.orm import DBSession, DeclarativeBase from sqlalchemy import func, select, and_ from sqlalchemy.orm import mapper from leo import leo from leo.models import Icd, Collection, collection_icd_table, Member leo.configure() leo.initialize_models() if __name__ == '__main__': with Context({}) as context: context.identity = vahid = Member.query.filter( Member.email == '*****@*****.**').one() # vahid.ensure_builtin_collections() # DBSession.commit() # # favorites = vahid.collections.filter(Collection.title == 'Favorites').one() # favorites.codes.append(Icd.query.filter(Icd.id == 1).one()) # DBSession.commit() collections_cte = select([ Collection.id.label('collection_id'), collection_icd_table.c.icd_id.label('icd_id') ]).select_from( Collection.__table__.join( collection_icd_table, collection_icd_table.c.collection_id == Collection.id)).where( Collection.user_id == context.identity.id).cte()
def test_filtering_mixin(self): for i in range(1, 6): # noinspection PyArgumentList DBSession.add(FilteringObject(title='object %s' % i, )) # noinspection PyArgumentList DBSession.add(FilteringObject(title='A simple title', )) DBSession.commit() # Bad Value with Context({'QUERY_STRING': 'id=1'}, self.application) as context: context.query_string['id'] = 1 self.assertRaises(HttpBadRequest, FilteringObject.filter_by_request) # IN with Context({'QUERY_STRING': 'id=IN(1,2,3)'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # NOT IN with Context({'QUERY_STRING': 'id=!IN(1,2,3)'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # IN (error) with Context({'QUERY_STRING': 'id=IN()'}, self.application): self.assertRaises(HttpBadRequest, FilteringObject.filter_by_request) # Between with Context({'QUERY_STRING': 'id=BETWEEN(1,3)'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # IS NULL with Context({'QUERY_STRING': 'title=null'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 0) # IS NOT NULL with Context({'QUERY_STRING': 'title=!null'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 6) # == with Context({'QUERY_STRING': 'id=1'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 1) # != with Context({'QUERY_STRING': 'id=!1'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) # >= with Context({'QUERY_STRING': 'id=>=2'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) # > with Context({'QUERY_STRING': 'id=>2'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 4) # <= with Context({'QUERY_STRING': 'id=<=3'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # < with Context({'QUERY_STRING': 'id=<3'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 2) # LIKE with Context({'QUERY_STRING': 'title=%obj%'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) with Context({'QUERY_STRING': 'title=%OBJ%'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 0) # ILIKE with Context({'QUERY_STRING': 'title=~%obj%'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) with Context({'QUERY_STRING': 'title=~%OBJ%'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) with Context({'QUERY_STRING': 'title=A sim%'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 1) with Context({'QUERY_STRING': 'title=%25ect 5'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 1) with Context({'QUERY_STRING': 'title=%imple%'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 1) with Context({'QUERY_STRING': 'title=~%IMPLE%'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 1)
def test_filtering_mixin(self): for i in range(1, 6): # noinspection PyArgumentList obj = FilteringObject( title='object %s' % i, ) DBSession.add(obj) DBSession.commit() # Bad Value with Context({'QUERY_STRING': 'id=1'}, self.application) as context: context.query_string['id'] = 1 self.assertRaises(HttpBadRequest, FilteringObject.filter_by_request) # IN with Context({'QUERY_STRING': 'id=^1,2,3'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # NOT IN with Context({'QUERY_STRING': 'id=!^1,2,3'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 2) # IN (error) with Context({'QUERY_STRING': 'id=^'}, self.application): self.assertRaises(HttpBadRequest, FilteringObject.filter_by_request) # Between with Context({'QUERY_STRING': 'id=~1,3'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # IS NULL with Context({'QUERY_STRING': 'title=null'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 0) # IS NOT NULL with Context({'QUERY_STRING': 'title=!null'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) # LIKE with Context({'QUERY_STRING': 'title=%obj'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) with Context({'QUERY_STRING': 'title=%OBJ'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 0) # ILIKE with Context({'QUERY_STRING': 'title=%~obj'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) with Context({'QUERY_STRING': 'title=%~OBJ'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 5) # == with Context({'QUERY_STRING': 'id=1'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 1) # != with Context({'QUERY_STRING': 'id=!1'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 4) # >= with Context({'QUERY_STRING': 'id=>=2'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 4) # > with Context({'QUERY_STRING': 'id=>2'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # <= with Context({'QUERY_STRING': 'id=<=3'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 3) # < with Context({'QUERY_STRING': 'id=<3'}, self.application): self.assertEqual(FilteringObject.filter_by_request().count(), 2)
def test_see_message(self): class Identity: def __init__(self, user): self.id = user.id self.reference_id = user.reference_id self.login(self.user1.email) with Context(dict()), cas_mockup_server(), self.given( f'See a message', f'/apiv1/messages/id:{self.message3.id}', f'SEE', query=dict(mimetype='!application/x-auditlog') ): assert status == 200 assert response.json['id'] == self.message3.id assert response.json['body'] == self.message3.body assert response.json['seenAt'] is not None assert response.json['attachment'] is not None assert response.json['modifiedAt'] is None assert response.json['seenBy'][0]['id'] is not None assert response.json['seenBy'][0]['referenceId'] is not None assert response.json['seenBy'][0]['title'] is not None assert response.json['seenBy'][0]['avatar'] is not None assert response.json['seenBy'][0]['email'] is not None assert response.json['seenBy'][0]['phone'] is None context.identity = Identity(self.user1) session = self.create_session() auditlog_message1 = session.query(Message) \ .get(self.auditlog_message1_id) auditlog_message2 = session.query(Message) \ .get(self.auditlog_message2_id) auditlog_message3 = session.query(Message) \ .get(self.auditlog_message3_id) assert auditlog_message1.seen_at is None assert auditlog_message2.seen_at is None assert auditlog_message3.seen_at is None message1 = session.query(Message).get(self.message1.id) message2 = session.query(Message).get(self.message2.id) message3 = session.query(Message).get(self.message3.id) assert message1.seen_at is not None assert message2.seen_at is not None assert message3.seen_at is not None when( 'See an auditlog message', url_parameters=dict(id=self.auditlog_message2_id), query=dict(mimetype='application/x-auditlog'), ) assert status == 200 session = self.create_session() auditlog_message1 = session.query(Message) \ .get(self.auditlog_message1_id) auditlog_message2 = session.query(Message) \ .get(self.auditlog_message2_id) auditlog_message3 = session.query(Message) \ .get(self.auditlog_message3_id) assert auditlog_message1.seen_at is not None assert auditlog_message2.seen_at is not None assert auditlog_message3.seen_at is None when( 'Sender wants to see own message', url_parameters=dict(id=self.message1.id) ) assert status == '621 Can Not See Own Message' when('Trying to pass with message already seen') assert status == '619 Message Already Seen' when('Message is not found', url_parameters=dict(id=0)) assert status == 404 when( 'Message is not found with alphabetical id', url_parameters=dict(id='Alphabetical') ) assert status == 404 when('Try to pass unauthorize request', authorization=None) assert status == 401
def __call__(self, environ, start_response): """Method that `WSGI <https://www.python.org/dev/peps/pep-0333/#id15>`_ server calls """ # Entering the context context_ = Context(environ, self) context_.__enter__() # Preparing some variables status = '200 OK' buffer = None response_iterable = None try: self._hook('begin_request') # Removing the trailing slash in-place, if exists context_.path = context_.path.rstrip('/') # Removing the heading slash, and query string anyway path = context_.path[1:].split('?')[0] # Splitting the path by slash(es) if any remaining_paths = path.split('/') if path else [] # Calling the controller, actually this will be serve our request response_body = self.__root__(*remaining_paths) if response_body: # The goal is to yield an iterable, to encode and iter over it # at the end of this method. if isinstance(response_body, types.GeneratorType): # Generators are iterable ! response_iterable = response_body # Trying to get at least one element from the generator, # to force the method call till the second # `yield` statement buffer = next(response_iterable) elif isinstance(response_body, (str, bytes)): # Mocking the body inside an iterable to prevent # the iteration over the str character by character # For more info check the pull-request # #34, https://github.com/Carrene/nanohttp/pull/34 response_iterable = (response_body, ) else: # Assuming the body is an iterable. response_iterable = response_body except Exception as ex: # the self._handle_exception may raise the error again, if the # error is not subclass of the HTTPStatusOtherwise, # a tuple of the status code and response body will be returned. status, response_body = self._handle_exception(ex) buffer = None response_iterable = (response_body, ) self._hook('begin_response') # Setting cookies in response headers, if any cookie = context_.cookies.output() if cookie: for line in cookie.split('\r\n'): context_.response_headers.add_header(*line.split(': ', 1)) # Sometimes don't need to transfer any body, for example the 304 case. if status[:3] in NO_CONTENT_STATUSES: del context_.response_headers['Content-Type'] start_response(status, context_.response_headers.items()) # This is only header, and body should not be transferred. # So the context is also should be destroyed context.__exit__(*sys.exc_info()) return [] else: start_response(status, context_.response_headers.items()) # It seems we have to transfer a body, so this function should yield # a generator of the body chunks. def _response(): try: if buffer is not None: yield context_.encode_response(buffer) if response_iterable: # noinspection PyTypeChecker for chunk in response_iterable: yield context_.encode_response(chunk) else: yield b'' except Exception as ex_: # pragma: no cover self.__logger__.exception( 'Exception while serving the response.') if settings.debug: yield str(ex_).encode() raise ex_ finally: self._hook('end_response') context.__exit__(*sys.exc_info()) return _response()
def test_filtering_mixin(db): session = db() for i in range(1, 6): session.add(FilteringObject(title='object %s' % i, )) session.add(FilteringObject(title='A simple title', )) session.commit() query = session.query(FilteringObject) with Context({'QUERY_STRING': 'id=1'}) as context, \ pytest.raises(HTTPBadRequest): context.query['id'] = 1 FilteringObject.filter_by_request(query) # IN with Context({'QUERY_STRING': 'id=IN(1,2,3)'}): assert FilteringObject.filter_by_request(query).count() == 3 # NOT IN with Context({'QUERY_STRING': 'id=!IN(1,2,3)'}): assert FilteringObject.filter_by_request(query).count() == 3 # IN (error) with Context({'QUERY_STRING': 'id=IN()'}), \ pytest.raises(HTTPBadRequest): FilteringObject.filter_by_request(query) # Between with Context({'QUERY_STRING': 'id=BETWEEN(1,3)'}): assert FilteringObject.filter_by_request(query).count() == 3 # Not Between with Context({'QUERY_STRING': 'id=!BETWEEN(1,5)'}): assert FilteringObject.filter_by_request(query).count() == 1 # Bad Between with pytest.raises(HTTPBadRequest), \ Context({'QUERY_STRING': 'id=BETWEEN(1,)'}): FilteringObject.filter_by_request(query) # IS NULL with Context({'QUERY_STRING': 'title=%00'}): assert FilteringObject.filter_by_request(query).count() == 0 # IS NOT NULL with Context({'QUERY_STRING': 'title=!%00'}): assert FilteringObject.filter_by_request(query).count() == 6 # == with Context({'QUERY_STRING': 'id=1'}): assert FilteringObject.filter_by_request(query).count() == 1 # != with Context({'QUERY_STRING': 'id=!1'}): assert FilteringObject.filter_by_request(query).count() == 5 # >= with Context({'QUERY_STRING': 'id=>=2'}): assert FilteringObject.filter_by_request(query).count() == 5 # > with Context({'QUERY_STRING': 'id=>2'}): assert FilteringObject.filter_by_request(query).count() == 4 # <= with Context({'QUERY_STRING': 'id=<=3'}): FilteringObject.filter_by_request(query).count() == 3 # < with Context({'QUERY_STRING': 'id=<3'}): assert FilteringObject.filter_by_request(query).count() == 2 # LIKE with Context({'QUERY_STRING': 'title=%obj%'}): assert FilteringObject.filter_by_request(query).count() == 5 with Context({'QUERY_STRING': 'title=%OBJ%'}): assert FilteringObject.filter_by_request(query).count() == 0 # ILIKE with Context({'QUERY_STRING': 'title=~%obj%'}): assert FilteringObject.filter_by_request(query).count() == 5 with Context({'QUERY_STRING': 'title=~%OBJ%'}): assert FilteringObject.filter_by_request(query).count() == 5 with Context({'QUERY_STRING': 'title=A sim%'}): assert FilteringObject.filter_by_request(query).count() == 1 with Context({'QUERY_STRING': 'title=%25ect 5'}): assert FilteringObject.filter_by_request(query).count() == 1 with Context({'QUERY_STRING': 'title=%imple%'}): assert FilteringObject.filter_by_request(query).count() == 1 with Context({'QUERY_STRING': 'title=~%IMPLE%'}): assert FilteringObject.filter_by_request(query).count() == 1 session.add(Interval(start=1, end=4)) session.commit() query = session.query(Interval) # Filtering on hybrid property with Context({'QUERY_STRING': 'length=3'}): assert Interval.filter_by_request(query).count() == 1 # Get sure filtering on hybrid property works correctly with Context({'QUERY_STRING': 'length=2'}): assert Interval.filter_by_request(query).count() == 0
def test_content_length(self): with Context({'CONTENT_LENGTH': '', 'wsgi.input': io.BytesIO()}): form = context.form self.assertEqual({}, form)
def test_session_member(self): with Context(environ={}, application=self.__application__): authenticator = self.__application__.__authenticator__ principal = authenticator.login(('*****@*****.**', 'test')) assert authenticator.get_member_id_by_session( principal.session_id) == 1
def test_filtering_mixin(db): session = db() for i in range(1, 6): session.add(FilteringObject( title='object %s' % i, )) session.add(FilteringObject( title='A simple title', )) session.commit() query = session.query(FilteringObject) with Context({'QUERY_STRING': 'id=1'}) as context, \ pytest.raises(HTTPBadRequest): context.query['id'] = 1 FilteringObject.filter_by_request(query) # IN with Context({'QUERY_STRING': 'id=IN(1,2,3)'}): assert FilteringObject.filter_by_request(query).count() == 3 # NOT IN with Context({'QUERY_STRING': 'id=!IN(1,2,3)'}): assert FilteringObject.filter_by_request(query).count() == 3 # IN (error) with Context({'QUERY_STRING': 'id=IN()'}), \ pytest.raises(HTTPBadRequest): FilteringObject.filter_by_request(query) # Between with Context({'QUERY_STRING': 'id=BETWEEN(1,3)'}): assert FilteringObject.filter_by_request(query).count() == 3 # IS NULL with Context({'QUERY_STRING': 'title=null'}): assert FilteringObject.filter_by_request(query).count() == 0 # IS NOT NULL with Context({'QUERY_STRING': 'title=!null'}): assert FilteringObject.filter_by_request(query).count() == 6 # == with Context({'QUERY_STRING': 'id=1'}): assert FilteringObject.filter_by_request(query).count() == 1 # != with Context({'QUERY_STRING': 'id=!1'}): assert FilteringObject.filter_by_request(query).count() == 5 # >= with Context({'QUERY_STRING': 'id=>=2'}): assert FilteringObject.filter_by_request(query).count() == 5 # > with Context({'QUERY_STRING': 'id=>2'}): assert FilteringObject.filter_by_request(query).count() == 4 # <= with Context({'QUERY_STRING': 'id=<=3'}): FilteringObject.filter_by_request(query).count() == 3 # < with Context({'QUERY_STRING': 'id=<3'}): assert FilteringObject.filter_by_request(query).count() == 2 # LIKE with Context({'QUERY_STRING': 'title=%obj%'}): assert FilteringObject.filter_by_request(query).count() == 5 with Context({'QUERY_STRING': 'title=%OBJ%'}): assert FilteringObject.filter_by_request(query).count() == 0 # ILIKE with Context({'QUERY_STRING': 'title=~%obj%'}): assert FilteringObject.filter_by_request(query).count() == 5 with Context({'QUERY_STRING': 'title=~%OBJ%'}): assert FilteringObject.filter_by_request(query).count() == 5 with Context({'QUERY_STRING': 'title=A sim%'}): assert FilteringObject.filter_by_request(query).count() == 1 with Context({'QUERY_STRING': 'title=%25ect 5'}): assert FilteringObject.filter_by_request(query).count() == 1 with Context({'QUERY_STRING': 'title=%imple%'}): assert FilteringObject.filter_by_request(query).count() == 1 with Context({'QUERY_STRING': 'title=~%IMPLE%'}): assert FilteringObject.filter_by_request(query).count() == 1