def test_get_all_peers_returns_peer_in_list(self): transfer = server.Transfer('1', '.', '1.1.1.1') rootUrl = b'piazza.org' mockOb = MagicMock(server.OutboundRequests) mockOb.all.return_value = iter([transfer]) app = server.OutboundRequestEndpoint(outboundRequests=mockOb, getFileNames=None, submitFileRequest=None, rootUrl=rootUrl).app kr = KleinResource(app) request = requestMock('/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(mockOb.all.called) expected = utils.sortedDump( {"files": [{ "url": "piazza.org/1/", "transferId": "1", "userIp": "1.1.1.1", "filepath": "." }]}) self.assertEqual(expected, request.getWrittenData())
def test_parseTransferRequest_failure(self): downloadTo = "." requests = [] def fakeParser(*args): raise filerequest.FileRequestError() endpoint = server.InboundRequestEndpoint( requests, downloadTo, fakeParser ) kr = KleinResource(endpoint.app) body = utils.sortedDump({}) request = requestMock('/', 'POST', body=body) d = _render(kr, request) self.assertFired(d) self.assertEqual( request.getWrittenData(), b'{"error": "error parsing request", "status": "error"}' )
def test_get_all_peers_returns_peer_in_list(self): transfer = server.Transfer('1', '.', '1.1.1.1') rootUrl = b'piazza.org' mockOb = MagicMock(server.OutboundRequests) mockOb.all.return_value = iter([transfer]) app = server.OutboundRequestEndpoint(outboundRequests=mockOb, getFileNames=None, submitFileRequest=None, rootUrl=rootUrl).app kr = KleinResource(app) request = requestMock('/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(mockOb.all.called) expected = utils.sortedDump({ "files": [{ "url": "piazza.org/1/", "transferId": "1", "userIp": "1.1.1.1", "filepath": "." }] }) self.assertEqual(expected, request.getWrittenData())
def get_attachment(self, ident, encoding): request = requestMock(path='/attachment/' + ident) request.args = { 'encoding': [encoding] } _render(self.resource, request) return request.getWrittenData()
def test_parseTransferRequest_success(self): downloadTo = "." requests = [] def fakeParser(*args): return ['it worked. this is a weak fake'] endpoint = server.InboundRequestEndpoint( requests, downloadTo, fakeParser ) kr = KleinResource(endpoint.app) body = utils.sortedDump({"type": "good request"}) request = requestMock('/', 'POST', body=body) d = _render(kr, request) self.assertFired(d) self.assertEqual( request.getWrittenData(), b'{"error": null, "status": "ok"}' )
def test_sending_mail_return_error_message_when_send_fails(self): self.mail_service.send = self._send_that_throws_exception request = requestMock('', body=json.dumps(self.input_mail.json)) result = self.mails_controller.send_mail(request) self.assertEqual(request.code, 422) self.assertEqual(result, '{"message": "email sending failed\\nmore information of error\\n123\\nthere was a code before this"}')
def test_sending_mail_return_sent_mail_data_when_send_succeeds(self): self.mail_service.send = self._successfuly_send_mail request = requestMock('', body=json.dumps(self.input_mail.json)) result = self.mails_controller.send_mail(request) self.assertEqual(request.code, 200) self.assertEqual(result, '{"status": [], "body": "email body", "ident": 1, "tags": [], "header": {"to": "[email protected]", "from": "[email protected]"}, "security_casing": {}}')
def get_mails_by_tag(self, tag, page=1, window=100): request = requestMock(path="/mails") request.args = { 'q': ['tag:%s' % tag], 'w': [str(window)], 'p': [str(page)] } _render(self.resource, request) response = json.loads(request.getWrittenData()) return [ResponseMail(m) for m in response['mails']]
def test_sending_mail_return_sent_mail_data_when_send_succeeds(self): self.mail_service.send = self._successfuly_send_mail request = requestMock('', body=json.dumps(self.input_mail.json)) result = self.mails_controller.send_mail(request) self.assertEqual(request.code, 200) self.assertEqual( result, '{"status": [], "body": "email body", "ident": 1, "tags": [], "header": {"to": "[email protected]", "from": "[email protected]"}, "security_casing": {}}' )
def test_sending_mail_return_error_message_when_send_fails(self): self.mail_service.send = self._send_that_throws_exception request = requestMock('', body=json.dumps(self.input_mail.json)) result = self.mails_controller.send_mail(request) self.assertEqual(request.code, 422) self.assertEqual( result, '{"message": "email sending failed\\nmore information of error\\n123\\nthere was a code before this"}' )
def test_newTransfer_succeeds(self): body = utils.sortedDump({"filepath": "plop.txt", "user": "******"}) request = requestMock('/', 'POST', body=body) d = _render(self.kr, request) self.assertFired(d) self.assertEqual( request.getWrittenData(), b'{"directories": [], "filenames": ["plop.txt"],' b' "transfer": "/1/"}')
def test_get_all_peers_returns_json_object(self): peerlist = MagicMock(peerdiscovery.PeerList) peerlist.all.return_value = iter([]) app = server.UsersEndpoint(peerlist).app kr = KleinResource(app) request = requestMock('/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertEqual(utils.sortedDump({"users": []}), request.getWrittenData())
def test_get_all_peers_returns_json_object(self): peerlist = MagicMock(peerdiscovery.PeerList) peerlist.all.return_value = iter([]) app = server.UsersEndpoint(peerlist).app kr = KleinResource(app) request = requestMock('/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertEqual( utils.sortedDump({"users": []}), request.getWrittenData() )
def test_with_non_existing_file_request_returns_no_resource(self): mockOb = MagicMock(server.OutboundRequests) mockOb.get.return_value = None outbound = mockOb app = server.FileEndpoint(outbound).app kr = KleinResource(app) request = requestMock('/nonexistant/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(mockOb.get.called) self.assertEqual(request.getWrittenData(), NoResource().render(request))
def test_get_all_peers_returns_json(self): peerlist = MagicMock(peerdiscovery.PeerList) peerlist.all.return_value = iter([]) app = server.UsersEndpoint(peerlist).app kr = KleinResource(app) request = requestMock('/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(peerlist.all.called) headers = request.responseHeaders.getRawHeaders('content-type') self.assertEqual(['application/json'], headers)
def test_newTransfer_succeeds(self): body = utils.sortedDump( { "filepath": "plop.txt", "user": "******" } ) request = requestMock('/', 'POST', body=body) d = _render(self.kr, request) self.assertFired(d) self.assertEqual( request.getWrittenData(), b'{"directories": [], "filenames": ["plop.txt"],' b' "transfer": "/1/"}' )
def test_get_all_peers_returns_peer_in_list(self): peerlist = MagicMock(peerdiscovery.PeerList) peer = peerdiscovery.Peer(b'paul', b'1.1.1.1', b'58673') peerlist.all.return_value = iter([peer]) app = server.UsersEndpoint(peerlist).app kr = KleinResource(app) request = requestMock('/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(peerlist.all.called) self.assertEqual(utils.sortedDump({"users": [peer.serialize()]}), request.getWrittenData())
def test_get_all_peers_returns_peer_in_list(self): peerlist = MagicMock(peerdiscovery.PeerList) peer = peerdiscovery.Peer(b'paul', b'1.1.1.1', b'58673') peerlist.all.return_value = iter([peer]) app = server.UsersEndpoint(peerlist).app kr = KleinResource(app) request = requestMock('/', 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(peerlist.all.called) self.assertEqual( utils.sortedDump({"users": [peer.serialize()]}), request.getWrittenData() )
def test_parseTransferRequest_success(self): downloadTo = "." requests = [] def fakeParser(*args): return ['it worked. this is a weak fake'] endpoint = server.InboundRequestEndpoint(requests, downloadTo, fakeParser) kr = KleinResource(endpoint.app) body = utils.sortedDump({"type": "good request"}) request = requestMock('/', 'POST', body=body) d = _render(kr, request) self.assertFired(d) self.assertEqual(request.getWrittenData(), b'{"error": null, "status": "ok"}')
def test_with_existing_file_request_returns_directory_listing(self): # uses the current directory where tests are run # this is all that is needed as no operations are performed # that change the files in the pwd. transfer = server.Transfer('1', '.', '1.1.1.1') mockOb = MagicMock(server.OutboundRequests) mockOb.get.return_value = transfer outbound = mockOb app = server.FileEndpoint(outbound).app kr = KleinResource(app) url = u'/' + transfer.transferId + u'/' request = requestMock(url.encode('ascii', 'ignore'), 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(mockOb.get.called) self.assertIn(b'Directory listing', request.getWrittenData())
def test_parseTransferRequest_failure(self): downloadTo = "." requests = [] def fakeParser(*args): raise filerequest.FileRequestError() endpoint = server.InboundRequestEndpoint(requests, downloadTo, fakeParser) kr = KleinResource(endpoint.app) body = utils.sortedDump({}) request = requestMock('/', 'POST', body=body) d = _render(kr, request) self.assertFired(d) self.assertEqual( request.getWrittenData(), b'{"error": "error parsing request", "status": "error"}')
def test_with_single_filename_returns_single_file(self): fpath = filepath.FilePath(self.mktemp()) contents = b'im the contents of a file :-)' fpath.setContent(contents) transfer = server.Transfer('1', fpath.path, '1.1.1.1') mockOb = MagicMock(server.OutboundRequests) mockOb.get.return_value = transfer outbound = mockOb app = server.FileEndpoint(outbound).app kr = KleinResource(app) url = u'/' + transfer.transferId + u'/' + fpath.basename() request = requestMock(url.encode('ascii', 'ignore'), 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(mockOb.get.called) self.assertIn(contents, request.getWrittenData())
def test_with_single_filename_returns_single_file(self): fpath = filepath.FilePath(self.mktemp()) contents = b'im the contents of a file :-)' fpath.setContent(contents) transfer = server.Transfer('1', fpath.path, '1.1.1.1') mockOb = MagicMock(server.OutboundRequests) mockOb.get.return_value = transfer outbound = mockOb app = server.FileEndpoint(outbound).app kr = KleinResource(app) url = u'/' + transfer.transferId + u'/' + fpath.basename() request = requestMock(url.encode('ascii', 'ignore'), 'GET') d = _render(kr, request) self.assertFired(d) self.assertTrue(mockOb.get.called) self.assertIn( contents, request.getWrittenData() )
def post_mail(self, data): request = requestMock(path='/mails', method="POST", body=data, headers={'Content-Type': ['application/json']}) _render(self.resource, request) response = json.loads(request.getWrittenData()) return ResponseMail(response)
def delete(self, path): request = requestMock(path=path, method="DELETE") return self._render(request)
def put(self, path, body): request = requestMock(path=path, method="PUT", body=body, headers={'Content-Type': ['application/json']}) return self._render(request)
def get(self, path, get_args, as_json=True): request = requestMock(path) request.args = get_args return self._render(request, as_json)
def mark_as_unread(self, mail_ident): request = requestMock('/mail/' + mail_ident + '/unread', method="POST", headers={'Content-Type': ['application/json']}) _render(self.resource, request) return request
def get_tags(self, **kwargs): request = requestMock('/tags') request.args = kwargs _render(self.resource, request) return json.loads(request.getWrittenData())
def put_mail(self, data): request = requestMock('/mails', method="PUT", body=data, headers={'Content-Type': ['application/json']}) _render(self.resource, request) response = json.loads(request.getWrittenData()) return response['ident']
def post_tags(self, mail_ident, tags_json): request = requestMock('/mail/' + mail_ident + '/tags', method="POST", body=tags_json, headers={'Content-Type': ['application/json']}) _render(self.resource, request) return json.loads(request.getWrittenData())
def request(root_resource, method, endpoint, headers=None, body=None): """ Make a mock request to the REST interface :param method: http method :type method: ``str`` in (``GET``, ``POST``, ``PUT``, ``DELETE``) :param endpoint: Absolute path to the endpoint, minus the API version :type endpoint: ``str`` :param headers: Any headers to include :type headers: ``dict`` of ``list`` :param body: the body to include in the request :type body: ``str`` """ # handle query args, since requestMock does not (see # twisted.web.http.py:Request.requestReceived) with_query = endpoint.split(b'?', 1) if len(with_query) == 1: mock_request = requestMock(endpoint, method, headers=headers, body=body) mock_request.args = {} else: mock_request = requestMock(with_query[0], method, headers=headers, body=body) mock_request.args = parse_qs(with_query[1]) # these are used when writing the response mock_request.code = 200 mock_request.getClientIP = mock.MagicMock(spec=(), return_value='ip') mock_request.setHeader = mock.MagicMock(spec=()) # twisted request has a responseHeaders (outgoing headers) and # requestHeaders (incoming headers, set by requestMock) mock_request.responseHeaders = http.Headers() # if setHeader has been called a with unicode value, twisted will raise a # TypeError after the request has been closed and it is attemptig to write # to the network. So just fail here for testing purposes def _twisted_compat(name, value): if not isinstance(name, str) or not isinstance(value, str): raise TypeError("Can only pass-through bytes on Python 2") mock_request.responseHeaders.setRawHeaders(name, [value]) mock_request.setHeader.side_effect = _twisted_compat def build_response(_): # build a response that offers some useful attributes of an IResponse status_code = 200 if mock_request.setResponseCode.call_args is not None: # first non-keyword arg - getting it from call_args means the non # kwargs are the first argument, not the second status_code = mock_request.setResponseCode.call_args[0][0] # if the content-type has not been set, Twisted by default sets the # content-type to be whatever is in # twisted.web.server.Request.defaultContentType, so replicate that # functionality if not (mock_request.responseHeaders.hasHeader('Content-Type') or Request.defaultContentType is None): mock_request.responseHeaders.setRawHeaders( 'Content-Type', [Request.defaultContentType]) response = mock.MagicMock(spec=['code', 'headers'], code=status_code, headers=mock_request.responseHeaders) # Annoying implementation detail: if the status code is one of the # status codes that should not have a body, twisted replaces the # write method of the request with a function that does nothing, so # no response body can every be written. This messes up the mock # request's write function (which just returns another mock. So # in this case, just return "". content = '' if status_code not in http.NO_BODY_CODES: # get the body by joining all calls to request.write content = "".join( [call[1][0] for call in mock_request.write.mock_calls]) return ResponseWrapper(response=response, content=content, request=mock_request) return _render( getChildForRequest(root_resource, mock_request), mock_request).addCallback(build_response)
def delete_mail(self, mail_ident): request = requestMock(path='/mail/' + mail_ident, method="DELETE") _render(self.resource, request) return request
def mark_many_as_read(self, idents): request = requestMock('/mails/read', method="POST", body=json.dumps({'idents': idents}), headers={'Content-Type': ['application/json']}) _render(self.resource, request) return request
def request(root_resource, method, endpoint, headers=None, body=None): """ Make a mock request to the REST interface :param method: http method :type method: ``str`` in (``GET``, ``POST``, ``PUT``, ``DELETE``) :param endpoint: Absolute path to the endpoint, minus the API version :type endpoint: ``str`` :param headers: Any headers to include :type headers: ``dict`` of ``list`` :param body: the body to include in the request :type body: ``str`` """ # build mock request mock_request = requestMock(endpoint, method, headers=headers, body=body) # these are used when writing the response mock_request.code = 200 mock_request.setHeader = mock.MagicMock(spec=()) # twisted request has a responseHeaders (outgoing headers) and # requestHeaders (incoming headers, set by requestMock) mock_request.responseHeaders = http.Headers() # if setHeader has been called a with unicode value, twisted will raise a # TypeError after the request has been closed and it is attemptig to write # to the network. So just fail here for testing purposes def _twisted_compat(name, value): if not isinstance(name, str) or not isinstance(value, str): raise TypeError("Can only pass-through bytes on Python 2") mock_request.responseHeaders.setRawHeaders(name, [value]) mock_request.setHeader.side_effect = _twisted_compat def build_response(_): # build a response that offers some useful attributes of an IResponse status_code = 200 if mock_request.setResponseCode.call_args is not None: # first non-keyword arg - getting it from call_args means the non # kwargs are the first argument, not the second status_code = mock_request.setResponseCode.call_args[0][0] # if the content-type has not been set, Twisted by default sets the # content-type to be whatever is in # twisted.web.server.Request.defaultContentType, so replicate that # functionality if not (mock_request.responseHeaders.hasHeader('Content-Type') or Request.defaultContentType is None): mock_request.responseHeaders.setRawHeaders( 'Content-Type', [Request.defaultContentType]) response = mock.MagicMock(spec=['code', 'headers'], code=status_code, headers=mock_request.responseHeaders) # Annoying implementation detail: if the status code is one of the # status codes that should not have a body, twisted replaces the # write method of the request with a function that does nothing, so # no response body can every be written. This messes up the mock # request's write function (which just returns another mock. So # in this case, just return "". content = '' if status_code not in http.NO_BODY_CODES: # get the body by joining all calls to request.write content = "".join( [call[1][0] for call in mock_request.write.mock_calls]) return ResponseWrapper(response=response, content=content, request=mock_request) return _render( getChildForRequest(root_resource, mock_request), mock_request).addCallback(build_response)