async def test_Searcher__search_reports_error(searcher, mocker): mock_methods = { '_results_callback': Mock(), '_searching_callback': Mock(), '_delay': AsyncMock(), '_search_coro': AsyncMock(side_effect=errors.RequestError('internet is down')), '_error_callback': Mock(), } mocks = Mock(**mock_methods) mocker.patch.multiple(searcher, **mock_methods) await searcher._search('mock query') assert mocks.mock_calls == [ call._results_callback(()), call._searching_callback(True), call._delay(), call._search_coro('mock query'), call._error_callback(errors.RequestError('internet is down')), call._searching_callback(False), call._results_callback(()), ]
async def test_handle_input_handles_RequestError(make_ImageHostJob): job = make_ImageHostJob(images_total=3) job._imghost.upload.side_effect = errors.RequestError('ugly image') await job.handle_input('foo.jpg') assert job._imghost.upload.call_args_list == [ call('foo.jpg', cache=not job.ignore_cache), ] assert job.output == () assert job.errors == (errors.RequestError('ugly image'),) assert job.images_uploaded == 0
async def test_search_handles_RequestError_from_search(make_SceneSearchJob, mocker): job = make_SceneSearchJob() cb = Mock() job.signal.register('search_results', cb) search_mock = mocker.patch('upsies.utils.scene.search', AsyncMock( side_effect=errors.RequestError('no interwebs'), )) await job._search() assert search_mock.call_args_list == [call(job._content_path)] assert job.output == () assert job.errors == (errors.RequestError('no interwebs'),) assert job.exit_code == 1 assert job.is_finished assert cb.call_args_list == []
async def test_fetch_text_catches_fatal_error(default_text, finish_on_success, make_TextFieldJob): fetcher = AsyncMock(side_effect=errors.RequestError('connection failed')) job = make_TextFieldJob(name='foo', label='Foo', text='Original text') assert not job.is_finished await job.fetch_text(fetcher, default_text=default_text, finish_on_success=finish_on_success, error_is_fatal=True) assert job.text == ('Original text' if default_text is None else default_text) assert job.output == () assert job.errors == (errors.RequestError('connection failed'), ) assert job.warnings == () assert job.is_finished is True assert job.exit_code == 0
async def test_upload_image_gets_unexpected_error(error_text, mocker, tmp_path): mocker.patch('upsies.utils.http.post', AsyncMock( side_effect=errors.RequestError('ignored', text=error_text), )) imghost = imgbb.ImgbbImageHost(cache_directory=tmp_path) with pytest.raises(errors.RequestError, match=rf'^Upload failed: {re.escape(str(error_text))}$'): await imghost._upload_image('some/image.png')
async def test_download_writes_filepath(mocker, tmp_path): mocker.patch('upsies.utils.http.get', AsyncMock(side_effect=errors.RequestError('no response'), )) filepath = tmp_path / 'downloaded' with pytest.raises(errors.RequestError, match=r'^no response$'): await http.download('mock url', filepath) assert not filepath.exists()
def test_open_files_raises_exception_from_get_file_object(mocker): mocker.patch('upsies.utils.http._get_file_object', side_effect=errors.RequestError('bad io')) with pytest.raises(errors.RequestError, match=r'^bad io$'): http._open_files({ 'image': 'path/to/foo.jpg', 'document': ('path/to/bar', 'text/plain'), })
async def test_handle_input_catches_RequestError(make_AddTorrentJob): job = make_AddTorrentJob() job._client.add_torrent.side_effect = errors.RequestError( 'No such file or whatever') await job.handle_input('foo.torrent') assert job.errors == ( 'Failed to add foo.torrent to mocksy: No such file or whatever', ) assert job.output == ()
async def test_submit_handles_RequestError_from_tracker_coro(method, job): setattr( job._tracker, method, AsyncMock(side_effect=errors.RequestError(f'{method}: No connection')), ) assert job.output == () assert job.errors == () await job._submit() if method == 'logout': assert job.output == (str(job._tracker.upload.return_value), ) else: assert job.output == () assert job.errors == (errors.RequestError(f'{method}: No connection'), ) if method in ('upload', 'logout'): assert job._tracker.logout.call_args_list == [call()] else: assert job._tracker.logout.call_args_list == []
async def test_get_image_url_prepends_image_path_to_request_error( mocker, tmp_path): ih = make_TestImageHost(cache_directory=tmp_path) mocker.patch.object( ih, '_upload_image', AsyncMock(side_effect=errors.RequestError('Connection refused'))) mocker.patch.object( ih, '_get_url_from_cache', Mock(return_value='http://localhost:123/cached.image.jpg')) mocker.patch.object(ih, '_store_url_to_cache') with pytest.raises(errors.RequestError, match=r'^Connection refused$'): await ih._get_image_url('path/to/image.jpg', cache=False) assert ih._get_url_from_cache.call_args_list == [] assert ih._upload_image.call_args_list == [call('path/to/image.jpg')] assert ih._store_url_to_cache.call_args_list == []
async def test_UpdateInfoThread_call_callback_handles_RequestError( info_updater, mocker): mocks = Mock( value_getter=AsyncMock(side_effect=errors.RequestError('Nah')), callback=Mock(), error_callback=Mock(), sleep_mock=AsyncMock(), ) info_updater._error_callback = mocks.error_callback mocker.patch('asyncio.sleep', mocks.sleep_mock) info_updater._cache.clear() await info_updater._call_callback( callback=mocks.callback, value_getter=mocks.value_getter, cache_key=('id', 'key'), ) assert mocks.mock_calls == [ call.callback(Ellipsis), call.sleep_mock(info_updater._delay_between_updates), call.value_getter(), call.callback(''), call.error_callback(errors.RequestError('Nah')), ] assert info_updater._cache == {}
async def test_upload_image_gets_expected_error(mocker, tmp_path): mocker.patch('upsies.utils.http.post', AsyncMock( side_effect=errors.RequestError('ignored', text=json.dumps({ "status_code": 400, "error": { "message": "Your request sucks", "code": 310, "context": "CHV\\UploadException" }, "status_txt": "Bad Request" })) )) imghost = imgbb.ImgbbImageHost(cache_directory=tmp_path) with pytest.raises(errors.RequestError, match=r'^Bad Request: Your request sucks$'): await imghost._upload_image('some/image.png')
async def test_get_apikey_when_request_fails(mocker, tmp_path): get_mock = mocker.patch('upsies.utils.http.get', AsyncMock()) post_mock = mocker.patch('upsies.utils.http.post', AsyncMock( side_effect=errors.RequestError('no interwebs'), )) imghost = ptpimg.PtpimgImageHost(options={}, cache_directory=tmp_path) with pytest.raises(errors.RequestError, match=r'^no interwebs$'): await imghost.get_apikey('foo@localhost', 'hunter2') assert post_mock.call_args_list == [call( url=f'{imghost.options["base_url"]}/login.php', cache=False, data={ 'email': 'foo@localhost', 'pass': '******', 'login': '', }, )] assert get_mock.call_args_list == []
async def test_handle_input_sets_info_property_on_failure(make_AddTorrentJob): infos = [ 'Adding foo.torrent', '', '', ] def info_cb(_): assert job.info == infos.pop(0) job = make_AddTorrentJob() job._client.add_torrent.side_effect = errors.RequestError('No') job.signal.register('adding', info_cb) job.signal.register('added', info_cb) job.signal.register('error', info_cb) job.signal.register('finished', info_cb) await job.handle_input('path/to/foo.torrent') assert infos == []
def test_RequestError_headers(): e = errors.RequestError('foo', headers={'a': 1, 'b': 2}) assert e.headers == {'a': 1, 'b': 2}
def test_RequestError_url(): e = errors.RequestError('foo', url='http://foo') assert e.url == 'http://foo'
] assert generate_episode_queries_mock.call_args_list == [] @pytest.mark.parametrize( argnames='dbs, exp_results, exp_exception, exp_queried_db_names', argvalues=( ( (make_db_class(name='foo', exception=None), make_db_class(name='bar', exception=None)), 'foo search results', None, ['foo'], ), ( (make_db_class(name='foo', exception=errors.RequestError('foo is down')), make_db_class(name='bar', exception=None)), 'bar search results', None, ['foo', 'bar'], ), ( (make_db_class(name='foo', exception=errors.RequestError('foo is down')), make_db_class(name='bar', exception=errors.RequestError('bar is down'))), None, errors.RequestError('All queries failed: foo is down, bar is down'), ['foo', 'bar'], ), ( (), [],
def test_RequestError_status_code(): e = errors.RequestError('foo', status_code=123) assert e.status_code == 123
imghost = make_TestImageHost() assert imghost.description == '' @pytest.mark.parametrize( argnames='options, exp_exception', argvalues=( ({}, None), ({ 'apikey': 'd34db33f' }, None), ({ 'apikey': '' }, errors.RequestError( 'You must configure an API key first. Run ' f'"{__project_name__} upload-images {{name}} --help" ' 'for more information.')), ), ) @pytest.mark.asyncio async def test_upload_checks_for_missing_apikey(options, exp_exception, mocker, tmp_path): resize_mock = mocker.patch('upsies.utils.image.resize') ih = make_TestImageHost(cache_directory=tmp_path, options=options) mocker.patch.object(ih, '_get_image_url', AsyncMock()) if exp_exception is None: await ih.upload('foo.png') assert resize_mock.call_args_list == [] assert ih._get_image_url.call_args_list == [ call('foo.png', cache=True) ]
method=method, ).respond_with_handler(Handler(), ) result = await http._request( method=method, url=httpserver.url_for('/foo'), user_agent=user_agent, ) assert result == 'have this' assert isinstance(result, http.Result) @pytest.mark.parametrize( argnames='timeout, response_delay, exp_exception', argvalues=( (1, 0.5, None), (1, 1.5, errors.RequestError('timeout')), ), ) @pytest.mark.parametrize('method', ('GET', 'POST')) @pytest.mark.asyncio async def test_request_with_timeout_argument(method, timeout, response_delay, exp_exception, mock_cache, httpserver): class Handler(RequestHandler): def handle(self, request): import time time.sleep(response_delay) return Response('have this') httpserver.expect_request( uri='/foo',
def test_RequestError_text(): e = errors.RequestError('foo', text='Error 404') assert e.text == 'Error 404'
async def coro(): raise errors.RequestError('teh interwebs borked!')
(tuple(f'Foo {i}' for i in range(7)), -1), None, ), ( 'foo bar baz', 3, {'status': 'success', 'data': None}, ((), -1), None, ), ( 'foo bar baz', 3, {'status': 'not success', 'message': 'Something went wrong'}, None, errors.RequestError(f'{predbde.PredbdeApi.label}: Something went wrong'), ), ), ids=lambda v: str(v), ) @pytest.mark.asyncio async def test_request_page(q, page, response, exp_return_value, exp_exception, api, mocker): mock_search_url = 'http://foo/api' mocker.patch.object(api, '_search_url', mock_search_url) get_mock = mocker.patch('upsies.utils.http.get', AsyncMock(return_value=Mock( json=Mock(return_value=response), ))) if exp_exception: with pytest.raises(type(exp_exception), match=rf'^{re.escape(str(exp_exception))}$'):
data = 'mock data' files = 'mock files' await client._request(path, data=data, files=files) assert post_mock.call_args_list == [ call(url=exp_request_url, headers=client._headers, data=data, files=files) ] @pytest.mark.parametrize( argnames='response, exception, exp_exception', argvalues=( ('Ok.', None, None), ('Fails.', None, errors.RequestError('Authentication failed')), (None, errors.RequestError('qBittorrent: Bad request'), errors.RequestError('qBittorrent: Bad request')), ), ids=lambda v: str(v), ) @pytest.mark.asyncio async def test_login(response, exception, exp_exception, mocker): client = qbittorrent.QbittorrentClientApi(config={ 'username': '******', 'password': '******', 'foo': 'bar', }) if exception: mocker.patch.object(client, '_request', AsyncMock(side_effect=exception))