def test_handle_GET_no_cache(self): """ Ensure that if the cache-control header in the request is set to no-cache then the lookup is foreced (i.e. don't use the local cache). """ test_key = hashlib.sha512().hexdigest() mockMessage = mock.MagicMock() mockMessage.method = 'GET' mockMessage.version = '1.1' mockMessage.path = ''.join(['/', test_key]) mockMessage.headers = {'Cache-Control': 'no-cache', } connector = HttpConnector(self.event_loop) def faux_get(*args, **kwargs): return { 'key': test_key, 'status': 'pending', } connector.get = mock.MagicMock(side_effect=faux_get) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, None)) response.assert_called_once_with(hrh.writer, 200, http_version=mockMessage.version) # The connector's get method was called with the forced flag set # to True. connector.get.assert_called_once_with(test_key, node, True)
def test_handle_request_causes_exception(self): """ A request that raises an exception causes a 500 response. """ mockMessage = mock.MagicMock() mockMessage.method = 'POST' mockMessage.version = '1.1' mockPayload = mock.MagicMock() @asyncio.coroutine def faux_read(*args, **kwargs): return 'raw_data' mockPayload.read = mock.MagicMock(side_effect=faux_read) connector = HttpConnector(self.event_loop) def faux_receive(*args, **kwargs): raise ValueError('Boom! Something went wrong.') connector.receive = mock.MagicMock(side_effect=faux_receive) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, mockPayload)) response.assert_called_once_with(hrh.writer, 500, http_version=mockMessage.version)
def test_handle_GET_internal_server_error(self): """ A GET request that causes an exception simply returns a 500 (Internal Server Error). """ test_key = hashlib.sha512().hexdigest() mockMessage = mock.MagicMock() mockMessage.method = 'GET' mockMessage.version = '1.1' mockMessage.path = ''.join(['/', test_key]) connector = HttpConnector(self.event_loop) def faux_get(*args, **kwargs): raise Exception('Bang!') connector.get = mock.MagicMock(side_effect=faux_get) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, None)) response.assert_called_once_with(hrh.writer, 500, http_version=mockMessage.version)
def test_handle_GET_request(self): """ A valid GET request casues a 200 reponse. """ test_key = hashlib.sha512().hexdigest() mockMessage = mock.MagicMock() mockMessage.method = 'GET' mockMessage.version = '1.1' mockMessage.path = ''.join(['/', test_key]) connector = HttpConnector(self.event_loop) def faux_get(*args, **kwargs): return { 'key': test_key, 'status': 'pending', } connector.get = mock.MagicMock(side_effect=faux_get) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, None)) response.assert_called_once_with(hrh.writer, 200, http_version=mockMessage.version)
def test_init_(self): """ The connector and node instances should be set properly. """ connector = HttpConnector(self.event_loop) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node) self.assertEqual(connector, hrh.connector) self.assertEqual(node, hrh.node)
def test_handle_request_not_POST_or_GET(self): """ A request that is not a POST causes a 405 response. """ mockMessage = mock.MagicMock() mockMessage.method = 'PUT' mockMessage.version = '1.1' mockPayload = mock.MagicMock() connector = HttpConnector(self.event_loop) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, mockPayload)) response.assert_called_once_with(hrh.writer, 405, http_version=mockMessage.version)
def test_handle_GET_bad_request(self): """ A GET request without a valid sha512 hexdigest as its path causes a 400 (Bad Request) response. """ test_key = 'not_a_valid_sha512_hexdigest' mockMessage = mock.MagicMock() mockMessage.method = 'GET' mockMessage.version = '1.1' mockMessage.path = ''.join(['/', test_key]) connector = HttpConnector(self.event_loop) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, None)) response.assert_called_once_with(hrh.writer, 400, http_version=mockMessage.version)
def test_init_with_extra_kwargs(self): """ An further arguments passed in (above and beyond the connector and node instances) are correctly handled. """ connector = HttpConnector(self.event_loop) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) self.assertEqual(connector, hrh.connector) self.assertEqual(node, hrh.node) self.assertEqual(True, hrh.debug)
def test_handle_POST_request(self): """ A valid POST request causes a 200 response. * WARNING * Too much mocking going on here (in the vain attempt to achieve 100% test coverage). """ mockMessage = mock.MagicMock() mockMessage.method = 'POST' mockMessage.version = '1.1' mockPayload = mock.MagicMock() @asyncio.coroutine def faux_read(*args, **kwargs): return 'raw_data' mockPayload.read = mock.MagicMock(side_effect=faux_read) connector = HttpConnector(self.event_loop) def faux_receive(*args, **kwargs): return OK('uuid', 'recipient', 'sender', 9999, 'version', 'seal') connector.receive = mock.MagicMock(side_effect=faux_receive) node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, connector, 1908) hrh = HttpRequestHandler(connector, node, debug=True) peer = '192.168.0.1' hrh.transport = mock.MagicMock() hrh.transport.get_extra_info = mock.MagicMock(side_effect=peer) hrh.writer = mock.MagicMock() with mock.patch.object(aiohttp, 'Response', return_value=mock.MagicMock()) as response: self.event_loop.run_until_complete(hrh.handle_request(mockMessage, mockPayload)) response.assert_called_once_with(hrh.writer, 200, http_version=mockMessage.version)
def protocol_factory(connector=connector, node=instance._node): """ Returns an appropriately configured NetstringProtocol object for each connection. """ return HttpRequestHandler(connector, node)