示例#1
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)
示例#2
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_,
    )
示例#3
0
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
示例#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()
示例#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
示例#6
0
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
示例#7
0
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()
示例#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)
示例#9
0
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()
示例#10
0
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()
示例#11
0
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()
示例#12
0
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
示例#13
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
示例#14
0
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()