Exemplo n.º 1
0
def test_update_submissions_deletes_files_associated_with_the_submission(
        homedir, mocker):
    """
    Check that:

    * Submissions are deleted on disk after sync.
    """
    mock_session = mocker.MagicMock()

    # Test scenario: one submission locally, no submissions on server.
    remote_submissions = []

    # A local submission object. To ensure that all files from various
    # stages of processing are cleaned up, we'll add several filenames.
    server_filename = "1-pericardial-surfacing-msg.gpg"
    local_filename_when_decrypted = "1-pericardial-surfacing-msg"

    local_submission = mocker.MagicMock()
    local_submission.uuid = "test-uuid"
    local_submission.filename = server_filename
    local_submission_source_journalist_filename = "pericardial_surfacing"
    source_directory = os.path.join(
        homedir, local_submission_source_journalist_filename)
    local_submission.location = mocker.MagicMock(return_value=os.path.join(
        source_directory, local_filename_when_decrypted))
    abs_local_filename = add_test_file_to_temp_dir(
        source_directory, local_filename_when_decrypted)
    local_submissions = [local_submission]

    # There needs to be a corresponding local_source.
    local_source = mocker.MagicMock()
    local_source.uuid = "test-source-uuid"
    local_source.id = 666
    mock_session.query().filter_by.return_value = [local_source]
    update_files(remote_submissions, local_submissions, mock_session, homedir)

    # Ensure the files associated with the submission are deleted on disk.
    assert not os.path.exists(abs_local_filename)

    # Ensure the record for the local submission is gone.
    mock_session.delete.assert_called_once_with(local_submission)

    # Session is committed to database.
    assert mock_session.commit.call_count == 1
Exemplo n.º 2
0
def test_update_files_renames_file_on_disk(homedir, mocker):
    """
    Check that:

    * Submissions are renamed on disk after sync.
    """
    data_dir = os.path.join(homedir, 'data')
    mock_session = mocker.MagicMock()
    # Remote submission with new filename
    server_filename = '1-spotted-potato-msg.gpg'
    remote_submission = mocker.MagicMock()
    remote_submission.uuid = 'test-uuid'
    remote_submission.filename = server_filename
    remote_submissions = [remote_submission]
    # Local submission that needs to be updated
    local_filename = '1-pericardial-surfacing-msg.gpg'
    local_submission = mocker.MagicMock()
    local_submission.uuid = 'test-uuid'
    local_submission.filename = local_filename
    local_submissions = [local_submission]
    # Add submission file to test directory
    local_filename_decrypted = '1-pericardial-surfacing-msg'
    add_test_file_to_temp_dir(data_dir, local_filename_decrypted)
    # There needs to be a corresponding local_source.
    local_source = mocker.MagicMock()
    local_source.uuid = 'test-source-uuid'
    local_source.id = 123
    mock_session.query().filter_by.return_value = [
        local_source,
    ]

    update_files(remote_submissions, local_submissions, mock_session, data_dir)

    updated_local_filename = '1-spotted-potato-msg'
    assert local_submission.filename == remote_submission.filename
    assert os.path.exists(os.path.join(data_dir, updated_local_filename))
Exemplo n.º 3
0
def test_update_files(homedir, mocker):
    """
    Check that:

    * Existing submissions are updated in the local database.
    * New submissions have an entry in the local database.
    * Local submission not returned by the remote server are deleted from the
      local database.
    """
    data_dir = os.path.join(homedir, "data")
    mock_session = mocker.MagicMock()
    # Source object related to the submissions.
    source = mocker.MagicMock()
    source.uuid = str(uuid.uuid4())
    # Some submission objects from the API, one of which will exist in the
    # local database, the other will NOT exist in the local source database
    # (this will be added to the database)
    remote_sub_update = make_remote_submission(source.uuid)
    remote_sub_create = make_remote_submission(source.uuid)
    remote_submissions = [remote_sub_update, remote_sub_create]
    # Some local submission objects. One already exists in the API results
    # (this will be updated), one does NOT exist in the API results (this will
    # be deleted from the local database).
    local_sub_update = mocker.MagicMock()
    local_sub_update.uuid = remote_sub_update.uuid
    local_sub_update.is_downloaded = True
    local_sub_update.is_decrypted = False
    local_filename = "originalsubmissionname.txt"
    local_sub_update.filename = local_filename
    local_sub_delete = mocker.MagicMock()
    local_sub_delete.uuid = str(uuid.uuid4())
    local_sub_delete.filename = "local_sub_delete.filename"
    local_submissions = [local_sub_update, local_sub_delete]
    # There needs to be a corresponding local_source.
    local_source = mocker.MagicMock()
    local_source.uuid = source.uuid
    local_source.id = 666  # };-)
    mock_session.query().filter_by().first.return_value = local_source
    mock_delete_submission_files = mocker.patch(
        "securedrop_client.storage.delete_single_submission_or_reply_on_disk")

    update_files(remote_submissions, local_submissions, mock_session, data_dir)

    # Check the expected local submission object has been updated with values
    # from the API.
    assert local_sub_update.filename == local_filename
    assert local_sub_update.size == remote_sub_update.size
    assert local_sub_update.is_read == remote_sub_update.is_read

    # Check the expected local source object has been created with values from
    # the API.
    assert mock_session.add.call_count == 1
    new_sub = mock_session.add.call_args_list[0][0][0]
    assert new_sub.uuid == remote_sub_create.uuid
    assert new_sub.source_id == local_source.id
    assert new_sub.filename == remote_sub_create.filename
    # Ensure the record for the local source that is missing from the results
    # of the API is deleted.
    mock_session.delete.assert_called_once_with(local_sub_delete)
    mock_delete_submission_files.assert_called_once_with(
        local_sub_delete, data_dir)
    # Session is committed to database.
    assert mock_session.commit.call_count == 1
Exemplo n.º 4
0
def test_update_files(homedir, mocker):
    """
    Check that:

    * Existing submissions are updated in the local database.
    * New submissions have an entry in the local database.
    * Local submission not returned by the remote server are deleted from the
      local database.
    * `rename_file` is called if local data files need to be updated with new
      filenames to match remote. Note: The only reason this should happen is if
      there is a new journalist_designation that causes remote filenames to be
      updated.
    """
    data_dir = os.path.join(homedir, 'data')
    mock_session = mocker.MagicMock()
    # Source object related to the submissions.
    source = mocker.MagicMock()
    source.uuid = str(uuid.uuid4())
    # Some submission objects from the API, one of which will exist in the
    # local database, the other will NOT exist in the local source database
    # (this will be added to the database)
    remote_sub_update = make_remote_submission(source.uuid)
    remote_sub_create = make_remote_submission(source.uuid)
    remote_submissions = [remote_sub_update, remote_sub_create]
    # Some local submission objects. One already exists in the API results
    # (this will be updated), one does NOT exist in the API results (this will
    # be deleted from the local database).
    local_sub_update = mocker.MagicMock()
    local_sub_update.uuid = remote_sub_update.uuid
    local_sub_update.filename = "overwrite_this.filename"
    local_sub_update.original_filename = "overwrite_this.filename.txt"
    local_sub_delete = mocker.MagicMock()
    local_sub_delete.uuid = str(uuid.uuid4())
    local_sub_delete.filename = "local_sub_delete.filename"
    local_sub_delete.original_filename = "local_sub_delete.filename.txt"
    local_submissions = [local_sub_update, local_sub_delete]
    # There needs to be a corresponding local_source.
    local_source = mocker.MagicMock()
    local_source.uuid = source.uuid
    local_source.id = 666  # };-)
    mock_session.query().filter_by.return_value = [
        local_source,
    ]
    patch_rename_file = mocker.patch('securedrop_client.storage.rename_file')

    update_files(remote_submissions, local_submissions, mock_session, data_dir)

    # Check the expected local submission object has been updated with values
    # from the API.
    assert local_sub_update.filename == remote_sub_update.filename
    assert local_sub_update.size == remote_sub_update.size
    assert local_sub_update.is_read == remote_sub_update.is_read
    # Check that rename_file is called if the local storage filenames need to
    # be updated
    assert patch_rename_file.called
    # Check the expected local source object has been created with values from
    # the API.
    assert mock_session.add.call_count == 1
    new_sub = mock_session.add.call_args_list[0][0][0]
    assert new_sub.uuid == remote_sub_create.uuid
    assert new_sub.source_id == local_source.id
    assert new_sub.filename == remote_sub_create.filename
    # Ensure the record for the local source that is missing from the results
    # of the API is deleted.
    mock_session.delete.assert_called_once_with(local_sub_delete)
    # Session is committed to database.
    assert mock_session.commit.call_count == 1