def test_Client_call_api(homedir, config, mocker): """ A new thread and APICallRunner is created / setup. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) cl.finish_api_call = mocker.MagicMock() mocker.patch('securedrop_client.logic.QThread') mocker.patch('securedrop_client.logic.APICallRunner') mocker.patch('securedrop_client.logic.QTimer') mock_api_call = mocker.MagicMock() mock_callback = mocker.MagicMock() mock_timeout = mocker.MagicMock() cl.call_api(mock_api_call, mock_callback, mock_timeout, 'foo', bar='baz') assert len(cl.api_threads) == 1 thread_info = cl.api_threads[list(cl.api_threads.keys())[0]] thread = thread_info['thread'] runner = thread_info['runner'] timer = thread_info['timer'] thread.started.connect.assert_called_once_with(runner.call_api) thread.start.assert_called_once_with() runner.moveToThread.assert_called_once_with(thread) timer.timeout.connect.call_count == 1 runner.call_finished.connect.call_count == 1
def test_Client_call_api(safe_tmpdir): """ A new thread and APICallRunner is created / setup. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, str(safe_tmpdir)) cl.finish_api_call = mock.MagicMock() with mock.patch('securedrop_client.logic.QThread'), \ mock.patch( 'securedrop_client.logic.APICallRunner'), \ mock.patch('securedrop_client.logic.QTimer'): mock_api_call = mock.MagicMock() mock_callback = mock.MagicMock() mock_timeout = mock.MagicMock() cl.call_api(mock_api_call, mock_callback, mock_timeout, 'foo', bar='baz') assert len(cl.api_threads) == 1 thread_info = cl.api_threads[list(cl.api_threads.keys())[0]] thread = thread_info['thread'] runner = thread_info['runner'] timer = thread_info['timer'] thread.started.connect.assert_called_once_with(runner.call_api) thread.start.assert_called_once_with() runner.moveToThread.assert_called_once_with(thread) timer.timeout.connect.call_count == 1 runner.call_finished.connect.call_count == 1
def test_Client_call_api(): """ A new thread and APICallRunner is created / setup. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session) cl.finish_api_call = mock.MagicMock() with mock.patch('securedrop_client.logic.QThread') as mock_qthread, \ mock.patch('securedrop_client.logic.APICallRunner') as mock_runner: mock_api_call = mock.MagicMock() mock_callback = mock.MagicMock() mock_timeout = mock.MagicMock() cl.call_api(mock_api_call, mock_callback, mock_timeout, 'foo', bar='baz') cl.api_thread.started.connect.\ assert_called_once_with(cl.api_runner.call_api) cl.api_thread.finished.connect.\ assert_called_once_with(cl.call_reset) cl.api_thread.start.assert_called_once_with() cl.api_runner.moveToThread.assert_called_once_with(cl.api_thread) cl.api_runner.call_finished.connect.\ assert_called_once_with(mock_callback) cl.api_runner.timeout.connect.assert_called_once_with(mock_timeout) cl.finish_api_call.connect(cl.api_runner.on_cancel_timeout)
def test_Client_call_api_existing_thread(): """ The client will ignore attempt to call API if an existing request is in progress. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session) cl.api_thread = True cl.call_api(mock.MagicMock(), mock.MagicMock(), mock.MagicMock()) assert cl.api_thread is True
def test_Client_on_file_download_Reply(homedir, config, mocker): """ If the handler is passed a reply, check the download_reply function is the one called against the API. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) source = factory.Source() journalist = db.User('Testy mcTestface') reply = db.Reply('reply-uuid', journalist, source, 'my-reply.gpg', 123) # Not a sdclientapi.Submission cl.call_api = mocker.MagicMock() cl.api = mocker.MagicMock() reply_sdk_object = mocker.MagicMock() mock_reply = mocker.patch('sdclientapi.Reply') mock_reply.return_value = reply_sdk_object cl.on_file_download(source, reply) cl.call_api.assert_called_once_with(cl.api.download_reply, cl.on_file_downloaded, cl.on_download_timeout, reply_sdk_object, cl.data_dir, current_object=reply)
def test_Client_on_file_download_Reply(safe_tmpdir): """ If the handler is passed a reply, check the download_reply function is the one called against the API. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, str(safe_tmpdir)) source = models.Source('source-uuid', 'testy-mctestface', False, 'mah pub key', 1, False, datetime.now()) journalist = models.User('Testy mcTestface') reply = models.Reply('reply-uuid', journalist, source, 'my-reply.gpg', 123) # Not a sdclientapi.Submission cl.call_api = mock.MagicMock() cl.api = mock.MagicMock() reply_sdk_object = mock.MagicMock() with mock.patch('sdclientapi.Reply') as mock_reply: mock_reply.return_value = reply_sdk_object cl.on_file_download(source, reply) cl.call_api.assert_called_once_with(cl.api.download_reply, cl.on_file_downloaded, cl.on_download_timeout, reply_sdk_object, cl.data_dir, current_object=reply)
def test_Client_unstars_a_source_if_unstarred(homedir, config, mocker): """ Ensure that the client stars a source if it is unstarred. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) source_db_object = mocker.MagicMock() source_db_object.uuid = mocker.MagicMock() source_db_object.is_starred = False cl.call_api = mocker.MagicMock() cl.api = mocker.MagicMock() cl.api.add_star = mocker.MagicMock() cl.on_update_star_complete = mocker.MagicMock() cl.on_sidebar_action_timeout = mocker.MagicMock() source_sdk_object = mocker.MagicMock() mock_source = mocker.patch('sdclientapi.Source') mock_source.return_value = source_sdk_object cl.update_star(source_db_object) cl.call_api.assert_called_once_with(cl.api.add_star, cl.on_update_star_complete, cl.on_sidebar_action_timeout, source_sdk_object) mock_gui.update_error_status.assert_called_once_with("")
def test_Client_sync_api_not_authenticated(safe_tmpdir): """ If the API isn't authenticated, don't sync. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, str(safe_tmpdir)) cl.authenticated = mock.MagicMock(return_value=False) cl.call_api = mock.MagicMock() cl.sync_api() assert cl.call_api.call_count == 0
def test_Client_sync_api(safe_tmpdir): """ Sync the API is authenticated. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, str(safe_tmpdir)) cl.authenticated = mock.MagicMock(return_value=True) cl.call_api = mock.MagicMock() cl.sync_api() cl.call_api.assert_called_once_with(storage.get_remote_data, cl.on_synced, cl.on_sync_timeout, cl.api)
def test_Client_sync_api_not_authenticated(homedir, config, mocker): """ If the API isn't authenticated, don't sync. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) cl.authenticated = mocker.MagicMock(return_value=False) cl.call_api = mocker.MagicMock() cl.sync_api() assert cl.call_api.call_count == 0
def test_Client_sync_api(homedir, config, mocker): """ Sync the API is authenticated. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) cl.authenticated = mocker.MagicMock(return_value=True) cl.call_api = mocker.MagicMock() cl.sync_api() cl.call_api.assert_called_once_with(storage.get_remote_data, cl.on_synced, cl.on_sync_timeout, cl.api)
def test_Client_login(safe_tmpdir): """ Ensures the API is called in the expected manner for logging in the user given the username, password and 2fa token. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, str(safe_tmpdir)) cl.call_api = mock.MagicMock() with mock.patch('securedrop_client.logic.sdclientapi.API') as mock_api: cl.login('username', 'password', '123456') cl.call_api.assert_called_once_with(mock_api().authenticate, cl.on_authenticate, cl.on_login_timeout)
def test_Client_delete_source(homedir, config, mocker): ''' Using the `config` fixture to ensure the config is written to disk. ''' mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() mock_source = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) cl.call_api = mocker.MagicMock() cl.api = mocker.MagicMock() cl.delete_source(mock_source) cl.call_api.assert_called_with(cl.api.delete_source, cl._on_delete_source_complete, cl._on_delete_action_timeout, mock_source)
def test_Client_login(homedir, config, mocker): """ Ensures the API is called in the expected manner for logging in the user given the username, password and 2fa token. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) cl.call_api = mocker.MagicMock() mock_api = mocker.patch('securedrop_client.logic.sdclientapi.API') cl.login('username', 'password', '123456') cl.call_api.assert_called_once_with(mock_api().authenticate, cl.on_authenticate, cl.on_login_timeout)
def test_Client_on_file_download_Submission(safe_tmpdir): """ If the handler is passed a submission, check the download_submission function is the one called against the API. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, str(safe_tmpdir)) source = models.Source('source-uuid', 'testy-mctestface', False, 'mah pub key', 1, False, datetime.now()) submission = models.Submission(source, 'submission-uuid', 1234, 'myfile.doc.gpg', 'http://myserver/myfile') cl.call_api = mock.MagicMock() cl.api = mock.MagicMock() submission_sdk_object = mock.MagicMock() with mock.patch('sdclientapi.Submission') as mock_submission: mock_submission.return_value = submission_sdk_object cl.on_file_download(source, submission) cl.call_api.assert_called_once_with(cl.api.download_submission, cl.on_file_downloaded, cl.on_download_timeout, submission_sdk_object, cl.data_dir, current_object=submission)
def test_Client_unstars_a_source_if_unstarred(safe_tmpdir): """ Ensure that the client stars a source if it is unstarred. """ mock_gui = mock.MagicMock() mock_session = mock.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, str(safe_tmpdir)) source_db_object = mock.MagicMock() source_db_object.uuid = mock.MagicMock() source_db_object.is_starred = False cl.call_api = mock.MagicMock() cl.api = mock.MagicMock() cl.api.add_star = mock.MagicMock() cl.on_update_star_complete = mock.MagicMock() cl.on_sidebar_action_timeout = mock.MagicMock() source_sdk_object = mock.MagicMock() with mock.patch('sdclientapi.Source') as mock_source: mock_source.return_value = source_sdk_object cl.update_star(source_db_object) cl.call_api.assert_called_once_with(cl.api.add_star, cl.on_update_star_complete, cl.on_sidebar_action_timeout, source_sdk_object) mock_gui.update_error_status.assert_called_once_with("")
def test_Client_on_file_download_Submission(homedir, config, mocker): """ If the handler is passed a submission, check the download_submission function is the one called against the API. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() cl = Client('http://localhost', mock_gui, mock_session, homedir) source = factory.Source() submission = db.Submission(source, 'submission-uuid', 1234, 'myfile.doc.gpg', 'http://myserver/myfile') cl.call_api = mocker.MagicMock() cl.api = mocker.MagicMock() submission_sdk_object = mocker.MagicMock() mock_submission = mocker.patch('sdclientapi.Submission') mock_submission.return_value = submission_sdk_object cl.on_file_download(source, submission) cl.call_api.assert_called_once_with(cl.api.download_submission, cl.on_file_downloaded, cl.on_download_timeout, submission_sdk_object, cl.data_dir, current_object=submission)