Exemple #1
0
def test_Controller_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()
    co = Controller('http://localhost', mock_gui, mock_session, homedir)
    co.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_success_callback = mocker.MagicMock()
    mock_failure_callback = mocker.MagicMock()

    co.call_api(mock_api_call,
                mock_success_callback,
                mock_failure_callback,
                'foo',
                bar='baz')

    assert len(co.api_threads) == 1
    thread_info = co.api_threads[list(co.api_threads.keys())[0]]
    thread = thread_info['thread']
    runner = thread_info['runner']
    thread.started.connect.assert_called_once_with(runner.call_api)
    thread.start.assert_called_once_with()
    runner.moveToThread.assert_called_once_with(thread)
    runner.call_succeeded.connect.call_count == 1
    runner.call_failed.connect.call_count == 1
    runner.call_timed_out.connect.call_count == 1
Exemple #2
0
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)
Exemple #3
0
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_,
    )
Exemple #4
0
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()
Exemple #5
0
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
Exemple #6
0
def test_Controller_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()
    co = Controller('http://localhost', mock_gui, mock_session, homedir)
    co.authenticated = mocker.MagicMock(return_value=False)
    co.call_api = mocker.MagicMock()
    co.sync_api()
    assert co.call_api.call_count == 0
Exemple #7
0
def test_Controller_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()
    co = Controller('http://localhost', mock_gui, mock_session, homedir)
    co.authenticated = mocker.MagicMock(return_value=True)
    co.call_api = mocker.MagicMock()
    co.sync_api()
    co.call_api.assert_called_once_with(storage.get_remote_data,
                                        co.on_sync_success, co.on_sync_failure,
                                        co.api)
Exemple #8
0
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)
Exemple #9
0
def test_Controller_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()
    co = Controller('http://localhost', mock_gui, mock_session, homedir)
    co.call_api = mocker.MagicMock()
    mock_api = mocker.patch('securedrop_client.logic.sdclientapi.API')
    co.login('username', 'password', '123456')
    co.call_api.assert_called_once_with(mock_api().authenticate,
                                        co.on_authenticate_success,
                                        co.on_authenticate_failure)
Exemple #10
0
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
Exemple #11
0
def test_Controller_login_offline_mode(homedir, config, mocker):
    """
    Ensures user is not authenticated when logging in in offline mode and that the correct windows
    are displayed.
    """
    co = Controller('http://localhost', mocker.MagicMock(), mocker.MagicMock(),
                    homedir)
    co.call_api = mocker.MagicMock()
    co.gui = mocker.MagicMock()
    co.gui.show_main_window = mocker.MagicMock()
    co.gui.hide_login = mocker.MagicMock()
    co.start_message_thread = mocker.MagicMock()
    co.start_reply_thread = mocker.MagicMock()
    co.update_sources = mocker.MagicMock()

    co.login_offline_mode()

    assert co.call_api.called is False
    assert co.is_authenticated is False
    co.gui.show_main_window.assert_called_once_with()
    co.gui.hide_login.assert_called_once_with()
    co.start_message_thread.assert_called_once_with()
    co.update_sources.assert_called_once_with()