def test_unicode(self): http = HttpMock(datafile('zoo.json'), headers={'status': '200'}) model = JsonModel() uri = u'https://www.googleapis.com/someapi/v1/collection/?foo=bar' method = u'POST' request = HttpRequest(http, model.response, uri, method=method, body=u'{}', headers={'content-type': 'application/json'}) request.execute() self.assertEqual(uri, http.uri) self.assertEqual(str, type(http.uri)) self.assertEqual(method, http.method) self.assertEqual(str, type(http.method))
def test_oauthed(resource, app, login): login() mock_http = HttpMock(resource('datasets-list.json'), {'status': '200'}) with mock.patch.object(main.decorator, 'http', return_value=mock_http): with mock.patch.object(main.decorator, 'has_credentials', return_value=True): response = app.get('/') # Should make the api call assert response.status_int == 200 assert re.search( re.compile(r'.*datasets.*datasetReference.*etag.*', re.DOTALL), response.body)
def test_get_media(self): http = HttpMock(datafile('zoo.json'), {'status': '200'}) zoo = build('zoo', 'v1', http=http) request = zoo.animals().get_media(name='Lion') parsed = urlparse(request.uri) q = parse_qs(parsed[4]) self.assertEqual(q['alt'], ['media']) self.assertEqual(request.headers['accept'], '*/*') http = HttpMockSequence([ ({ 'status': '200' }, 'standing in for media'), ]) response = request.execute(http=http) self.assertEqual(b'standing in for media', response)
def setUp(self): # Patch the creation of a Gmail API service without the need for authorized credentials. credentials = get_dummy_credentials() self.get_credentials_mock_patcher = patch( 'lily.messaging.email.connector.get_credentials') get_credentials_mock = self.get_credentials_mock_patcher.start() get_credentials_mock.return_value = credentials self.authorize_mock_patcher = patch.object(GmailService, 'authorize') authorize_mock = self.authorize_mock_patcher.start() authorize_mock.return_value = None self.build_service_mock_patcher = patch.object(GmailService, 'build_service') build_service_mock = self.build_service_mock_patcher.start() http = HttpMock('lily/messaging/email/tests/data/gmail_discovery.json', {'status': '200'}) build_service_mock.return_value = build('gmail', 'v1', http=http)
def test_get_history_id(self, get_http_mock): """ Test the GmailConnector in retrieving the history id. """ get_http_mock.return_value = HttpMock( 'lily/messaging/email/tests/data/get_history_id.json', {'status': '200'}) email_account = EmailAccount.objects.first() connector = GmailConnector(email_account) response = connector.get_history_id() # Verify that the service call returned the correct json object. with open('lily/messaging/email/tests/data/get_history_id.json' ) as infile: json_obj = json.load(infile) self.assertEqual(response, json_obj)
def test_type_coercion(self): http = HttpMock(datafile('zoo.json'), {'status': '200'}) zoo = build('zoo', 'v1', http=http) request = zoo.query(q="foo", i=1.0, n=1.0, b=0, a=[1, 2, 3], o={'a': 1}, e='bar') self._check_query_types(request) request = zoo.query(q="foo", i=1, n=1, b=False, a=[1, 2, 3], o={'a': 1}, e='bar') self._check_query_types(request) request = zoo.query(q="foo", i="1", n="1", b="", a=[1, 2, 3], o={'a': 1}, e='bar', er='two') request = zoo.query(q="foo", i="1", n="1", b="", a=[1, 2, 3], o={'a': 1}, e='bar', er=['one', 'three'], rr=['foo', 'bar']) self._check_query_types(request) # Five is right out. self.assertRaises(TypeError, zoo.query, er=['one', 'five'])
def _setUp_client_with_mock(self, zone_request_side_effect, rrs_list_side_effect=None): from certbot_dns_google._internal.dns_google import _GoogleClient pwd = os.path.dirname(__file__) rel_path = 'testdata/discovery.json' discovery_file = os.path.join(pwd, rel_path) http_mock = HttpMock(discovery_file, {'status': '200'}) dns_api = discovery.build('dns', 'v1', http=http_mock) client = _GoogleClient(ACCOUNT_JSON_PATH, dns_api) # Setup mock_mz = mock.MagicMock() mock_mz.list.return_value.execute.side_effect = zone_request_side_effect mock_rrs = mock.MagicMock() def rrs_list(project=None, managedZone=None, name=None, type=None): response = {"rrsets": []} if name == "_acme-challenge.example.org.": response = { "rrsets": [{ "name": "_acme-challenge.example.org.", "type": "TXT", "rrdatas": ["\"example-txt-contents\""], "ttl": 60 }] } mock_return = mock.MagicMock() mock_return.execute.return_value = response mock_return.execute.side_effect = rrs_list_side_effect return mock_return mock_rrs.list.side_effect = rrs_list mock_changes = mock.MagicMock() client.dns.managedZones = mock.MagicMock(return_value=mock_mz) client.dns.changes = mock.MagicMock(return_value=mock_changes) client.dns.resourceRecordSets = mock.MagicMock(return_value=mock_rrs) return client, mock_changes
def test_save_history_id(self, get_http_mock): """ Test the GmailConnector in saving the updated historty id to the email account. """ get_http_mock.return_value = HttpMock( 'lily/messaging/email/tests/data/get_history_archived.json', {'status': '200'}) email_account = EmailAccount.objects.first() connector = GmailConnector(email_account) # First do a history update, so a new history id is retreived. connector.get_history() # Save the history id to the email account. connector.save_history_id() # Verify that the history is indeed saved on the email account. email_account.refresh_from_db() self.assertEqual(email_account.history_id, 8170)
def setUp(self): http = HttpMock('tests/fixtures/ml_engine/first_result.json', {'status': '200'}) self.ml_engine_test = ml_engine.MlEngine("PROJECT", "BUCKET_NAME", "REGION", http=http) self.main_body = { "trainingInput": { "runtimeVersion": "1.0", "region": "REGION", "pythonModule": "PACOTE.MODULO", "jobDir": "gs://BUCKET_NAME/jobs/PRODUTO_MODULO_1994_04_27_12_00_01", "packageUris": ["gs://BUCKET_NAME/packages/PACOTE"], "args": [] }, "jobId": "PRODUTO_MODULO_1994_04_27_12_00_01" }
def test_bad_request_product(): with patch.object(googleplay.GooglePlayVerifier, "_authorize", return_value=None): verifier = GooglePlayVerifier("bundle_id", "private_key_path") auth = HttpMock(datafile("androidpublisher.json"), headers={"status": 200}) request_mock_builder = RequestMockBuilder( { "androidpublisher.purchases.products.get": ( httplib2.Response({"status": 400, "reason": b"Bad request"}), b'{"reason": "Bad request"}', ) } ) build_mock_result = googleplay.build("androidpublisher", "v3", http=auth, requestBuilder=request_mock_builder) with patch.object(googleplay, "build", return_value=build_mock_result): with pytest.raises(errors.GoogleError, match="Bad request"): verifier.verify("broken_purchase_token", "product_scu")
def test_resumable_media_handle_resume_of_upload_of_unknown_size(self): http = HttpMockSequence([ ({ 'status': '200', 'location': 'http://upload.example.com' }, ''), ({ 'status': '400' }, ''), ]) self.http = HttpMock(datafile('zoo.json'), {'status': '200'}) zoo = build('zoo', 'v1', http=self.http) # Create an upload that doesn't know the full size of the media. fd = BytesIO(b'data goes here') upload = MediaIoBaseUpload(fd=fd, mimetype='image/png', chunksize=500, resumable=True) request = zoo.animals().insert(media_body=upload, body=None) # Put it in an error state. self.assertRaises(HttpError, request.next_chunk, http=http) http = HttpMockSequence([ ({ 'status': '400', 'range': '0-5' }, 'echo_request_headers_as_json'), ]) try: # Should resume the upload by first querying the status of the upload. request.next_chunk(http=http) except HttpError as e: expected = {'Content-Range': 'bytes */14', 'content-length': '0'} self.assertEqual( expected, json.loads(e.content.decode('utf-8')), 'Should send an empty body when requesting the current upload status.' )
def test_create_new_model(self): """Test request to create a new model""" http = HttpMock('tests/fixtures/ml_engine/first_result.json', {'status': '200'}) ml_engine_test = ml_engine.MlEngine("PROJECT", "BUCKET_NAME", "REGION", http=http) post_to_create_model = ml_engine_test.create_new_model( "MODEL", "DESCRIPTION") # Test Method self.assertEqual(post_to_create_model.method, "POST") # Test API self.assertEqual( post_to_create_model.uri, "https://ml.googleapis.com/v1/projects/PROJECT/models?alt=json") # Test Body Post expected = {"name": "MODEL", "description": "DESCRIPTION"} self.assertDictEqual(json.loads(post_to_create_model.body), expected)
def test_get_short_message_info(self, get_http_mock): """ Test the GmailConnector in retrieving the short message info for a specific email message. """ message_id = '15a6008a4baa65f3' get_http_mock.return_value = HttpMock( 'lily/messaging/email/tests/data/get_short_message_info_{0}_archived.json' .format(message_id), {'status': '200'}) email_account = EmailAccount.objects.first() connector = GmailConnector(email_account) response = connector.get_short_message_info(message_id) # Verify that the service call returned the correct json object. with open( 'lily/messaging/email/tests/data/get_short_message_info_{0}_archived.json' .format(message_id)) as infile: json_obj = json.load(infile) self.assertEqual(response, json_obj)
def test_resumable_media_fail_unknown_response_code_first_request(self): """Not a multipart upload.""" self.http = HttpMock(datafile('zoo.json'), {'status': '200'}) zoo = build('zoo', 'v1', http=self.http) media_upload = MediaFileUpload(datafile('small.png'), resumable=True) request = zoo.animals().insert(media_body=media_upload, body=None) http = HttpMockSequence([ ({ 'status': '400', 'location': 'http://upload.example.com' }, ''), ]) try: request.execute(http=http) self.fail('Should have raised ResumableUploadError.') except ResumableUploadError as e: self.assertEqual(400, e.resp.status)
def test_start_prediciton_job(self): """"Teste request to start a training job""" http = HttpMock('tests/fixtures/ml_engine/first_result.json', {'status': '200'}) input_file = "gs://BUCKET/recommendation/matrix_prefs/PRODUTO/input/part-00000" output_file = "gs://BUCKET/recommendation/matrix_prefs/PRODUTO/output/part-00000" ml_engine_test = ml_engine.MlEngine("PROJECT", "BUCKET_NAME", "REGION", http=http) post_to_create = ml_engine_test.start_predict_job( "PRODUTO", "MODEL_NAME", [input_file], output_file) body_expected = { "predictionInput": { "outputPath": "gs://BUCKET/recommendation/matrix_prefs/PRODUTO/output/part-00000", "region": "us-east1", "inputPaths": [ "gs://BUCKET/recommendation/matrix_prefs/PRODUTO/input/part-00000" ], "modelName": "projects/PROJECT/models/MODEL_NAME", "dataFormat": "JSON" }, "jobId": "PRODUTO_MODEL_NAME_1994_04_27_12_00_01_prediction" } method_expected = "POST" uri_expected = "https://ml.googleapis.com/v1/projects/PROJECT/jobs?alt=json" # Test Method self.assertEqual(post_to_create.method, method_expected) # Test API self.assertEqual(post_to_create.uri, uri_expected) # Test Body Post self.assertDictEqual(json.loads(post_to_create.body), body_expected)
def test_trash_email_message(self, get_http_mock): """ Test the GmailConnector on trashing an email message. """ message_id = '15af6279f554fd15' get_http_mock.return_value = HttpMock( 'lily/messaging/email/tests/data/trash_email_message_{0}.json'. format(message_id), {'status': '200'}) email_account = EmailAccount.objects.first() connector = GmailConnector(email_account) response = connector.trash_email_message(message_id) # Verify that the service call returned the correct json object. with open( 'lily/messaging/email/tests/data/trash_email_message_{0}.json'. format(message_id)) as infile: json_obj = json.load(infile) self.assertEqual(response, json_obj)
def test_add_email_account_sync_now(self, get_http_mock): """ After adding an email account via OAUTH the user has to do some settings for the account. Test by editting the account to synchronize only the email messages from this moment on. """ # The google profile is retrieved to get the current history id, mock that API call. get_http_mock.return_value = HttpMock( 'lily/messaging/email/tests/data/profile.json', {'status': '200'}) # Setup the data to patch the email account with. email_account = self.email_accounts[0] from_name = "Firstname Lastname" label = "ABC" only_new = True privacy = EmailAccount.READ_ONLY shared_email_configs = [] stub_dict = { 'id': email_account.pk, 'from_name': from_name, 'label': label, 'only_new': only_new, 'privacy': privacy, 'shared_email_configs': shared_email_configs } # Make the API call to patch the email account. response = self.user.patch('/api/messaging/email/accounts/{0}/'.format( email_account.pk), data=stub_dict, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) # Verify that the email account is up to date with the patched data. email_account.refresh_from_db() self.assertTrue(email_account.is_authorized) self.assertEqual(email_account.history_id, 557200) self.assertEqual(email_account.from_name, from_name) self.assertEqual(email_account.label, label) self.assertEqual(email_account.privacy, EmailAccount.READ_ONLY)
def test_resumable_media_handle_uploads_of_unknown_size(self): http = HttpMockSequence([ ({ 'status': '200', 'location': 'http://upload.example.com' }, ''), ({ 'status': '200' }, 'echo_request_headers_as_json'), ]) self.http = HttpMock(datafile('zoo.json'), {'status': '200'}) zoo = build('zoo', 'v1', http=self.http) # Create an upload that doesn't know the full size of the media. class IoBaseUnknownLength(MediaUpload): def chunksize(self): return 10 def mimetype(self): return 'image/png' def size(self): return None def resumable(self): return True def getbytes(self, begin, length): return '0123456789' upload = IoBaseUnknownLength() request = zoo.animals().insert(media_body=upload, body=None) status, body = request.next_chunk(http=http) self.assertEqual(body, { 'Content-Range': 'bytes 0-9/*', 'Content-Length': '10', })
def test_value_update(): ''' Given: - 'google-sheets-value-update' is being called to be executed with args to the api When: - the command is being called from main Then: - if successful return the proper readable output else google api will through an error ''' http = HttpMock( 'test_data/update_spreadsheet/test_value_update/response.json', {'status': '200'}) api_key = 'your_api_key' service = build('sheets', 'v4', http=http, developerKey=api_key) args = util_load_json( "test_data/update_spreadsheet/test_value_update/command_mock.json") command_result = GoogleSheets.value_update_sheets(service, args) assert command_result.readable_output == '### Successfully updated sheet values'
def test_default_ranges_if_not_specified(include_grid_data, ranges, expected): ''' Given: - spreadsheetId, ranges, include_grid_data Google service When: - we want to check if include_grid_data was specified but not the ranges argument Then: - if include_grid_data is true and ranges not specified return default ranges else return ranges ''' path = 'test_data/helper_functions/test_default_ranges_if_not_specified/' http = HttpMock(os.path.join(path, 'response.json'), {'status': '200'}) api_key = 'your_api_key' service = build('sheets', 'v4', http=http, developerKey=api_key) res = GoogleSheets.default_ranges_if_not_specified("fake", ranges, include_grid_data, service) assert res == expected
def test_no_unicode_in_request_params(self): access_token = u'foo' client_id = u'some_client_id' client_secret = u'cOuDdkfjxxnv+' refresh_token = u'1/0/a.df219fjls0' token_expiry = unicode(datetime.datetime.utcnow()) token_uri = unicode(GOOGLE_TOKEN_URI) revoke_uri = unicode(GOOGLE_REVOKE_URI) user_agent = u'refresh_checker/1.0' credentials = OAuth2Credentials(access_token, client_id, client_secret, refresh_token, token_expiry, token_uri, user_agent, revoke_uri=revoke_uri) http = HttpMock(headers={'status': '200'}) http = credentials.authorize(http) http.request(u'http://example.com', method=u'GET', headers={u'foo': u'bar'}) for k, v in http.headers.iteritems(): self.assertEqual(str, type(k)) self.assertEqual(str, type(v)) # Test again with unicode strings that can't simple be converted to ASCII. try: http.request(u'http://example.com', method=u'GET', headers={u'foo': u'\N{COMET}'}) self.fail('Expected exception to be raised.') except NonAsciiHeaderError: pass self.credentials.token_response = 'foobar' instance = OAuth2Credentials.from_json(self.credentials.to_json()) self.assertEqual('foobar', instance.token_response)
def test_get_message_info(self, get_http_mock): """ Test the GmailConnector in retrieving the info of a single email message. """ get_http_mock.return_value = HttpMock( 'lily/messaging/email/tests/data/get_message_info_15a6008a4baa65f3.json', {'status': '200'}) email_account = EmailAccount.objects.first() connector = GmailConnector(email_account) response = connector.get_message_info('15a6008a4baa65f3') # Verify that the service call returned the correct json object. with open( 'lily/messaging/email/tests/data/get_message_info_15a6008a4baa65f3.json' ) as infile: json_obj = json.load(infile) self.assertEqual(response, json_obj) # Verify that the history id is not retrieved from the get API response. self.assertEqual(connector.history_id, None)
def test_get_status_success(mocker: MockFixture): """ It should be OK and indicate the email of the authenticated user """ mocker.patch( 'toucan_connectors.google_sheets.google_sheets_connector.GoogleSheetsConnector._google_client_request_kwargs', return_value={ 'http': HttpMock( path.join(path.dirname(__file__), './user-infos.json'), {'status': '200'}, ) }, ) gsheet_connector = GoogleSheetsConnector( name='test_connector', retrieve_token=lambda _a, _b: 'access_token', auth_id='test_auth_id', ) connector_status = gsheet_connector.get_status() assert connector_status.status is True assert '*****@*****.**' in connector_status.message
def test_pickle(self): sorted_resource_keys = [ '_baseUrl', '_developerKey', '_dynamic_attrs', '_http', '_model', '_requestBuilder', '_resourceDesc', '_rootDesc', '_schema', 'animals', 'global_', 'load', 'loadNoTemplate', 'my', 'query', 'scopedAnimals' ] http = HttpMock(datafile('zoo.json'), {'status': '200'}) zoo = build('zoo', 'v1', http=http) self.assertEqual(sorted(zoo.__dict__.keys()), sorted_resource_keys) pickled_zoo = pickle.dumps(zoo) new_zoo = pickle.loads(pickled_zoo) self.assertEqual(sorted(new_zoo.__dict__.keys()), sorted_resource_keys) self.assertTrue(hasattr(new_zoo, 'animals')) self.assertTrue(callable(new_zoo.animals)) self.assertTrue(hasattr(new_zoo, 'global_')) self.assertTrue(callable(new_zoo.global_)) self.assertTrue(hasattr(new_zoo, 'load')) self.assertTrue(callable(new_zoo.load)) self.assertTrue(hasattr(new_zoo, 'loadNoTemplate')) self.assertTrue(callable(new_zoo.loadNoTemplate)) self.assertTrue(hasattr(new_zoo, 'my')) self.assertTrue(callable(new_zoo.my)) self.assertTrue(hasattr(new_zoo, 'query')) self.assertTrue(callable(new_zoo.query)) self.assertTrue(hasattr(new_zoo, 'scopedAnimals')) self.assertTrue(callable(new_zoo.scopedAnimals)) self.assertEqual(sorted(zoo._dynamic_attrs), sorted(new_zoo._dynamic_attrs)) self.assertEqual(zoo._baseUrl, new_zoo._baseUrl) self.assertEqual(zoo._developerKey, new_zoo._developerKey) self.assertEqual(zoo._requestBuilder, new_zoo._requestBuilder) self.assertEqual(zoo._resourceDesc, new_zoo._resourceDesc) self.assertEqual(zoo._rootDesc, new_zoo._rootDesc)
def test_get_single_spreadsheet(path): ''' Given: - 'google-sheets-spreadsheet-get' is being called to be executed with a single id in the args When: - the command is being called from main Then: - return the proper readable output and context upon failure an exception will be raised from google. ''' http = HttpMock(path + 'response.json', {'status': '200'}) api_key = 'your_api_key' service = build('sheets', 'v4', http=http, developerKey=api_key) command_result = GoogleSheets.get_spreadsheet( service, util_load_json(os.path.join(path, 'args.json'))) with open(path + 'markdown.md', 'r') as file: markdown_assert = file.read() assert command_result.readable_output == markdown_assert assert command_result.outputs == util_load_json( os.path.join(path, 'output.json'))
def test_get_status_api_down(mocker): """ It should fail if the third-party api is down. """ mocker.patch( 'toucan_connectors.google_sheets.google_sheets_connector.GoogleSheetsConnector._google_client_request_kwargs', return_value={ 'http': HttpMock( path.join(path.dirname(__file__), './user-infos.json'), # the content will not be read {'status': '400'}, ) }, ) gsheet_connector = GoogleSheetsConnector( name='test_connector', retrieve_token=lambda _a, _b: 'access_token', auth_id='test_auth_id', ) connector_status = gsheet_connector.get_status() assert connector_status.status is False
def test_http_error(self): """ Scenario: Evaluate generation of error raising logic when calls to Google API returns an error code other than 403. Given a list of terms of type List[str] And start date in ISO format And end date in ISO format When Google API returns an HTTP error code other than 403 Then GoogleApiClient#fetch_google_scores() logs the HttpError """ http = HttpMock(datafile('trends_discovery.json'), {'status': '200'}) error_bytes = b'{"error" : { ' \ b'"code" : 400, ' \ b'"message" : "Bad Request", ' \ b'"errors" : [{ "reason" : "badRequest" }] } }' response = Response({'status': 400}) request_builder = RequestMockBuilder( {'trends.getTimelinesForHealth': (response, error_bytes)}) with patch.object(GoogleApiClient, '__init__', lambda x: None): instance = GoogleApiClient() instance.service = build(serviceName=SERVICE_NAME, version=SERVICE_VERSION, http=http, developerKey='APIKEY', requestBuilder=request_builder, cache_discovery=False, static_discovery=False) instance.block_until = None terms = ['flu'] start = date.today() - timedelta(days=5) end = start + timedelta(days=1) with self.assertLogs(level='WARNING') as logContext: instance.fetch_google_scores(terms, start, end) self.assertListEqual(logContext.output, [ 'WARNING:root:<HttpError 400 when requesting None returned "Bad Request". Details: "Bad Request">' ])
def test_403_error(self): """ Scenario: Evaluate generation of error raising logic when calls to Google API hit the daily limit. Given a list of terms of type List[str] And start date in ISO format And end date in ISO format When Google API returns HTTP 403 Then GoogleApiClient#fetch_google_scores() raises a RuntimeError """ http = HttpMock(datafile('trends_discovery.json'), {'status': '200'}) error_bytes = b'{"error" : { ' \ b'"code" : 403, ' \ b'"message" : "Daily Limit Exceeded", ' \ b'"errors" : [{ "reason" : "dailyLimitExceeded" }] } }' response = Response({'status': 403}) request_builder = RequestMockBuilder( {'trends.getTimelinesForHealth': (response, error_bytes)}) with patch.object(GoogleApiClient, '__init__', lambda x: None): instance = GoogleApiClient() instance.service = build(serviceName=SERVICE_NAME, version=SERVICE_VERSION, http=http, developerKey='APIKEY', requestBuilder=request_builder, cache_discovery=False, static_discovery=False) instance.block_until = None terms = ['flu'] start = date.today() - timedelta(days=5) end = start + timedelta(days=1) try: instance.fetch_google_scores(terms, start, end) except RuntimeError as runtime_error: self.assertRegex(str(runtime_error), '^dailyLimitExceeded: blocked until ')
def test_execute_service_call_failed_service_call_exception( self, get_http_mock): """ Test if the execute service call raises an exception after it fails after six rate limit errors. """ mock_api_calls = [ # Simulate one FailedServiceCallException by getting six times a rateLimitExceeded error. HttpMock('lily/messaging/email/tests/data/403.json', {'status': '403'}), HttpMock('lily/messaging/email/tests/data/403.json', {'status': '403'}), HttpMock('lily/messaging/email/tests/data/403.json', {'status': '403'}), HttpMock('lily/messaging/email/tests/data/403.json', {'status': '403'}), HttpMock('lily/messaging/email/tests/data/403.json', {'status': '403'}), HttpMock('lily/messaging/email/tests/data/403.json', {'status': '403'}), ] # Mock the http instance with succesive http mock objects. get_http_mock.side_effect = mock_api_calls email_account = EmailAccount.objects.first() connector = GmailConnector(email_account) try: # Execute service call. connector.execute_service_call( connector.gmail_service.service.users().messages().list( userId='me', quotaUser=email_account.id, q='!in:chats', )) self.fail('FailedServiceCallException should have been raised.') except FailedServiceCallException: pass
def setUp(self): http = HttpMock(datafile('zoo.json'), {'status': '200'}) zoo = build('zoo', 'v1', http=http) self.request = zoo.animals().get_media(name='Lion') self.fd = BytesIO()