summaryrefslogtreecommitdiff
path: root/tests/SettingsGuiBaseTest.py
blob: 35bdd9c6e8ab25ca89b95c0eaed7caaf6ccf884b (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
import json
import os
import unittest
from PyQt5 import QtCore, QtTest

from onionshare import strings
from onionshare.common import Common
from onionshare.settings import Settings
from onionshare.onion import Onion
from onionshare_gui import Application, OnionShare
from onionshare_gui.settings_dialog import SettingsDialog


class OnionStub(object):
    def __init__(self, is_authenticated, supports_v3_onions):
        self._is_authenticated = is_authenticated
        self.supports_v3_onions = supports_v3_onions

    def is_authenticated(self):
        return self._is_authenticated


class SettingsGuiBaseTest(object):
    @staticmethod
    def set_up():
        '''Create the GUI'''

        # Default settings for the settings GUI tests
        test_settings = {
          "no_bridges": False,
          "tor_bridges_use_custom_bridges": "Bridge 1.2.3.4:56 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\nBridge 5.6.7.8:910 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\nBridge 11.12.13.14:1516 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n",
        }

        # Create our test file
        testfile = open('/tmp/test.txt', 'w')
        testfile.write('onionshare')
        testfile.close()

        common = Common()
        common.settings = Settings(common)
        common.define_css()
        strings.load_strings(common)

        # Start the Onion
        testonion = Onion(common)
        global qtapp
        qtapp = Application(common)
        app = OnionShare(common, testonion, True, 0)

        for key, val in common.settings.default_settings.items():
            if key not in test_settings:
                test_settings[key] = val

        open('/tmp/settings.json', 'w').write(json.dumps(test_settings))

        gui = SettingsDialog(common, testonion, qtapp, '/tmp/settings.json', True)
        return gui

    @staticmethod
    def tear_down():
        '''Clean up after tests'''
        os.remove('/tmp/settings.json')

    def run_settings_gui_tests(self):
        self.gui.show()

        # Window is shown
        self.assertTrue(self.gui.isVisible())
        self.assertEqual(self.gui.windowTitle(), strings._('gui_settings_window_title'))

        # Check for updates button is hidden
        self.assertFalse(self.gui.check_for_updates_button.isVisible())

        # public mode is off
        self.assertFalse(self.gui.public_mode_checkbox.isChecked())
        # enable public mode
        QtTest.QTest.mouseClick(self.gui.public_mode_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.public_mode_checkbox.height()/2))
        self.assertTrue(self.gui.public_mode_checkbox.isChecked())

        # autostop timer is off
        self.assertFalse(self.gui.autostop_timer_checkbox.isChecked())
        # enable autostop timer
        QtTest.QTest.mouseClick(self.gui.autostop_timer_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.autostop_timer_checkbox.height()/2))
        self.assertTrue(self.gui.autostop_timer_checkbox.isChecked())

        # legacy mode checkbox and related widgets
        if self.gui.onion.is_authenticated():
            if self.gui.onion.supports_v3_onions:
                # legacy mode is off
                self.assertFalse(self.gui.use_legacy_v2_onions_checkbox.isChecked())
                # persistence is still available, stealth is hidden and disabled
                self.assertTrue(self.gui.save_private_key_widget.isVisible())
                self.assertFalse(self.gui.save_private_key_checkbox.isChecked())
                self.assertFalse(self.gui.use_stealth_widget.isVisible())
                self.assertFalse(self.gui.stealth_checkbox.isChecked())
                self.assertFalse(self.gui.hidservauth_copy_button.isVisible())

                # enable legacy mode
                QtTest.QTest.mouseClick(self.gui.use_legacy_v2_onions_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.use_legacy_v2_onions_checkbox.height()/2))
                self.assertTrue(self.gui.use_legacy_v2_onions_checkbox.isChecked())
                self.assertTrue(self.gui.save_private_key_checkbox.isVisible())
                self.assertTrue(self.gui.use_stealth_widget.isVisible())

                # enable persistent mode
                QtTest.QTest.mouseClick(self.gui.save_private_key_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.save_private_key_checkbox.height()/2))
                self.assertTrue(self.gui.save_private_key_checkbox.isChecked())
                # enable stealth mode
                QtTest.QTest.mouseClick(self.gui.stealth_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.stealth_checkbox.height()/2))
                self.assertTrue(self.gui.stealth_checkbox.isChecked())
                # now that stealth is enabled, we can't turn off legacy mode
                self.assertFalse(self.gui.use_legacy_v2_onions_checkbox.isEnabled())
                # disable stealth, persistence
                QtTest.QTest.mouseClick(self.gui.save_private_key_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.save_private_key_checkbox.height()/2))
                QtTest.QTest.mouseClick(self.gui.stealth_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.stealth_checkbox.height()/2))
                # legacy mode checkbox is enabled again
                self.assertTrue(self.gui.use_legacy_v2_onions_checkbox.isEnabled())
                # uncheck legacy mode
                QtTest.QTest.mouseClick(self.gui.use_legacy_v2_onions_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.use_legacy_v2_onions_checkbox.height()/2))
                # legacy options hidden again
                self.assertTrue(self.gui.save_private_key_widget.isVisible())
                self.assertFalse(self.gui.use_stealth_widget.isVisible())

                # re-enable legacy mode
                QtTest.QTest.mouseClick(self.gui.use_legacy_v2_onions_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.use_legacy_v2_onions_checkbox.height()/2))

            else:
                # legacy mode setting is hidden
                self.assertFalse(self.gui.use_legacy_v2_onions_checkbox.isVisible())
                # legacy options are showing
                self.assertTrue(self.gui.save_private_key_widget.isVisible())
                self.assertTrue(self.gui.use_stealth_widget.isVisible())

            # enable them all again so that we can see the setting stick in settings.json
            QtTest.QTest.mouseClick(self.gui.save_private_key_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.save_private_key_checkbox.height()/2))
            QtTest.QTest.mouseClick(self.gui.stealth_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.stealth_checkbox.height()/2))
        else:
            # None of the onion settings should appear
            self.assertFalse(self.gui.use_legacy_v2_onions_checkbox.isVisible())
            self.assertFalse(self.gui.save_private_key_widget.isVisible())
            self.assertFalse(self.gui.save_private_key_checkbox.isChecked())
            self.assertFalse(self.gui.use_stealth_widget.isVisible())
            self.assertFalse(self.gui.stealth_checkbox.isChecked())
            self.assertFalse(self.gui.hidservauth_copy_button.isVisible())

        # stay open toggled off, on
        self.assertTrue(self.gui.close_after_first_download_checkbox.isChecked())
        QtTest.QTest.mouseClick(self.gui.close_after_first_download_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.close_after_first_download_checkbox.height()/2))
        self.assertFalse(self.gui.close_after_first_download_checkbox.isChecked())

        # receive mode
        self.gui.data_dir_lineedit.setText('/tmp/OnionShareSettingsTest')


        # bundled mode is enabled
        self.assertTrue(self.gui.connection_type_bundled_radio.isEnabled())
        self.assertTrue(self.gui.connection_type_bundled_radio.isChecked())
        # bridge options are shown
        self.assertTrue(self.gui.connection_type_bridges_radio_group.isVisible())
        # bridges are set to custom
        self.assertFalse(self.gui.tor_bridges_no_bridges_radio.isChecked())
        self.assertTrue(self.gui.tor_bridges_use_custom_radio.isChecked())

        # switch to obfs4
        QtTest.QTest.mouseClick(self.gui.tor_bridges_use_obfs4_radio, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.tor_bridges_use_obfs4_radio.height()/2))
        self.assertTrue(self.gui.tor_bridges_use_obfs4_radio.isChecked())

        # custom bridges are hidden
        self.assertFalse(self.gui.tor_bridges_use_custom_textbox_options.isVisible())
        # other modes are unchecked but enabled
        self.assertTrue(self.gui.connection_type_automatic_radio.isEnabled())
        self.assertTrue(self.gui.connection_type_control_port_radio.isEnabled())
        self.assertTrue(self.gui.connection_type_socket_file_radio.isEnabled())
        self.assertFalse(self.gui.connection_type_automatic_radio.isChecked())
        self.assertFalse(self.gui.connection_type_control_port_radio.isChecked())
        self.assertFalse(self.gui.connection_type_socket_file_radio.isChecked())

        # enable automatic mode
        QtTest.QTest.mouseClick(self.gui.connection_type_automatic_radio, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.connection_type_automatic_radio.height()/2))
        self.assertTrue(self.gui.connection_type_automatic_radio.isChecked())
        # bundled is off
        self.assertFalse(self.gui.connection_type_bundled_radio.isChecked())
        # bridges are hidden
        self.assertFalse(self.gui.connection_type_bridges_radio_group.isVisible())

        # auth type is hidden in bundled or automatic mode
        self.assertFalse(self.gui.authenticate_no_auth_radio.isVisible())
        self.assertFalse(self.gui.authenticate_password_radio.isVisible())

        # enable control port mode
        QtTest.QTest.mouseClick(self.gui.connection_type_control_port_radio, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.connection_type_control_port_radio.height()/2))
        self.assertTrue(self.gui.connection_type_control_port_radio.isChecked())
        # automatic is off
        self.assertFalse(self.gui.connection_type_automatic_radio.isChecked())
        # auth options appear
        self.assertTrue(self.gui.authenticate_no_auth_radio.isVisible())
        self.assertTrue(self.gui.authenticate_password_radio.isVisible())

        # enable socket mode
        QtTest.QTest.mouseClick(self.gui.connection_type_socket_file_radio, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.connection_type_socket_file_radio.height()/2))
        self.assertTrue(self.gui.connection_type_socket_file_radio.isChecked())
        # control port is off
        self.assertFalse(self.gui.connection_type_control_port_radio.isChecked())
        # auth options are still present
        self.assertTrue(self.gui.authenticate_no_auth_radio.isVisible())
        self.assertTrue(self.gui.authenticate_password_radio.isVisible())

        # re-enable bundled mode
        QtTest.QTest.mouseClick(self.gui.connection_type_bundled_radio, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.connection_type_bundled_radio.height()/2))
        # go back to custom bridges
        QtTest.QTest.mouseClick(self.gui.tor_bridges_use_custom_radio, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.tor_bridges_use_custom_radio.height()/2))
        self.assertTrue(self.gui.tor_bridges_use_custom_radio.isChecked())
        self.assertTrue(self.gui.tor_bridges_use_custom_textbox.isVisible())
        self.assertFalse(self.gui.tor_bridges_use_obfs4_radio.isChecked())
        self.gui.tor_bridges_use_custom_textbox.setPlainText('94.242.249.2:83 E25A95F1DADB739F0A83EB0223A37C02FD519306\n148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC\n93.80.47.217:41727 A6A0D497D98097FCFE91D639548EE9E34C15CDD3')

        # Test that the Settings Dialog can save the settings and close itself
        QtTest.QTest.mouseClick(self.gui.save_button, QtCore.Qt.LeftButton)
        self.assertFalse(self.gui.isVisible())

        # Test our settings are reflected in the settings json
        with open('/tmp/settings.json') as f:
            data = json.load(f)

        self.assertTrue(data["public_mode"])
        self.assertTrue(data["autostop_timer"])

        if self.gui.onion.is_authenticated():
            if self.gui.onion.supports_v3_onions:
                self.assertTrue(data["use_legacy_v2_onions"])
            self.assertTrue(data["save_private_key"])
            self.assertTrue(data["use_stealth"])
        else:
            self.assertFalse(data["use_legacy_v2_onions"])
            self.assertFalse(data["save_private_key"])
            self.assertFalse(data["use_stealth"])

        self.assertEqual(data["data_dir"], "/tmp/OnionShareSettingsTest")
        self.assertFalse(data["close_after_first_download"])
        self.assertEqual(data["connection_type"], "bundled")
        self.assertFalse(data["tor_bridges_use_obfs4"])
        self.assertEqual(data["tor_bridges_use_custom_bridges"], "Bridge 94.242.249.2:83 E25A95F1DADB739F0A83EB0223A37C02FD519306\nBridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC\nBridge 93.80.47.217:41727 A6A0D497D98097FCFE91D639548EE9E34C15CDD3\n")