def test_Controller_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() co = Controller('http://localhost', mock_gui, mock_session, homedir) source = factory.Source() journalist = db.User('Testy mcTestface') reply = db.Reply(uuid='reply-uuid', journalist=journalist, source=source, filename='1-my-reply.gpg', size=123) # Not a sdclientapi.Submission co.call_api = mocker.MagicMock() co.api = mocker.MagicMock() reply_sdk_object = mocker.MagicMock() mock_reply = mocker.patch('sdclientapi.Reply') mock_reply.return_value = reply_sdk_object co.on_file_download(source, reply) co.call_api.assert_called_once_with(co.api.download_reply, co.on_file_download_success, co.on_file_download_failure, reply_sdk_object, co.data_dir, current_object=reply)
def test_Controller_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() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.call_api = mocker.MagicMock() co.api = mocker.MagicMock() source = factory.Source() file_ = db.File(source=source, uuid='uuid', size=1234, filename='1-myfile.doc.gpg', download_url='http://myserver/myfile', is_downloaded=False) submission_sdk_object = mocker.MagicMock() mock_submission = mocker.patch('sdclientapi.Submission') mock_submission.return_value = submission_sdk_object co.on_file_download(source, file_) co.call_api.assert_called_once_with( co.api.download_submission, co.on_file_download_success, co.on_file_download_failure, submission_sdk_object, co.data_dir, current_object=file_, )
def test_Controller_on_reply_success(homedir, mocker): ''' Check that when the result is a success, the client emits the correct signal. ''' mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() mock_reply_init = mocker.patch('securedrop_client.logic.db.Reply') co = Controller('http://localhost', mock_gui, mock_session, homedir) co.api = mocker.Mock() journalist_uuid = 'abc123' co.api.token_journalist_uuid = journalist_uuid mock_reply_succeeded = mocker.patch.object(co, 'reply_succeeded') mock_reply_failed = mocker.patch.object(co, 'reply_failed') reply = sdlocalobjects.Reply(uuid='xyz456', filename='1-wat.gpg') source_uuid = 'foo111' msg_uuid = 'bar222' current_object = (source_uuid, msg_uuid) co.on_reply_success(reply, current_object) co.session.commit.assert_called_once_with() mock_reply_succeeded.emit.assert_called_once_with(msg_uuid) assert not mock_reply_failed.emit.called assert mock_reply_init.called # to prevent stale mocks
def test_Controller_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() co = Controller('http://localhost', mock_gui, mock_session, homedir) source_db_object = mocker.MagicMock() source_db_object.uuid = mocker.MagicMock() source_db_object.is_starred = False co.call_api = mocker.MagicMock() co.api = mocker.MagicMock() co.api.add_star = mocker.MagicMock() co.on_update_star_success = mocker.MagicMock() co.on_update_star_failure = mocker.MagicMock() source_sdk_object = mocker.MagicMock() mock_source = mocker.patch('sdclientapi.Source') mock_source.return_value = source_sdk_object co.update_star(source_db_object) co.call_api.assert_called_once_with( co.api.add_star, co.on_update_star_success, co.on_update_star_failure, source_sdk_object, ) mock_gui.clear_error_status.assert_called_once_with()
def test_Controller_send_reply_gpg_error(homedir, mocker): ''' Check that if gpg fails when sending a message, we alert the UI and do *not* call the API. ''' mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.call_api = mocker.Mock() co.api = mocker.Mock() mock_encrypt = mocker.patch.object(co.gpg, 'encrypt_to_source', side_effect=Exception) source_uuid = 'abc123' msg_uuid = 'xyz456' msg = 'wat' mock_sdk_source = mocker.Mock() mock_source_init = mocker.patch( 'securedrop_client.logic.sdclientapi.Source', return_value=mock_sdk_source) mock_reply_failed = mocker.patch.object(co, 'reply_failed') co.send_reply(source_uuid, msg_uuid, msg) # ensure there is an attempt to encrypt the message mock_encrypt.assert_called_once_with(source_uuid, msg) # ensure we emit a failure on gpg errors mock_reply_failed.emit.assert_called_once_with(msg_uuid) # ensure api not is called after a gpg error assert not co.call_api.called assert mock_source_init.called # to prevent stale mocks
def test_Controller_authenticated_no_api(homedir, config, mocker): """ If the API is authenticated return True. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.api = None assert co.authenticated() is False
def test_Controller_update_star_not_logged_in(homedir, config, mocker): """ Ensure that starring/unstarring a source when not logged in calls the method that displays an error status in the left sidebar. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) source_db_object = mocker.MagicMock() co.on_action_requiring_login = mocker.MagicMock() co.api = None co.update_star(source_db_object) co.on_action_requiring_login.assert_called_with()
def test_Controller_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() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.call_api = mocker.MagicMock() co.api = mocker.MagicMock() co.delete_source(mock_source) co.call_api.assert_called_with(co.api.delete_source, co.on_delete_source_success, co.on_delete_source_failure, mock_source)
def test_Controller_start_reply_thread_if_already_running( homedir, config, mocker): """ Ensure that when starting the reply thread, we don't start another thread if it's already running. Instead, we just authenticate the existing thread. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.api = 'api object' co.reply_sync = mocker.MagicMock() co.reply_thread = mocker.MagicMock() co.reply_thread.api = None co.start_reply_thread() co.reply_sync.api = co.api co.reply_thread.start.assert_not_called()
def test_Controller_logout(homedir, config, mocker): """ The API is reset to None and the UI is set to logged out state. The message and reply threads should also have the Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.api = mocker.MagicMock() co.message_sync = mocker.MagicMock() co.reply_sync = mocker.MagicMock() co.message_sync.api = mocker.MagicMock() co.reply_sync.api = mocker.MagicMock() co.logout() assert co.api is None assert co.message_sync.api is None assert co.reply_sync.api is None co.gui.logout.assert_called_once_with()
def test_Controller_on_authenticate_success(homedir, config, mocker): """ Ensure the client syncs when the user successfully logs in. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.sync_api = mocker.MagicMock() co.api = mocker.MagicMock() co.start_message_thread = mocker.MagicMock() co.start_reply_thread = mocker.MagicMock() co.api.username = '******' co.on_authenticate_success(True) co.sync_api.assert_called_once_with() co.start_message_thread.assert_called_once_with() co.gui.show_main_window.assert_called_once_with('test') co.gui.clear_error_status.assert_called_once_with()
def test_Controller_on_reply_failure(homedir, mocker): ''' Check that when the result is a failure, the client emits the correct signal. ''' mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.api = mocker.Mock() journalist_uuid = 'abc123' co.api.token_journalist_uuid = journalist_uuid mock_reply_succeeded = mocker.patch.object(co, 'reply_succeeded') mock_reply_failed = mocker.patch.object(co, 'reply_failed') source_uuid = 'foo111' msg_uuid = 'bar222' current_object = (source_uuid, msg_uuid) co.on_reply_failure(Exception, current_object) mock_reply_failed.emit.assert_called_once_with(msg_uuid) assert not mock_reply_succeeded.emit.called
def test_Controller_send_reply_success(homedir, mocker): ''' Check that the "happy path" of encrypting a message and sending it to the sever behaves as expected. ''' mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) co.call_api = mocker.Mock() co.api = mocker.Mock() encrypted_reply = 's3kr1t m3ss1dg3' mock_encrypt = mocker.patch.object(co.gpg, 'encrypt_to_source', return_value=encrypted_reply) source_uuid = 'abc123' msg_uuid = 'xyz456' msg = 'wat' mock_sdk_source = mocker.Mock() mock_source_init = mocker.patch( 'securedrop_client.logic.sdclientapi.Source', return_value=mock_sdk_source) co.send_reply(source_uuid, msg_uuid, msg) # ensure message is encrypted mock_encrypt.assert_called_once_with(source_uuid, msg) # ensure api is called co.call_api.assert_called_once_with( co.api.reply_source, co.on_reply_success, co.on_reply_failure, mock_sdk_source, encrypted_reply, msg_uuid, current_object=(source_uuid, msg_uuid), ) assert mock_source_init.called # to prevent stale mocks
def test_Controller_on_file_download_user_not_signed_in( homedir, config, mocker): """ If a user clicks the download button but is not logged in, an error should appear. Using the `config` fixture to ensure the config is written to disk. """ mock_gui = mocker.MagicMock() mock_session = mocker.MagicMock() co = Controller('http://localhost', mock_gui, mock_session, homedir) source = factory.Source() file_ = db.File(source=source, uuid='uuid', size=1234, filename='1-myfile.doc.gpg', download_url='http://myserver/myfile', is_downloaded=False) co.on_action_requiring_login = mocker.MagicMock() co.api = None submission_sdk_object = mocker.MagicMock() mock_submission = mocker.patch('sdclientapi.Submission') mock_submission.return_value = submission_sdk_object co.on_file_download(source, file_) co.on_action_requiring_login.assert_called_once_with()