-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathtest_delete_sources.py
101 lines (81 loc) · 3.52 KB
/
test_delete_sources.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""
Functional tests for deleting one or more sources in the SecureDrop client.
The tests are based upon the client testing descriptions here:
https://github.com/freedomofpress/securedrop-client/wiki/Test-plan#basic-client-testing
"""
import random
import pytest
from flaky import flaky
from PyQt5.QtCore import Qt
from securedrop_client.gui.widgets import MultiSelectView, SourceConversationWrapper
from tests.conftest import (
TIME_CLICK_ACTION,
TIME_RENDER_CONV_VIEW,
TIME_RENDER_SOURCE_LIST,
TIME_SYNC,
)
@pytest.mark.parametrize("num_to_delete", [1, 3])
@flaky
def test_delete_sources(functional_test_logged_in_context, qtbot, mocker, num_to_delete):
"""
Check that sources selected for deletion are first confirmed and then
removed from the source list.
"""
gui, controller = functional_test_logged_in_context
# Wait for a full sync to give us a stable source list.
qtbot.wait(TIME_SYNC)
def check_for_sources():
"""Check that we have enough sources to work with."""
assert len(list(gui.main_view.source_list.source_items.keys())) >= num_to_delete
qtbot.waitUntil(check_for_sources, timeout=TIME_RENDER_SOURCE_LIST)
# Select num_to_delete sources at random.
source_uuids_to_delete = random.sample(
sorted(gui.main_view.source_list.source_items), num_to_delete
)
for i, source_uuid in enumerate(source_uuids_to_delete):
source_item = gui.main_view.source_list.source_items[source_uuid]
source_widget = gui.main_view.source_list.itemWidget(source_item)
# Simulate a non-<Ctrl> initial click...
if i == 0:
qtbot.mouseClick(source_widget, Qt.LeftButton)
# ...followed by subsequent <Ctrl>-clicks.
else:
qtbot.mouseClick(
source_widget, Qt.LeftButton, modifier=Qt.KeyboardModifier.ControlModifier
)
qtbot.wait(TIME_CLICK_ACTION)
def check_for_conversation():
"""
Check that the GUI is showing the right view for the number of
sources selected.
"""
if num_to_delete == 1:
index = gui.main_view.CONVERSATION_INDEX
widget = SourceConversationWrapper
else:
index = gui.main_view.MULTI_SELECTED_INDEX
widget = MultiSelectView
assert gui.main_view.view_layout.currentIndex() == index
assert isinstance(
gui.main_view.view_layout.widget(gui.main_view.view_layout.currentIndex()), widget
)
qtbot.waitUntil(check_for_conversation, timeout=TIME_RENDER_CONV_VIEW)
# Delete the selected source. We can't qtbot.mouseClick() on a QAction, but
# we can trigger it directly.
gui.main_view.top_pane.batch_actions.toolbar.delete_sources_action.trigger()
def check_and_accept_dialog():
"""Check that the dialog confirms deletion of all sources selected."""
dialog = (
gui.main_view.top_pane.batch_actions.toolbar._last_dialog
) # FIXME: workaround for #2273
assert set(source_uuids_to_delete) == {source.uuid for source in dialog.sources}
dialog.accept()
qtbot.waitUntil(check_and_accept_dialog, timeout=TIME_CLICK_ACTION)
def check_source_list():
"""
Check that all of the sources selected for deletion have been removed
from the source list.
"""
for source_uuid in source_uuids_to_delete:
assert source_uuid not in gui.main_view.source_list.source_items
qtbot.waitUntil(check_source_list, timeout=TIME_RENDER_SOURCE_LIST)