Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show pending status right after deletion job enqueued #955

Merged
merged 1 commit into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion securedrop_client/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ def on_delete_source_success(self, source_uuid: str) -> None:
"""
Rely on sync to delete the source locally so we know for sure it was deleted
"""
self.source_deleted.emit(source_uuid)
pass

def on_delete_source_failure(self, e: Exception) -> None:
if not isinstance(e, (RequestTimeoutError, ServerConnectionError)):
Copy link
Contributor

@redshiftzero redshiftzero Mar 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized that here in the source deletion failure callback we should really be setting the source widget back to its non-pending state (since the job won't get added back to the queue, and so is not pending), this can be another ticket since this is an issue on master. Since it's a rare/unexpected case I don't consider it a release blocker, but still, worth resolving.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, yes, if the deletion fails due to an error other than a timeout then we should set it back to non-pending. good find!

Expand All @@ -783,6 +783,7 @@ def delete_source(self, source: db.Source):
job.failure_signal.connect(self.on_delete_source_failure, type=Qt.QueuedConnection)

self.api_job_queue.enqueue(job)
self.source_deleted.emit(source.uuid)

@login_required
def send_reply(self, source_uuid: str, reply_uuid: str, message: str) -> None:
Expand Down
19 changes: 8 additions & 11 deletions tests/test_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,7 @@ def test_Controller_on_message_downloaded_checksum_failure(mocker, homedir, sess

def test_Controller_on_delete_source_success(mocker, homedir):
'''
Test that on a successful deletion request to the server that we emit a signal back to the gui.
Test that on a successful deletion does not delete the source locally (regression).
'''
co = Controller('http://localhost', mocker.MagicMock(), mocker.MagicMock(), homedir)
co.source_deleted = mocker.MagicMock()
Expand All @@ -1310,7 +1310,6 @@ def test_Controller_on_delete_source_success(mocker, homedir):
co.on_delete_source_success('uuid')

storage.delete_local_source_by_uuid.assert_not_called()
co.source_deleted.emit.assert_called_once_with('uuid')


def test_Controller_on_delete_source_failure(homedir, config, mocker, session_maker):
Expand Down Expand Up @@ -1347,30 +1346,28 @@ def test_Controller_delete_source(homedir, config, mocker, session_maker, sessio
co = Controller('http://localhost', mock_gui, session_maker, homedir)
co.call_api = mocker.MagicMock()
co.api = mocker.MagicMock()
co.source_deleted = mocker.MagicMock()

mock_success_signal = mocker.MagicMock()
mock_failure_signal = mocker.MagicMock()
mock_job = mocker.MagicMock(
success_signal=mock_success_signal, failure_signal=mock_failure_signal
)
mock_job_cls = mocker.patch(
"securedrop_client.logic.DeleteSourceJob", return_value=mock_job
)
success_signal=mock_success_signal, failure_signal=mock_failure_signal)
mock_job_cls = mocker.patch("securedrop_client.logic.DeleteSourceJob", return_value=mock_job)
mock_queue = mocker.patch.object(co, 'api_job_queue')

source = factory.Source()
session.add(source)
session.commit()

co.delete_source(source)

co.source_deleted.emit.assert_called_once_with(source.uuid)
mock_job_cls.assert_called_once_with(source.uuid)
mock_queue.enqueue.assert_called_once_with(mock_job)
mock_success_signal.connect.assert_called_once_with(
co.on_delete_source_success, type=Qt.QueuedConnection
)
co.on_delete_source_success, type=Qt.QueuedConnection)
mock_failure_signal.connect.assert_called_once_with(
co.on_delete_source_failure, type=Qt.QueuedConnection
)
co.on_delete_source_failure, type=Qt.QueuedConnection)


def test_Controller_send_reply_success(homedir, config, mocker, session_maker, session,
Expand Down