def test_execute_file_update_operation(test_notebook, test_file_source, file_exists): if file_exists: original_file = File.objects.create( notebook_id=test_notebook.id, filename=test_file_source.filename, content=b"1234" ) update_operation = FileUpdateOperation.objects.create(file_source=test_file_source) assert update_operation.status == FileUpdateOperation.PENDING file_content = {"result": "foo"} def request_callback(request): update_operation.refresh_from_db() assert update_operation.status == FileUpdateOperation.RUNNING return (200, {}, json.dumps(file_content)) # this somewhat awkward construction is due to the fact that responses # doesn't yet support streaming with callbacks, see: # https://github.com/getsentry/responses/issues/228 with responses.RequestsMock() as requests_mock: requests_mock._matches.append( responses.CallbackResponse("GET", test_file_source.url, request_callback, stream=True) ) execute_file_update_operation(update_operation.id) update_operation.refresh_from_db() assert update_operation.status == FileUpdateOperation.COMPLETED assert update_operation.started_at and update_operation.ended_at assert update_operation.ended_at > update_operation.started_at file = File.objects.get(notebook_id=test_notebook.id, filename=test_file_source.filename) assert file.content.tobytes().decode("utf-8") == json.dumps(file_content) if file_exists: assert file.last_updated > original_file.last_updated
def test_timeout(version): # this can't be tested with responses, # because it substitutes requests session # and doesn't worry about timeouts pytest.skip("cannot be tested yet") timeout_in_sec = 1 client = make_client(version) # configure to raise the error before the timeout client.timeout = timeout_in_sec / 2.0 def timeout_request_callback(request): sleep(timeout_in_sec) return (200, {'X-TAXII-Content-Type': content_type}, "All good!") uri = get_fix(version).DISCOVERY_URI_HTTP # https://github.com/getsentry/responses/pull/268 content_type = VID_TAXII_XML_11 if version == 11 else VID_TAXII_XML_10 responses.mock._matches.append( responses.CallbackResponse( responses.POST, uri, callback=timeout_request_callback, content_type='application/json', stream=True, )) with pytest.raises(requests.exceptions.Timeout): client.discover_services(uri=uri)
def test_stream_connect(): tweet_data = { "data": { "id": "1067094924124872705", "text": "Just getting started with Twitter APIs?", } } def callback(request): s = random.randint(1, 2) if s == 1: return 200, {}, json.dumps(tweet_data) else: return 200, {}, "\r\n" responses.add( responses.CallbackResponse( responses.GET, url="https://api.twitter.com/2/tweets/sample/stream", callback=callback, stream=True, content_type="application/json", ) ) stream_api = MyStreamApi(bearer_token="bearer token") stream_api.sample_stream() assert stream_api.running == False assert stream_api.tweet_max_count == 10
def test_retry_once_on_unauthorized(version): # Test if the client refreshes the JWT if it receives an UNAUTHORIZED # status message. # Flow is as follows when client.poll() is called: # 1. Authenticate and get first_token # 2. Do poll request with first_token: Get UNAUTHORIZED response. # 3. Authenticate again and get second_token # 4. Do poll request with second_token: Get POLL_RESPONSE. # Set up two responses with tokens for auth request first_token = "first" second_token = "second" for token in (first_token, second_token): responses.add( method=responses.POST, url=JWT_URL, json={"token": token}, content_type="application/json", stream=True, ) client = make_client(version) client.set_auth(username="******", password="******", jwt_auth_url=JWT_PATH) # Set up two responses for poll request: First is UNAUTHORIZED, the second is # a normal POLL_RESPONSE if the token was refreshed. attempts = [] def poll_callback(request): attempts.append(request) _, _, token = request.headers["Authorization"].partition("Bearer ") if len(attempts) == 1: assert token == first_token return ( 200, make_taxii_headers(version), get_fix(version).STATUS_MESSAGE_UNAUTHORIZED, ) else: assert len(attempts) == 2 assert token == second_token return (200, make_taxii_headers(version), get_fix(version).POLL_RESPONSE) responses.mock._matches.append( responses.CallbackResponse( responses.POST, url="http://example.localhost/poll", callback=poll_callback, stream=True, )) list(client.poll(collection_name="X", uri="/poll")) assert client.jwt_token == second_token
def test_get_raises_retrival_error(self): test_collection_uuid = 'abcdef123456' test_collection_version = '1980-01-01' with responses.RequestsMock() as helper: helper.add(responses.CallbackResponse(responses.GET, self.cda.endpoint_url('collections', test_collection_uuid), callback=RequestCallback(567, '{}'), content_type='application/json')) with self.assertRaises(RetrievalError): self.cda.get(test_collection_uuid, test_collection_version)
def test_append_raises_update_error(self): test_collection_uuid = 'abcdef123456' test_collection_version = '1980-01-01' with responses.RequestsMock() as helper: helper.add(responses.CallbackResponse(responses.PATCH, self.cda.endpoint_url('collections', test_collection_uuid), callback=RequestCallback(405, '{}'), content_type='application/json')) with self.assertRaises(UpdateError): self.cda.append(test_collection_uuid, test_collection_version, [])
def wrapper(): response = responses.CallbackResponse( method=responses.POST, url='https://iam.cloud.ibm.com/identity/token', callback=callback, ) responses.add(response) func()
def test_append_with_no_items_successful(self): test_collection_uuid = 'abcdef123456' test_collection_version = '1980-01-01' expected_collection = dict(uuid=test_collection_uuid, version=test_collection_version) with responses.RequestsMock() as helper: helper.add(responses.CallbackResponse(responses.PATCH, self.cda.endpoint_url('collections', test_collection_uuid), callback=RequestCallback(200, json.dumps(expected_collection)), content_type='application/json')) collection = self.cda.append(test_collection_uuid, test_collection_version, []) self.assertEqual(collection, expected_collection)
def test_create_raises_creation_error(self): test_collection_uuid = 'abcdef123456' test_collection_version = '1980-01-01' fake_dss_response = {"code": "unknown"} with responses.RequestsMock() as helper: helper.add(responses.CallbackResponse(responses.PUT, self.cda.endpoint_url('collections'), callback=RequestCallback(500, json.dumps(fake_dss_response)), content_type='application/json')) with self.assertRaises(CreationError): self.cda.create(test_collection_uuid, 'foo bar', 'bar', test_collection_version, [])
def test_create_ok(self): test_collection_uuid = 'abcdef123456' test_collection_version = '1980-01-01' expected_collection = dict(uuid=test_collection_uuid, version=test_collection_version) with responses.RequestsMock() as helper: helper.add(responses.CallbackResponse(responses.PUT, self.cda.endpoint_url('collections'), callback=RequestCallback(201, json.dumps(expected_collection)), content_type='application/json')) collection = self.cda.create(test_collection_uuid, 'foo bar', 'bar', test_collection_version, []) self.assertEqual(collection, expected_collection)
def test_send_request_with_unexpected_response_code_raises_unauthorized_client_access_error(self): test_collection_uuid = 'abcdef123456' expected_response = {'code': 'mock_error'} with responses.RequestsMock() as helper: url = self.cda.endpoint_url(test_collection_uuid) helper.add(responses.CallbackResponse(responses.GET, url, callback=RequestCallback(401, json.dumps(expected_response)), content_type='application/json')) with self.assertRaises(UnauthorizedClientAccessError): self.cda.send_request(test_collection_uuid, 'get', url, {}, expected_status_code=200)
def _record_response(self, request, response_status, response_headers, response_body): # Shenanigans to get a response object like responses would # record in calls list def tmp_callback(request): return response_status, response_headers, response_body callback_response = responses.CallbackResponse(request.method, self._url, tmp_callback) response = callback_response.get_response(request) self._call_recorder.record(self, request, response, None)
def test_send_request_successful_with_auto_retry_on_http_504_timeout(self): test_collection_uuid = 'abcdef123456' expected_response = {'code': 'hello_world'} with responses.RequestsMock() as helper: url = self.cda.endpoint_url(test_collection_uuid) helper.add(responses.CallbackResponse(responses.GET, url, callback=RequestCallback(200, json.dumps(expected_response), delay=True), content_type='application/json')) response = self.cda.send_request(test_collection_uuid, 'get', url, {}) self.assertEqual(response.json(), expected_response)
def test_jwt_auth_response(version): jwt_path = "/management/auth/" jwt_url = "http://{}{}".format(get_fix(version).HOST, jwt_path) token = "dummy" username = "******" password = "******" def jwt_request_callback(request): body = request.body if isinstance(body, bytes): body = body.decode() body = json.loads(body) assert body["username"] == username assert body["password"] == password content = json.dumps({"token": token}).encode() return (200, {}, content) # https://github.com/getsentry/responses/pull/268 responses.mock._matches.append( responses.CallbackResponse( method=responses.POST, url=jwt_url, callback=jwt_request_callback, content_type="application/json", stream=True, )) discovery_uri = get_fix(version).DISCOVERY_URI_HTTP register_uri(discovery_uri, get_fix(version).DISCOVERY_RESPONSE, version) print(version, get_fix(version).DISCOVERY_RESPONSE) # client with relative JWT auth path client = make_client(version) client.set_auth(username=username, password=password, jwt_auth_url=jwt_path) services = client.discover_services(uri=discovery_uri) assert len(services) == 4 # client with full JWT auth path client = make_client(version) client.set_auth(username=username, password=password, jwt_auth_url=jwt_url) services = client.discover_services(uri=discovery_uri) assert len(services) == 4
def test_jwt_auth_response(version): username = '******' password = '******' def jwt_request_callback(request): body = request.body if isinstance(body, bytes): body = body.decode() body = json.loads(body) assert body['username'] == username assert body['password'] == password content = json.dumps({"token": "dummy"}).encode() return (200, {}, content) # https://github.com/getsentry/responses/pull/268 responses.mock._matches.append( responses.CallbackResponse( method=responses.POST, url=JWT_URL, callback=jwt_request_callback, content_type='application/json', stream=True, )) discovery_uri = get_fix(version).DISCOVERY_URI_HTTP register_uri(discovery_uri, get_fix(version).DISCOVERY_RESPONSE, version) print(version, get_fix(version).DISCOVERY_RESPONSE) # client with relative JWT auth path client = make_client(version) client.set_auth(username=username, password=password, jwt_auth_url=JWT_PATH) services = client.discover_services(uri=discovery_uri) assert len(services) == 4 # client with full JWT auth path client = make_client(version) client.set_auth(username=username, password=password, jwt_auth_url=JWT_URL) services = client.discover_services(uri=discovery_uri) assert len(services) == 4
def update_integration_mocks(self, stage_name): stage_url_lower = STAGE_URL.format(api_id=self.id.lower(), region_name=self.region_name, stage_name=stage_name) stage_url_upper = STAGE_URL.format(api_id=self.id.upper(), region_name=self.region_name, stage_name=stage_name) for url in [stage_url_lower, stage_url_upper]: responses._default_mock._matches.insert( 0, responses.CallbackResponse( url=url, method=responses.GET, callback=self.resource_callback, content_type="text/plain", match_querystring=False, ))
def test_send_request_with_unexpected_response_code_raises_client_error( self): test_collection_uuid = 'abcdef123456' expected_response = {'code': 'hello_world'} with ResponsesHelper() as helper: url = self.cda.endpoint_url(test_collection_uuid) helper.add( responses.CallbackResponse(responses.GET, url, callback=RequestCallback( 201, json.dumps(expected_response)), content_type='application/json')) with self.assertRaises(ClientError): self.cda.send_request(test_collection_uuid, 'get', url, {}, expected_status_code=200)
def test_send_request_successful_with_auto_retry_on_http_502(self): test_collection_uuid = 'abcdef123456' expected_response = {'code': 'hello_world'} mock_response_sequence = [(502, {}, '{"code": "mock_error"}'), (200, {}, json.dumps(expected_response))] def mock_request_handler(_request): return mock_response_sequence.pop(0) with ResponsesHelper() as helper: url = self.cda.endpoint_url(test_collection_uuid) helper.add( responses.CallbackResponse(responses.GET, url, callback=mock_request_handler, content_type='application/json')) response = self.cda.send_request(test_collection_uuid, 'get', url, {}) self.assertEqual(response.json(), expected_response)
def test_jwt_token_when_set_directly(version): given_token = "abcd" client = make_client(version) # The purpose of this test is to check that this assignment has effect: client.jwt_token = given_token def poll_callback(request): _, _, token = request.headers["Authorization"].partition("Bearer ") assert token == given_token return (200, make_taxii_headers(version), get_fix(version).POLL_RESPONSE) responses.mock._matches.append( responses.CallbackResponse( responses.POST, url="http://example.localhost/poll", callback=poll_callback, stream=True, )) list(client.poll(collection_name="X", uri="/poll"))
def __enter__(self): context = super().__enter__() if self.passthru_url is not None: self.add_passthru(self.passthru_url) def encode_int(x): return b64encode(x.to_bytes(ceil(x.bit_length() / 8), 'big')).decode('utf-8') def generate_test_public_keys(_request): public_key = TestKeyManager.get_public_key() public_numbers = public_key.public_numbers() public_exponent = public_numbers.e public_modulus = public_numbers.n response_body = { 'kid': 'local_test', 'e': encode_int(public_exponent), 'n': encode_int(public_modulus) } return 200, {}, json.dumps(dict(keys=[response_body])) self.add( responses.Response( method=responses.GET, url= f'{config.access_token_issuer}/.well-known/openid-configuration', json={ 'jwks_uri': f'{config.access_token_issuer}/test/public-keys' })) self.add( responses.CallbackResponse( method=responses.GET, url=f'{config.access_token_issuer}/test/public-keys', callback=generate_test_public_keys, content_type='application/json')) return context