summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMicah Lee <micah@micahflee.com>2019-11-10 13:55:15 -0800
committerMicah Lee <micah@micahflee.com>2019-11-10 13:55:15 -0800
commit16245d33e3b0c886d1201c0ef88a7c14b8d5b40e (patch)
treee5e11d60b1b04b9218a5743ebf7f448873517dee /tests
parent05df88bf89b4b697f6a371bc3bbc6ea3de929166 (diff)
downloadonionshare-16245d33e3b0c886d1201c0ef88a7c14b8d5b40e.tar.gz
onionshare-16245d33e3b0c886d1201c0ef88a7c14b8d5b40e.zip
Delete the old tests and replace them with the new tests
Diffstat (limited to 'tests')
-rw-r--r--tests/GuiBaseTest.py383
-rw-r--r--tests/GuiReceiveTest.py169
-rw-r--r--tests/GuiShareTest.py328
-rw-r--r--tests/GuiWebsiteTest.py136
-rw-r--r--tests/SettingsGuiBaseTest.py333
-rw-r--r--tests/TorGuiBaseTest.py176
-rw-r--r--tests/TorGuiReceiveTest.py61
-rw-r--r--tests/TorGuiShareTest.py91
-rw-r--r--tests/conftest.py45
-rw-r--r--tests/gui_base_test.py425
-rw-r--r--tests/local_onionshare_401_public_mode_skips_ratelimit_test.py27
-rw-r--r--tests/local_onionshare_401_triggers_ratelimit_test.py27
-rw-r--r--tests/local_onionshare_quitting_during_share_prompts_warning_test.py34
-rw-r--r--tests/local_onionshare_receive_mode_clear_all_button_test.py26
-rw-r--r--tests/local_onionshare_receive_mode_timer_test.py26
-rw-r--r--tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py26
-rw-r--r--tests/local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py26
-rw-r--r--tests/local_onionshare_receive_mode_upload_public_mode_test.py26
-rw-r--r--tests/local_onionshare_receive_mode_upload_test.py26
-rw-r--r--tests/local_onionshare_settings_dialog_legacy_tor_test.py27
-rw-r--r--tests/local_onionshare_settings_dialog_no_tor_test.py27
-rw-r--r--tests/local_onionshare_settings_dialog_v3_tor_test.py27
-rw-r--r--tests/local_onionshare_share_mode_autostart_and_autostop_timer_mismatch_test.py30
-rw-r--r--tests/local_onionshare_share_mode_autostart_timer_test.py26
-rw-r--r--tests/local_onionshare_share_mode_autostart_timer_too_short_test.py35
-rw-r--r--tests/local_onionshare_share_mode_cancel_share_test.py27
-rw-r--r--tests/local_onionshare_share_mode_clear_all_button_test.py26
-rw-r--r--tests/local_onionshare_share_mode_download_public_mode_test.py26
-rw-r--r--tests/local_onionshare_share_mode_download_stay_open_test.py26
-rw-r--r--tests/local_onionshare_share_mode_download_test.py26
-rw-r--r--tests/local_onionshare_share_mode_individual_file_view_stay_open_test.py26
-rw-r--r--tests/local_onionshare_share_mode_individual_file_view_test.py26
-rw-r--r--tests/local_onionshare_share_mode_large_download_test.py26
-rw-r--r--tests/local_onionshare_share_mode_password_persistent_test.py31
-rw-r--r--tests/local_onionshare_share_mode_timer_test.py26
-rw-r--r--tests/local_onionshare_share_mode_timer_too_short_test.py35
-rw-r--r--tests/local_onionshare_share_mode_unreadable_file_test.py26
-rw-r--r--tests/local_onionshare_website_mode_csp_enabled_test.py26
-rw-r--r--tests/local_onionshare_website_mode_test.py26
-rw-r--r--tests/onionshare_790_cancel_on_second_share_test.py30
-rw-r--r--tests/onionshare_receive_mode_upload_public_mode_test.py27
-rw-r--r--tests/onionshare_receive_mode_upload_test.py27
-rw-r--r--tests/onionshare_share_mode_cancel_share_test.py28
-rw-r--r--tests/onionshare_share_mode_download_public_mode_test.py27
-rw-r--r--tests/onionshare_share_mode_download_stay_open_test.py27
-rw-r--r--tests/onionshare_share_mode_download_test.py27
-rw-r--r--tests/onionshare_share_mode_persistent_test.py33
-rw-r--r--tests/onionshare_share_mode_stealth_test.py30
-rw-r--r--tests/onionshare_share_mode_timer_test.py27
-rw-r--r--tests/onionshare_share_mode_tor_connection_killed_test.py27
-rw-r--r--tests/onionshare_share_mode_v2_onion_test.py28
-rw-r--r--tests/test_cli.py (renamed from tests/test_onionshare.py)0
-rw-r--r--tests/test_cli_common.py (renamed from tests/test_onionshare_common.py)0
-rw-r--r--tests/test_cli_settings.py (renamed from tests/test_onionshare_settings.py)32
-rw-r--r--tests/test_cli_strings.py (renamed from tests/test_onionshare_strings.py)0
-rw-r--r--tests/test_cli_web.py (renamed from tests/test_onionshare_web.py)28
-rw-r--r--tests/test_gui_receive.py246
-rw-r--r--tests/test_gui_share.py585
-rw-r--r--tests/test_gui_tabs.py227
-rw-r--r--tests/test_gui_website.py106
-rw-r--r--tests/test_helpers.py38
61 files changed, 1647 insertions, 2895 deletions
diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py
deleted file mode 100644
index 068bb5c5..00000000
--- a/tests/GuiBaseTest.py
+++ /dev/null
@@ -1,383 +0,0 @@
-import json
-import os
-import requests
-import shutil
-import base64
-
-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.web import Web
-from onionshare_gui import Application, OnionShare, MainWindow
-from onionshare_gui.mode.share_mode import ShareMode
-from onionshare_gui.mode.receive_mode import ReceiveMode
-from onionshare_gui.mode.website_mode import WebsiteMode
-
-
-class GuiBaseTest(object):
- @staticmethod
- def set_up(test_settings):
- """Create GUI with given settings"""
- # Create our test file
- testfile = open("/tmp/test.txt", "w")
- testfile.write("onionshare")
- testfile.close()
-
- # Create a test dir and files
- if not os.path.exists("/tmp/testdir"):
- testdir = os.mkdir("/tmp/testdir")
- testfile = open("/tmp/testdir/test", "w")
- testfile.write("onionshare")
- testfile.close()
-
- common = Common()
- common.settings = Settings(common)
- common.define_css()
- strings.load_strings(common)
-
- # Get all of the settings in test_settings
- test_settings["data_dir"] = "/tmp/OnionShare"
- for key, val in common.settings.default_settings.items():
- if key not in test_settings:
- test_settings[key] = val
-
- # Start the Onion
- testonion = Onion(common)
- global qtapp
- qtapp = Application(common)
- app = OnionShare(common, testonion, True, 0)
-
- web = Web(common, False, True)
- open("/tmp/settings.json", "w").write(json.dumps(test_settings))
-
- gui = MainWindow(
- common,
- testonion,
- qtapp,
- app,
- ["/tmp/test.txt", "/tmp/testdir"],
- "/tmp/settings.json",
- True,
- )
- return gui
-
- @staticmethod
- def tear_down():
- """Clean up after tests"""
- try:
- os.remove("/tmp/test.txt")
- os.remove("/tmp/settings.json")
- os.remove("/tmp/large_file")
- os.remove("/tmp/download.zip")
- os.remove("/tmp/webpage")
- shutil.rmtree("/tmp/testdir")
- shutil.rmtree("/tmp/OnionShare")
- except:
- pass
-
- def gui_loaded(self):
- """Test that the GUI actually is shown"""
- self.assertTrue(self.gui.show)
-
- def windowTitle_seen(self):
- """Test that the window title is OnionShare"""
- self.assertEqual(self.gui.windowTitle(), "OnionShare")
-
- def settings_button_is_visible(self):
- """Test that the settings button is visible"""
- self.assertTrue(self.gui.settings_button.isVisible())
-
- def settings_button_is_hidden(self):
- """Test that the settings button is hidden when the server starts"""
- self.assertFalse(self.gui.settings_button.isVisible())
-
- def server_status_bar_is_visible(self):
- """Test that the status bar is visible"""
- self.assertTrue(self.gui.status_bar.isVisible())
-
- def click_mode(self, mode):
- """Test that we can switch Mode by clicking the button"""
- if type(mode) == ReceiveMode:
- QtTest.QTest.mouseClick(self.gui.receive_mode_button, QtCore.Qt.LeftButton)
- self.assertTrue(self.gui.mode, self.gui.MODE_RECEIVE)
- if type(mode) == ShareMode:
- QtTest.QTest.mouseClick(self.gui.share_mode_button, QtCore.Qt.LeftButton)
- self.assertTrue(self.gui.mode, self.gui.MODE_SHARE)
- if type(mode) == WebsiteMode:
- QtTest.QTest.mouseClick(self.gui.website_mode_button, QtCore.Qt.LeftButton)
- self.assertTrue(self.gui.mode, self.gui.MODE_WEBSITE)
-
- def click_toggle_history(self, mode):
- """Test that we can toggle Download or Upload history by clicking the toggle button"""
- currently_visible = mode.history.isVisible()
- QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton)
- self.assertEqual(mode.history.isVisible(), not currently_visible)
-
- def history_indicator(self, mode, public_mode, indicator_count="1"):
- """Test that we can make sure the history is toggled off, do an action, and the indiciator works"""
- # Make sure history is toggled off
- if mode.history.isVisible():
- QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton)
- self.assertFalse(mode.history.isVisible())
-
- # Indicator should not be visible yet
- self.assertFalse(mode.toggle_history.indicator_label.isVisible())
-
- if type(mode) == ReceiveMode:
- # Upload a file
- files = {"file[]": open("/tmp/test.txt", "rb")}
- url = f"http://127.0.0.1:{self.gui.app.port}/upload"
- if public_mode:
- r = requests.post(url, files=files)
- else:
- r = requests.post(
- url,
- files=files,
- auth=requests.auth.HTTPBasicAuth("onionshare", mode.web.password),
- )
- QtTest.QTest.qWait(2000)
-
- if type(mode) == ShareMode:
- # Download files
- url = f"http://127.0.0.1:{self.gui.app.port}/download"
- if public_mode:
- r = requests.get(url)
- else:
- r = requests.get(
- url,
- auth=requests.auth.HTTPBasicAuth("onionshare", mode.web.password),
- )
- QtTest.QTest.qWait(2000)
-
- # Indicator should be visible, have a value of "1"
- self.assertTrue(mode.toggle_history.indicator_label.isVisible())
- self.assertEqual(mode.toggle_history.indicator_label.text(), indicator_count)
-
- # Toggle history back on, indicator should be hidden again
- QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton)
- self.assertFalse(mode.toggle_history.indicator_label.isVisible())
-
- def history_is_not_visible(self, mode):
- """Test that the History section is not visible"""
- self.assertFalse(mode.history.isVisible())
-
- def history_is_visible(self, mode):
- """Test that the History section is visible"""
- self.assertTrue(mode.history.isVisible())
-
- def server_working_on_start_button_pressed(self, mode):
- """Test we can start the service"""
- # Should be in SERVER_WORKING state
- QtTest.QTest.mouseClick(mode.server_status.server_button, QtCore.Qt.LeftButton)
- self.assertEqual(mode.server_status.status, 1)
-
- def toggle_indicator_is_reset(self, mode):
- self.assertEqual(mode.toggle_history.indicator_count, 0)
- self.assertFalse(mode.toggle_history.indicator_label.isVisible())
-
- def server_status_indicator_says_starting(self, mode):
- """Test that the Server Status indicator shows we are Starting"""
- self.assertEqual(
- mode.server_status_label.text(),
- strings._("gui_status_indicator_share_working"),
- )
-
- def server_status_indicator_says_scheduled(self, mode):
- """Test that the Server Status indicator shows we are Scheduled"""
- self.assertEqual(
- mode.server_status_label.text(),
- strings._("gui_status_indicator_share_scheduled"),
- )
-
- def server_is_started(self, mode, startup_time=2000):
- """Test that the server has started"""
- QtTest.QTest.qWait(startup_time)
- # Should now be in SERVER_STARTED state
- self.assertEqual(mode.server_status.status, 2)
-
- def web_server_is_running(self):
- """Test that the web server has started"""
- try:
- r = requests.get(f"http://127.0.0.1:{self.gui.app.port}/")
- self.assertTrue(True)
- except requests.exceptions.ConnectionError:
- self.assertTrue(False)
-
- def have_a_password(self, mode, public_mode):
- """Test that we have a valid password"""
- if not public_mode:
- self.assertRegex(mode.server_status.web.password, r"(\w+)-(\w+)")
- else:
- self.assertIsNone(mode.server_status.web.password, r"(\w+)-(\w+)")
-
- def add_button_visible(self, mode):
- """Test that the add button should be visible"""
- self.assertTrue(mode.server_status.file_selection.add_button.isVisible())
-
- def url_description_shown(self, mode):
- """Test that the URL label is showing"""
- self.assertTrue(mode.server_status.url_description.isVisible())
-
- def have_copy_url_button(self, mode, public_mode):
- """Test that the Copy URL button is shown and that the clipboard is correct"""
- self.assertTrue(mode.server_status.copy_url_button.isVisible())
-
- QtTest.QTest.mouseClick(
- mode.server_status.copy_url_button, QtCore.Qt.LeftButton
- )
- clipboard = self.gui.qtapp.clipboard()
- if public_mode:
- self.assertEqual(clipboard.text(), f"http://127.0.0.1:{self.gui.app.port}")
- else:
- self.assertEqual(
- clipboard.text(),
- f"http://onionshare:{mode.server_status.web.password}@127.0.0.1:{self.gui.app.port}",
- )
-
- def server_status_indicator_says_started(self, mode):
- """Test that the Server Status indicator shows we are started"""
- if type(mode) == ReceiveMode:
- self.assertEqual(
- mode.server_status_label.text(),
- strings._("gui_status_indicator_receive_started"),
- )
- if type(mode) == ShareMode:
- self.assertEqual(
- mode.server_status_label.text(),
- strings._("gui_status_indicator_share_started"),
- )
-
- def web_page(self, mode, string, public_mode):
- """Test that the web page contains a string"""
-
- url = f"http://127.0.0.1:{self.gui.app.port}/"
- if public_mode:
- r = requests.get(url)
- else:
- r = requests.get(
- url, auth=requests.auth.HTTPBasicAuth("onionshare", mode.web.password)
- )
-
- self.assertTrue(string in r.text)
-
- def history_widgets_present(self, mode):
- """Test that the relevant widgets are present in the history view after activity has taken place"""
- self.assertFalse(mode.history.empty.isVisible())
- self.assertTrue(mode.history.not_empty.isVisible())
-
- def counter_incremented(self, mode, count):
- """Test that the counter has incremented"""
- self.assertEqual(mode.history.completed_count, count)
-
- def server_is_stopped(self, mode, stay_open):
- """Test that the server stops when we click Stop"""
- if (
- type(mode) == ReceiveMode
- or (type(mode) == ShareMode and stay_open)
- or (type(mode) == WebsiteMode)
- ):
- QtTest.QTest.mouseClick(
- mode.server_status.server_button, QtCore.Qt.LeftButton
- )
- self.assertEqual(mode.server_status.status, 0)
-
- def web_server_is_stopped(self):
- """Test that the web server also stopped"""
- QtTest.QTest.qWait(2000)
-
- try:
- r = requests.get(f"http://127.0.0.1:{self.gui.app.port}/")
- self.assertTrue(False)
- except requests.exceptions.ConnectionError:
- self.assertTrue(True)
-
- def server_status_indicator_says_closed(self, mode, stay_open):
- """Test that the Server Status indicator shows we closed"""
- if type(mode) == ReceiveMode:
- self.assertEqual(
- self.gui.receive_mode.server_status_label.text(),
- strings._("gui_status_indicator_receive_stopped"),
- )
- if type(mode) == ShareMode:
- if stay_open:
- self.assertEqual(
- self.gui.share_mode.server_status_label.text(),
- strings._("gui_status_indicator_share_stopped"),
- )
- else:
- self.assertEqual(
- self.gui.share_mode.server_status_label.text(),
- strings._("closing_automatically"),
- )
-
- def clear_all_history_items(self, mode, count):
- if count == 0:
- QtTest.QTest.mouseClick(mode.history.clear_button, QtCore.Qt.LeftButton)
- self.assertEquals(len(mode.history.item_list.items.keys()), count)
-
- # Auto-stop timer tests
- def set_timeout(self, mode, timeout):
- """Test that the timeout can be set"""
- timer = QtCore.QDateTime.currentDateTime().addSecs(timeout)
- mode.server_status.autostop_timer_widget.setDateTime(timer)
- self.assertTrue(mode.server_status.autostop_timer_widget.dateTime(), timer)
-
- def autostop_timer_widget_hidden(self, mode):
- """Test that the auto-stop timer widget is hidden when share has started"""
- self.assertFalse(mode.server_status.autostop_timer_container.isVisible())
-
- def server_timed_out(self, mode, wait):
- """Test that the server has timed out after the timer ran out"""
- QtTest.QTest.qWait(wait)
- # We should have timed out now
- self.assertEqual(mode.server_status.status, 0)
-
- # Auto-start timer tests
- def set_autostart_timer(self, mode, timer):
- """Test that the timer can be set"""
- schedule = QtCore.QDateTime.currentDateTime().addSecs(timer)
- mode.server_status.autostart_timer_widget.setDateTime(schedule)
- self.assertTrue(mode.server_status.autostart_timer_widget.dateTime(), schedule)
-
- def autostart_timer_widget_hidden(self, mode):
- """Test that the auto-start timer widget is hidden when share has started"""
- self.assertFalse(mode.server_status.autostart_timer_container.isVisible())
-
- def scheduled_service_started(self, mode, wait):
- """Test that the server has timed out after the timer ran out"""
- QtTest.QTest.qWait(wait)
- # We should have started now
- self.assertEqual(mode.server_status.status, 2)
-
- def cancel_the_share(self, mode):
- """Test that we can cancel a share before it's started up """
- self.server_working_on_start_button_pressed(mode)
- self.server_status_indicator_says_scheduled(mode)
- self.add_delete_buttons_hidden()
- self.settings_button_is_hidden()
- self.set_autostart_timer(mode, 10)
- QtTest.QTest.mousePress(mode.server_status.server_button, QtCore.Qt.LeftButton)
- QtTest.QTest.qWait(2000)
- QtTest.QTest.mouseRelease(
- mode.server_status.server_button, QtCore.Qt.LeftButton
- )
- self.assertEqual(mode.server_status.status, 0)
- self.server_is_stopped(mode, False)
- self.web_server_is_stopped()
-
- # Hack to close an Alert dialog that would otherwise block tests
- def accept_dialog(self):
- window = self.gui.qtapp.activeWindow()
- if window:
- window.close()
-
- # 'Grouped' tests follow from here
-
- def run_all_common_setup_tests(self):
- self.gui_loaded()
- self.windowTitle_seen()
- self.settings_button_is_visible()
- self.server_status_bar_is_visible()
diff --git a/tests/GuiReceiveTest.py b/tests/GuiReceiveTest.py
deleted file mode 100644
index 380702fd..00000000
--- a/tests/GuiReceiveTest.py
+++ /dev/null
@@ -1,169 +0,0 @@
-import os
-import requests
-from datetime import datetime, timedelta
-from PyQt5 import QtCore, QtTest
-from .GuiBaseTest import GuiBaseTest
-
-
-class GuiReceiveTest(GuiBaseTest):
- def upload_file(
- self,
- public_mode,
- file_to_upload,
- expected_basename,
- identical_files_at_once=False,
- ):
- """Test that we can upload the file"""
-
- # Wait 2 seconds to make sure the filename, based on timestamp, isn't accidentally reused
- QtTest.QTest.qWait(2000)
-
- files = {"file[]": open(file_to_upload, "rb")}
- url = f"http://127.0.0.1:{self.gui.app.port}/upload"
- if public_mode:
- r = requests.post(url, files=files)
- if identical_files_at_once:
- # Send a duplicate upload to test for collisions
- r = requests.post(url, files=files)
- else:
- r = requests.post(
- url,
- files=files,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.receive_mode.web.password
- ),
- )
- if identical_files_at_once:
- # Send a duplicate upload to test for collisions
- r = requests.post(
- url,
- files=files,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.receive_mode.web.password
- ),
- )
-
- QtTest.QTest.qWait(2000)
-
- # Make sure the file is within the last 10 seconds worth of fileames
- exists = False
- now = datetime.now()
- for i in range(10):
- date_dir = now.strftime("%Y-%m-%d")
- if identical_files_at_once:
- time_dir = now.strftime("%H.%M.%S-1")
- else:
- time_dir = now.strftime("%H.%M.%S")
- receive_mode_dir = os.path.join(
- self.gui.common.settings.get("data_dir"), date_dir, time_dir
- )
- expected_filename = os.path.join(receive_mode_dir, expected_basename)
- if os.path.exists(expected_filename):
- exists = True
- break
- now = now - timedelta(seconds=1)
-
- self.assertTrue(exists)
-
- def upload_file_should_fail(self, public_mode):
- """Test that we can't upload the file when permissions are wrong, and expected content is shown"""
- files = {"file[]": open("/tmp/test.txt", "rb")}
- url = f"http://127.0.0.1:{self.gui.app.port}/upload"
- if public_mode:
- r = requests.post(url, files=files)
- else:
- r = requests.post(
- url,
- files=files,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.receive_mode.web.password
- ),
- )
-
- QtCore.QTimer.singleShot(1000, self.accept_dialog)
- self.assertTrue("Error uploading, please inform the OnionShare user" in r.text)
-
- def upload_dir_permissions(self, mode=0o755):
- """Manipulate the permissions on the upload dir in between tests"""
- os.chmod("/tmp/OnionShare", mode)
-
- def try_without_auth_in_non_public_mode(self):
- r = requests.post(f"http://127.0.0.1:{self.gui.app.port}/upload")
- self.assertEqual(r.status_code, 401)
- r = requests.get(f"http://127.0.0.1:{self.gui.app.port}/close")
- self.assertEqual(r.status_code, 401)
-
- # 'Grouped' tests follow from here
-
- def run_all_receive_mode_setup_tests(self, public_mode):
- """Set up a share in Receive mode and start it"""
- self.click_mode(self.gui.receive_mode)
- self.history_is_not_visible(self.gui.receive_mode)
- self.click_toggle_history(self.gui.receive_mode)
- self.history_is_visible(self.gui.receive_mode)
- self.server_working_on_start_button_pressed(self.gui.receive_mode)
- self.server_status_indicator_says_starting(self.gui.receive_mode)
- self.settings_button_is_hidden()
- self.server_is_started(self.gui.receive_mode)
- self.web_server_is_running()
- self.have_a_password(self.gui.receive_mode, public_mode)
- self.url_description_shown(self.gui.receive_mode)
- self.have_copy_url_button(self.gui.receive_mode, public_mode)
- self.server_status_indicator_says_started(self.gui.receive_mode)
- self.web_page(
- self.gui.receive_mode,
- "Select the files you want to send, then click",
- public_mode,
- )
-
- def run_all_receive_mode_tests(self, public_mode):
- """Upload files in receive mode and stop the share"""
- self.run_all_receive_mode_setup_tests(public_mode)
- if not public_mode:
- self.try_without_auth_in_non_public_mode()
- self.upload_file(public_mode, "/tmp/test.txt", "test.txt")
- self.history_widgets_present(self.gui.receive_mode)
- self.counter_incremented(self.gui.receive_mode, 1)
- self.upload_file(public_mode, "/tmp/test.txt", "test.txt")
- self.counter_incremented(self.gui.receive_mode, 2)
- self.upload_file(public_mode, "/tmp/testdir/test", "test")
- self.counter_incremented(self.gui.receive_mode, 3)
- self.upload_file(public_mode, "/tmp/testdir/test", "test")
- self.counter_incremented(self.gui.receive_mode, 4)
- # Test uploading the same file twice at the same time, and make sure no collisions
- self.upload_file(public_mode, "/tmp/test.txt", "test.txt", True)
- self.counter_incremented(self.gui.receive_mode, 6)
- self.history_indicator(self.gui.receive_mode, public_mode, "2")
- self.server_is_stopped(self.gui.receive_mode, False)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.receive_mode, False)
- self.server_working_on_start_button_pressed(self.gui.receive_mode)
- self.server_is_started(self.gui.receive_mode)
- self.history_indicator(self.gui.receive_mode, public_mode, "2")
-
- def run_all_receive_mode_unwritable_dir_tests(self, public_mode):
- """Attempt to upload (unwritable) files in receive mode and stop the share"""
- self.run_all_receive_mode_setup_tests(public_mode)
- self.upload_dir_permissions(0o400)
- self.upload_file_should_fail(public_mode)
- self.server_is_stopped(self.gui.receive_mode, True)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.receive_mode, False)
- self.upload_dir_permissions(0o755)
-
- def run_all_receive_mode_timer_tests(self, public_mode):
- """Auto-stop timer tests in receive mode"""
- self.run_all_receive_mode_setup_tests(public_mode)
- self.set_timeout(self.gui.receive_mode, 5)
- self.autostop_timer_widget_hidden(self.gui.receive_mode)
- self.server_timed_out(self.gui.receive_mode, 15000)
- self.web_server_is_stopped()
-
- def run_all_clear_all_button_tests(self, public_mode):
- """Test the Clear All history button"""
- self.run_all_receive_mode_setup_tests(public_mode)
- self.upload_file(public_mode, "/tmp/test.txt", "test.txt")
- self.history_widgets_present(self.gui.receive_mode)
- self.clear_all_history_items(self.gui.receive_mode, 0)
- self.upload_file(public_mode, "/tmp/test.txt", "test.txt")
- self.clear_all_history_items(self.gui.receive_mode, 2)
diff --git a/tests/GuiShareTest.py b/tests/GuiShareTest.py
deleted file mode 100644
index 4a30dad5..00000000
--- a/tests/GuiShareTest.py
+++ /dev/null
@@ -1,328 +0,0 @@
-import os
-import requests
-import socks
-import zipfile
-import tempfile
-from PyQt5 import QtCore, QtTest
-from .GuiBaseTest import GuiBaseTest
-
-
-class GuiShareTest(GuiBaseTest):
- # Persistence tests
- def have_same_password(self, password):
- """Test that we have the same password"""
- self.assertEqual(self.gui.share_mode.server_status.web.password, password)
-
- # Share-specific tests
-
- def file_selection_widget_has_files(self, num=2):
- """Test that the number of items in the list is as expected"""
- self.assertEqual(
- self.gui.share_mode.server_status.file_selection.get_num_files(), num
- )
-
- def deleting_all_files_hides_delete_button(self):
- """Test that clicking on the file item shows the delete button. Test that deleting the only item in the list hides the delete button"""
- rect = self.gui.share_mode.server_status.file_selection.file_list.visualItemRect(
- self.gui.share_mode.server_status.file_selection.file_list.item(0)
- )
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.file_selection.file_list.viewport(),
- QtCore.Qt.LeftButton,
- pos=rect.center(),
- )
- # Delete button should be visible
- self.assertTrue(
- self.gui.share_mode.server_status.file_selection.delete_button.isVisible()
- )
- # Click delete, delete button should still be visible since we have one more file
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.file_selection.delete_button,
- QtCore.Qt.LeftButton,
- )
-
- rect = self.gui.share_mode.server_status.file_selection.file_list.visualItemRect(
- self.gui.share_mode.server_status.file_selection.file_list.item(0)
- )
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.file_selection.file_list.viewport(),
- QtCore.Qt.LeftButton,
- pos=rect.center(),
- )
- self.assertTrue(
- self.gui.share_mode.server_status.file_selection.delete_button.isVisible()
- )
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.file_selection.delete_button,
- QtCore.Qt.LeftButton,
- )
-
- # No more files, the delete button should be hidden
- self.assertFalse(
- self.gui.share_mode.server_status.file_selection.delete_button.isVisible()
- )
-
- def add_a_file_and_delete_using_its_delete_widget(self):
- """Test that we can also delete a file by clicking on its [X] widget"""
- self.gui.share_mode.server_status.file_selection.file_list.add_file(
- "/etc/hosts"
- )
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.file_selection.file_list.item(
- 0
- ).item_button,
- QtCore.Qt.LeftButton,
- )
- self.file_selection_widget_has_files(0)
-
- def file_selection_widget_read_files(self):
- """Re-add some files to the list so we can share"""
- self.gui.share_mode.server_status.file_selection.file_list.add_file(
- "/etc/hosts"
- )
- self.gui.share_mode.server_status.file_selection.file_list.add_file(
- "/tmp/test.txt"
- )
- self.file_selection_widget_has_files(2)
-
- def add_large_file(self):
- """Add a large file to the share"""
- size = 1024 * 1024 * 155
- with open("/tmp/large_file", "wb") as fout:
- fout.write(os.urandom(size))
- self.gui.share_mode.server_status.file_selection.file_list.add_file(
- "/tmp/large_file"
- )
-
- def add_delete_buttons_hidden(self):
- """Test that the add and delete buttons are hidden when the server starts"""
- self.assertFalse(
- self.gui.share_mode.server_status.file_selection.add_button.isVisible()
- )
- self.assertFalse(
- self.gui.share_mode.server_status.file_selection.delete_button.isVisible()
- )
-
- def download_share(self, public_mode):
- """Test that we can download the share"""
- url = f"http://127.0.0.1:{self.gui.app.port}/download"
- if public_mode:
- r = requests.get(url)
- else:
- r = requests.get(
- url,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.share_mode.server_status.web.password
- ),
- )
-
- tmp_file = tempfile.NamedTemporaryFile()
- with open(tmp_file.name, "wb") as f:
- f.write(r.content)
-
- zip = zipfile.ZipFile(tmp_file.name)
- QtTest.QTest.qWait(2000)
- self.assertEqual("onionshare", zip.read("test.txt").decode("utf-8"))
-
- def individual_file_is_viewable_or_not(self, public_mode, stay_open):
- """Test whether an individual file is viewable (when in stay_open mode) and that it isn't (when not in stay_open mode)"""
- url = f"http://127.0.0.1:{self.gui.app.port}"
- download_file_url = f"http://127.0.0.1:{self.gui.app.port}/test.txt"
- if public_mode:
- r = requests.get(url)
- else:
- r = requests.get(
- url,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.share_mode.server_status.web.password
- ),
- )
-
- if stay_open:
- self.assertTrue('a href="test.txt"' in r.text)
-
- if public_mode:
- r = requests.get(download_file_url)
- else:
- r = requests.get(
- download_file_url,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.share_mode.server_status.web.password
- ),
- )
-
- tmp_file = tempfile.NamedTemporaryFile()
- with open(tmp_file.name, "wb") as f:
- f.write(r.content)
-
- with open(tmp_file.name, "r") as f:
- self.assertEqual("onionshare", f.read())
- else:
- self.assertFalse('a href="/test.txt"' in r.text)
- if public_mode:
- r = requests.get(download_file_url)
- else:
- r = requests.get(
- download_file_url,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.share_mode.server_status.web.password
- ),
- )
- self.assertEqual(r.status_code, 404)
- self.download_share(public_mode)
-
- QtTest.QTest.qWait(2000)
-
- def hit_401(self, public_mode):
- """Test that the server stops after too many 401s, or doesn't when in public_mode"""
- url = f"http://127.0.0.1:{self.gui.app.port}/"
-
- for _ in range(20):
- password_guess = self.gui.common.build_password()
- r = requests.get(
- url, auth=requests.auth.HTTPBasicAuth("onionshare", password_guess)
- )
-
- # A nasty hack to avoid the Alert dialog that blocks the rest of the test
- if not public_mode:
- QtCore.QTimer.singleShot(1000, self.accept_dialog)
-
- # In public mode, we should still be running (no rate-limiting)
- if public_mode:
- self.web_server_is_running()
- # In non-public mode, we should be shut down (rate-limiting)
- else:
- self.web_server_is_stopped()
-
- # 'Grouped' tests follow from here
-
- def run_all_share_mode_setup_tests(self):
- """Tests in share mode prior to starting a share"""
- self.click_mode(self.gui.share_mode)
- self.file_selection_widget_has_files()
- self.history_is_not_visible(self.gui.share_mode)
- self.click_toggle_history(self.gui.share_mode)
- self.history_is_visible(self.gui.share_mode)
- self.deleting_all_files_hides_delete_button()
- self.add_a_file_and_delete_using_its_delete_widget()
- self.file_selection_widget_read_files()
-
- def run_all_share_mode_started_tests(self, public_mode, startup_time=2000):
- """Tests in share mode after starting a share"""
- self.server_working_on_start_button_pressed(self.gui.share_mode)
- self.server_status_indicator_says_starting(self.gui.share_mode)
- self.add_delete_buttons_hidden()
- self.settings_button_is_hidden()
- self.server_is_started(self.gui.share_mode, startup_time)
- self.web_server_is_running()
- self.have_a_password(self.gui.share_mode, public_mode)
- self.url_description_shown(self.gui.share_mode)
- self.have_copy_url_button(self.gui.share_mode, public_mode)
- self.server_status_indicator_says_started(self.gui.share_mode)
-
- def run_all_share_mode_download_tests(self, public_mode, stay_open):
- """Tests in share mode after downloading a share"""
- self.web_page(self.gui.share_mode, "Total size", public_mode)
- self.download_share(public_mode)
- self.history_widgets_present(self.gui.share_mode)
- self.server_is_stopped(self.gui.share_mode, stay_open)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.share_mode, stay_open)
- self.add_button_visible(self.gui.share_mode)
- self.server_working_on_start_button_pressed(self.gui.share_mode)
- self.toggle_indicator_is_reset(self.gui.share_mode)
- self.server_is_started(self.gui.share_mode)
- self.history_indicator(self.gui.share_mode, public_mode)
-
- def run_all_share_mode_individual_file_download_tests(self, public_mode, stay_open):
- """Tests in share mode after downloading a share"""
- self.web_page(self.gui.share_mode, "Total size", public_mode)
- self.individual_file_is_viewable_or_not(public_mode, stay_open)
- self.history_widgets_present(self.gui.share_mode)
- self.server_is_stopped(self.gui.share_mode, stay_open)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.share_mode, stay_open)
- self.add_button_visible(self.gui.share_mode)
- self.server_working_on_start_button_pressed(self.gui.share_mode)
- self.server_is_started(self.gui.share_mode)
- self.history_indicator(self.gui.share_mode, public_mode)
-
- def run_all_share_mode_tests(self, public_mode, stay_open):
- """End-to-end share tests"""
- self.run_all_share_mode_setup_tests()
- self.run_all_share_mode_started_tests(public_mode)
- self.run_all_share_mode_download_tests(public_mode, stay_open)
-
- def run_all_clear_all_button_tests(self, public_mode, stay_open):
- """Test the Clear All history button"""
- self.run_all_share_mode_setup_tests()
- self.run_all_share_mode_started_tests(public_mode)
- self.individual_file_is_viewable_or_not(public_mode, stay_open)
- self.history_widgets_present(self.gui.share_mode)
- self.clear_all_history_items(self.gui.share_mode, 0)
- self.individual_file_is_viewable_or_not(public_mode, stay_open)
- self.clear_all_history_items(self.gui.share_mode, 2)
-
- def run_all_share_mode_individual_file_tests(self, public_mode, stay_open):
- """Tests in share mode when viewing an individual file"""
- self.run_all_share_mode_setup_tests()
- self.run_all_share_mode_started_tests(public_mode)
- self.run_all_share_mode_individual_file_download_tests(public_mode, stay_open)
-
- def run_all_large_file_tests(self, public_mode, stay_open):
- """Same as above but with a larger file"""
- self.run_all_share_mode_setup_tests()
- self.add_large_file()
- self.run_all_share_mode_started_tests(public_mode, startup_time=15000)
- self.assertTrue(self.gui.share_mode.filesize_warning.isVisible())
- self.server_is_stopped(self.gui.share_mode, stay_open)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.share_mode, stay_open)
-
- def run_all_share_mode_persistent_tests(self, public_mode, stay_open):
- """Same as end-to-end share tests but also test the password is the same on multiple shared"""
- self.run_all_share_mode_setup_tests()
- self.run_all_share_mode_started_tests(public_mode)
- password = self.gui.share_mode.server_status.web.password
- self.run_all_share_mode_download_tests(public_mode, stay_open)
- self.have_same_password(password)
-
- def run_all_share_mode_timer_tests(self, public_mode):
- """Auto-stop timer tests in share mode"""
- self.run_all_share_mode_setup_tests()
- self.set_timeout(self.gui.share_mode, 5)
- self.run_all_share_mode_started_tests(public_mode)
- self.autostop_timer_widget_hidden(self.gui.share_mode)
- self.server_timed_out(self.gui.share_mode, 10000)
- self.web_server_is_stopped()
-
- def run_all_share_mode_autostart_timer_tests(self, public_mode):
- """Auto-start timer tests in share mode"""
- self.run_all_share_mode_setup_tests()
- self.set_autostart_timer(self.gui.share_mode, 5)
- self.server_working_on_start_button_pressed(self.gui.share_mode)
- self.autostart_timer_widget_hidden(self.gui.share_mode)
- self.server_status_indicator_says_scheduled(self.gui.share_mode)
- self.web_server_is_stopped()
- self.scheduled_service_started(self.gui.share_mode, 7000)
- self.web_server_is_running()
-
- def run_all_share_mode_autostop_autostart_mismatch_tests(self, public_mode):
- """Auto-stop timer tests in share mode"""
- self.run_all_share_mode_setup_tests()
- self.set_autostart_timer(self.gui.share_mode, 15)
- self.set_timeout(self.gui.share_mode, 5)
- QtCore.QTimer.singleShot(4000, self.accept_dialog)
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton
- )
- self.server_is_stopped(self.gui.share_mode, False)
-
- def run_all_share_mode_unreadable_file_tests(self):
- """Attempt to share an unreadable file"""
- self.run_all_share_mode_setup_tests()
- QtCore.QTimer.singleShot(1000, self.accept_dialog)
- self.gui.share_mode.server_status.file_selection.file_list.add_file(
- "/tmp/nonexistent.txt"
- )
- self.file_selection_widget_has_files(2)
diff --git a/tests/GuiWebsiteTest.py b/tests/GuiWebsiteTest.py
deleted file mode 100644
index 8c733442..00000000
--- a/tests/GuiWebsiteTest.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import json
-import os
-import requests
-import socks
-import zipfile
-import tempfile
-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.web import Web
-from onionshare_gui import Application, OnionShare, MainWindow
-from .GuiShareTest import GuiShareTest
-
-
-class GuiWebsiteTest(GuiShareTest):
- @staticmethod
- def set_up(test_settings):
- """Create GUI with given settings"""
- # Create our test file
- testfile = open("/tmp/index.html", "w")
- testfile.write(
- "<html><body><p>This is a test website hosted by OnionShare</p></body></html>"
- )
- testfile.close()
-
- common = Common()
- common.settings = Settings(common)
- common.define_css()
- strings.load_strings(common)
-
- # Get all of the settings in test_settings
- test_settings["data_dir"] = "/tmp/OnionShare"
- for key, val in common.settings.default_settings.items():
- if key not in test_settings:
- test_settings[key] = val
-
- # Start the Onion
- testonion = Onion(common)
- global qtapp
- qtapp = Application(common)
- app = OnionShare(common, testonion, True, 0)
-
- web = Web(common, False, True)
- open("/tmp/settings.json", "w").write(json.dumps(test_settings))
-
- gui = MainWindow(
- common,
- testonion,
- qtapp,
- app,
- ["/tmp/index.html"],
- "/tmp/settings.json",
- True,
- )
- return gui
-
- @staticmethod
- def tear_down():
- """Clean up after tests"""
- try:
- os.remove("/tmp/index.html")
- os.remove("/tmp/settings.json")
- except:
- pass
-
- def view_website(self, public_mode):
- """Test that we can download the share"""
- url = f"http://127.0.0.1:{self.gui.app.port}/"
- if public_mode:
- r = requests.get(url)
- else:
- r = requests.get(
- url,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.website_mode.server_status.web.password
- ),
- )
-
- QtTest.QTest.qWait(2000)
- self.assertTrue("This is a test website hosted by OnionShare" in r.text)
-
- def check_csp_header(self, public_mode, csp_header_disabled):
- """Test that the CSP header is present when enabled or vice versa"""
- url = f"http://127.0.0.1:{self.gui.app.port}/"
- if public_mode:
- r = requests.get(url)
- else:
- r = requests.get(
- url,
- auth=requests.auth.HTTPBasicAuth(
- "onionshare", self.gui.website_mode.server_status.web.password
- ),
- )
-
- QtTest.QTest.qWait(2000)
- if csp_header_disabled:
- self.assertFalse("Content-Security-Policy" in r.headers)
- else:
- self.assertTrue("Content-Security-Policy" in r.headers)
-
- def run_all_website_mode_setup_tests(self):
- """Tests in website mode prior to starting a share"""
- self.click_mode(self.gui.website_mode)
- self.file_selection_widget_has_files(1)
- self.history_is_not_visible(self.gui.website_mode)
- self.click_toggle_history(self.gui.website_mode)
- self.history_is_visible(self.gui.website_mode)
-
- def run_all_website_mode_started_tests(self, public_mode, startup_time=2000):
- """Tests in website mode after starting a share"""
- self.server_working_on_start_button_pressed(self.gui.website_mode)
- self.server_status_indicator_says_starting(self.gui.website_mode)
- self.add_delete_buttons_hidden()
- self.settings_button_is_hidden()
- self.server_is_started(self.gui.website_mode, startup_time)
- self.web_server_is_running()
- self.have_a_password(self.gui.website_mode, public_mode)
- self.url_description_shown(self.gui.website_mode)
- self.have_copy_url_button(self.gui.website_mode, public_mode)
- self.server_status_indicator_says_started(self.gui.website_mode)
-
- def run_all_website_mode_download_tests(self, public_mode):
- """Tests in website mode after viewing the site"""
- self.run_all_website_mode_setup_tests()
- self.run_all_website_mode_started_tests(public_mode, startup_time=2000)
- self.view_website(public_mode)
- self.check_csp_header(
- public_mode, self.gui.common.settings.get("csp_header_disabled")
- )
- self.history_widgets_present(self.gui.website_mode)
- self.server_is_stopped(self.gui.website_mode, False)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.website_mode, False)
- self.add_button_visible(self.gui.website_mode)
diff --git a/tests/SettingsGuiBaseTest.py b/tests/SettingsGuiBaseTest.py
deleted file mode 100644
index 1aa6da25..00000000
--- a/tests/SettingsGuiBaseTest.py
+++ /dev/null
@@ -1,333 +0,0 @@
-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",
- )
diff --git a/tests/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py
deleted file mode 100644
index ab5ed508..00000000
--- a/tests/TorGuiBaseTest.py
+++ /dev/null
@@ -1,176 +0,0 @@
-import json
-import os
-import requests
-import socks
-
-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.web import Web
-from onionshare_gui import Application, OnionShare, MainWindow
-from onionshare_gui.mode.share_mode import ShareMode
-from onionshare_gui.mode.receive_mode import ReceiveMode
-
-from .GuiBaseTest import GuiBaseTest
-
-
-class TorGuiBaseTest(GuiBaseTest):
- @staticmethod
- def set_up(test_settings):
- """Create GUI with given settings"""
- # Create our test file
- testfile = open("/tmp/test.txt", "w")
- testfile.write("onionshare")
- testfile.close()
-
- # Create a test dir and files
- if not os.path.exists("/tmp/testdir"):
- testdir = os.mkdir("/tmp/testdir")
- testfile = open("/tmp/testdir/test.txt", "w")
- testfile.write("onionshare")
- testfile.close()
-
- common = Common()
- common.settings = Settings(common)
- common.define_css()
- strings.load_strings(common)
-
- # Get all of the settings in test_settings
- test_settings["connection_type"] = "automatic"
- test_settings["data_dir"] = "/tmp/OnionShare"
- for key, val in common.settings.default_settings.items():
- if key not in test_settings:
- test_settings[key] = val
-
- # Start the Onion
- testonion = Onion(common)
- global qtapp
- qtapp = Application(common)
- app = OnionShare(common, testonion, False, 0)
-
- web = Web(common, False, False)
- open("/tmp/settings.json", "w").write(json.dumps(test_settings))
-
- gui = MainWindow(
- common,
- testonion,
- qtapp,
- app,
- ["/tmp/test.txt", "/tmp/testdir"],
- "/tmp/settings.json",
- False,
- )
- return gui
-
- def history_indicator(self, mode, public_mode):
- """Test that we can make sure the history is toggled off, do an action, and the indiciator works"""
- # Make sure history is toggled off
- if mode.history.isVisible():
- QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton)
- self.assertFalse(mode.history.isVisible())
-
- # Indicator should not be visible yet
- self.assertFalse(mode.toggle_history.indicator_label.isVisible())
-
- # Set up connecting to the onion
- (socks_address, socks_port) = self.gui.app.onion.get_tor_socks_port()
- session = requests.session()
- session.proxies = {}
- session.proxies["http"] = f"socks5h://{socks_address}:{socks_port}"
-
- if type(mode) == ReceiveMode:
- # Upload a file
- files = {"file[]": open("/tmp/test.txt", "rb")}
- if not public_mode:
- path = f"http://{self.gui.app.onion_host}/{mode.web.password}/upload"
- else:
- path = f"http://{self.gui.app.onion_host}/upload"
- response = session.post(path, files=files)
- QtTest.QTest.qWait(4000)
-
- if type(mode) == ShareMode:
- # Download files
- if public_mode:
- path = f"http://{self.gui.app.onion_host}/download"
- else:
- path = f"http://{self.gui.app.onion_host}/{mode.web.password}/download"
- response = session.get(path)
- QtTest.QTest.qWait(4000)
-
- # Indicator should be visible, have a value of "1"
- self.assertTrue(mode.toggle_history.indicator_label.isVisible())
- self.assertEqual(mode.toggle_history.indicator_label.text(), "1")
-
- # Toggle history back on, indicator should be hidden again
- QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton)
- self.assertFalse(mode.toggle_history.indicator_label.isVisible())
-
- def have_an_onion_service(self):
- """Test that we have a valid Onion URL"""
- self.assertRegex(self.gui.app.onion_host, r"[a-z2-7].onion")
-
- def web_page(self, mode, string, public_mode):
- """Test that the web page contains a string"""
- (socks_address, socks_port) = self.gui.app.onion.get_tor_socks_port()
- socks.set_default_proxy(socks.SOCKS5, socks_address, socks_port)
- s = socks.socksocket()
- s.settimeout(60)
- s.connect((self.gui.app.onion_host, 80))
- if not public_mode:
- path = f"/{mode.server_status.web.password}"
- else:
- path = "/"
- http_request = f"GET {path} HTTP/1.0\r\n"
- http_request += f"Host: {self.gui.app.onion_host}\r\n"
- http_request += "\r\n"
- s.sendall(http_request.encode("utf-8"))
- with open("/tmp/webpage", "wb") as file_to_write:
- while True:
- data = s.recv(1024)
- if not data:
- break
- file_to_write.write(data)
- file_to_write.close()
- f = open("/tmp/webpage")
- self.assertTrue(string in f.read())
- f.close()
-
- def have_copy_url_button(self, mode, public_mode):
- """Test that the Copy URL button is shown and that the clipboard is correct"""
- self.assertTrue(mode.server_status.copy_url_button.isVisible())
-
- QtTest.QTest.mouseClick(
- mode.server_status.copy_url_button, QtCore.Qt.LeftButton
- )
- clipboard = self.gui.qtapp.clipboard()
- if public_mode:
- self.assertEqual(clipboard.text(), f"http://{self.gui.app.onion_host}")
- else:
- self.assertEqual(
- clipboard.text(),
- f"http://{self.gui.app.onion_host}/{mode.server_status.web.password}",
- )
-
- # Stealth tests
- def copy_have_hidserv_auth_button(self, mode):
- """Test that the Copy HidservAuth button is shown"""
- self.assertTrue(mode.server_status.copy_hidservauth_button.isVisible())
-
- def hidserv_auth_string(self):
- """Test the validity of the HidservAuth string"""
- self.assertRegex(
- self.gui.app.auth_string,
- r"HidServAuth {} [a-zA-Z1-9]".format(self.gui.app.onion_host),
- )
-
- # Miscellaneous tests
- def tor_killed_statusbar_message_shown(self, mode):
- """Test that the status bar message shows Tor was disconnected"""
- self.gui.app.onion.c = None
- QtTest.QTest.qWait(1000)
- self.assertTrue(
- mode.status_bar.currentMessage(), strings._("gui_tor_connection_lost")
- )
diff --git a/tests/TorGuiReceiveTest.py b/tests/TorGuiReceiveTest.py
deleted file mode 100644
index a8944363..00000000
--- a/tests/TorGuiReceiveTest.py
+++ /dev/null
@@ -1,61 +0,0 @@
-import os
-import requests
-from PyQt5 import QtTest
-from .TorGuiBaseTest import TorGuiBaseTest
-
-
-class TorGuiReceiveTest(TorGuiBaseTest):
- def upload_file(self, public_mode, file_to_upload, expected_file):
- """Test that we can upload the file"""
- (socks_address, socks_port) = self.gui.app.onion.get_tor_socks_port()
- session = requests.session()
- session.proxies = {}
- session.proxies["http"] = f"socks5h://{socks_address}:{socks_port}"
- files = {"file[]": open(file_to_upload, "rb")}
- if not public_mode:
- path = f"http://{self.gui.app.onion_host}/{self.gui.receive_mode.web.password}/upload"
- else:
- path = f"http://{self.gui.app.onion_host}/upload"
- response = session.post(path, files=files)
- QtTest.QTest.qWait(4000)
- self.assertTrue(os.path.isfile(expected_file))
-
- # 'Grouped' tests follow from here
-
- def run_all_receive_mode_tests(self, public_mode, receive_allow_receiver_shutdown):
- """Run a full suite of tests in Receive mode"""
- self.click_mode(self.gui.receive_mode)
- self.history_is_not_visible(self.gui.receive_mode)
- self.click_toggle_history(self.gui.receive_mode)
- self.history_is_visible(self.gui.receive_mode)
- self.server_working_on_start_button_pressed(self.gui.receive_mode)
- self.server_status_indicator_says_starting(self.gui.receive_mode)
- self.settings_button_is_hidden()
- self.server_is_started(self.gui.receive_mode, startup_time=45000)
- self.web_server_is_running()
- self.have_an_onion_service()
- self.have_a_password(self.gui.receive_mode, public_mode)
- self.url_description_shown(self.gui.receive_mode)
- self.have_copy_url_button(self.gui.receive_mode, public_mode)
- self.server_status_indicator_says_started(self.gui.receive_mode)
- self.web_page(
- self.gui.receive_mode,
- "Select the files you want to send, then click",
- public_mode,
- )
- self.upload_file(public_mode, "/tmp/test.txt", "/tmp/OnionShare/test.txt")
- self.history_widgets_present(self.gui.receive_mode)
- self.counter_incremented(self.gui.receive_mode, 1)
- self.upload_file(public_mode, "/tmp/test.txt", "/tmp/OnionShare/test-2.txt")
- self.counter_incremented(self.gui.receive_mode, 2)
- self.upload_file(public_mode, "/tmp/testdir/test", "/tmp/OnionShare/test")
- self.counter_incremented(self.gui.receive_mode, 3)
- self.upload_file(public_mode, "/tmp/testdir/test", "/tmp/OnionShare/test-2")
- self.counter_incremented(self.gui.receive_mode, 4)
- self.history_indicator(self.gui.receive_mode, public_mode)
- self.server_is_stopped(self.gui.receive_mode, False)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.receive_mode, False)
- self.server_working_on_start_button_pressed(self.gui.receive_mode)
- self.server_is_started(self.gui.receive_mode, startup_time=45000)
- self.history_indicator(self.gui.receive_mode, public_mode)
diff --git a/tests/TorGuiShareTest.py b/tests/TorGuiShareTest.py
deleted file mode 100644
index 1c9c5b40..00000000
--- a/tests/TorGuiShareTest.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import requests
-import zipfile
-from PyQt5 import QtTest
-from .TorGuiBaseTest import TorGuiBaseTest
-from .GuiShareTest import GuiShareTest
-
-
-class TorGuiShareTest(TorGuiBaseTest, GuiShareTest):
- def download_share(self, public_mode):
- """Test downloading a share"""
- # Set up connecting to the onion
- (socks_address, socks_port) = self.gui.app.onion.get_tor_socks_port()
- session = requests.session()
- session.proxies = {}
- session.proxies["http"] = f"socks5h://{socks_address}:{socks_port}"
-
- # Download files
- if public_mode:
- path = f"http://{self.gui.app.onion_host}/download"
- else:
- path = f"http://{self.gui.app.onion_host}/{self.gui.share_mode.web.password}/download"
- response = session.get(path, stream=True)
- QtTest.QTest.qWait(4000)
-
- if response.status_code == 200:
- with open("/tmp/download.zip", "wb") as file_to_write:
- for chunk in response.iter_content(chunk_size=128):
- file_to_write.write(chunk)
- file_to_write.close()
- zip = zipfile.ZipFile("/tmp/download.zip")
- QtTest.QTest.qWait(4000)
- self.assertEqual("onionshare", zip.read("test.txt").decode("utf-8"))
-
- # Persistence tests
- def have_same_onion(self, onion):
- """Test that we have the same onion"""
- self.assertEqual(self.gui.app.onion_host, onion)
-
- # legacy v2 onion test
- def have_v2_onion(self):
- """Test that the onion is a v2 style onion"""
- self.assertRegex(self.gui.app.onion_host, r"[a-z2-7].onion")
- self.assertEqual(len(self.gui.app.onion_host), 22)
-
- # 'Grouped' tests follow from here
-
- def run_all_share_mode_started_tests(self, public_mode):
- """Tests in share mode after starting a share"""
- self.server_working_on_start_button_pressed(self.gui.share_mode)
- self.server_status_indicator_says_starting(self.gui.share_mode)
- self.add_delete_buttons_hidden()
- self.settings_button_is_hidden()
- self.server_is_started(self.gui.share_mode, startup_time=45000)
- self.web_server_is_running()
- self.have_an_onion_service()
- self.have_a_password(self.gui.share_mode, public_mode)
- self.url_description_shown(self.gui.share_mode)
- self.have_copy_url_button(self.gui.share_mode, public_mode)
- self.server_status_indicator_says_started(self.gui.share_mode)
-
- def run_all_share_mode_download_tests(self, public_mode, stay_open):
- """Tests in share mode after downloading a share"""
- self.web_page(self.gui.share_mode, "Total size", public_mode)
- self.download_share(public_mode)
- self.history_widgets_present(self.gui.share_mode)
- self.server_is_stopped(self.gui.share_mode, stay_open)
- self.web_server_is_stopped()
- self.server_status_indicator_says_closed(self.gui.share_mode, stay_open)
- self.add_button_visible(self.gui.share_mode)
- self.server_working_on_start_button_pressed(self.gui.share_mode)
- self.server_is_started(self.gui.share_mode, startup_time=45000)
- self.history_indicator(self.gui.share_mode, public_mode)
-
- def run_all_share_mode_persistent_tests(self, public_mode, stay_open):
- """Same as end-to-end share tests but also test the password is the same on multiple shared"""
- self.run_all_share_mode_setup_tests()
- self.run_all_share_mode_started_tests(public_mode)
- password = self.gui.share_mode.server_status.web.password
- onion = self.gui.app.onion_host
- self.run_all_share_mode_download_tests(public_mode, stay_open)
- self.have_same_onion(onion)
- self.have_same_password(password)
-
- def run_all_share_mode_timer_tests(self, public_mode):
- """Auto-stop timer tests in share mode"""
- self.run_all_share_mode_setup_tests()
- self.set_timeout(self.gui.share_mode, 120)
- self.run_all_share_mode_started_tests(public_mode)
- self.autostop_timer_widget_hidden(self.gui.share_mode)
- self.server_timed_out(self.gui.share_mode, 125000)
- self.web_server_is_stopped()
diff --git a/tests/conftest.py b/tests/conftest.py
index ac81d14d..200f526d 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,6 +3,9 @@ import sys
# Force tests to look for resources in the source code tree
sys.onionshare_dev_mode = True
+# Let OnionShare know the tests are running, to avoid colliding with settings files
+sys.onionshare_test_mode = True
+
import os
import shutil
import tempfile
@@ -12,6 +15,10 @@ import pytest
from onionshare import common, web, settings, strings
+# The temporary directory for CLI tests
+test_temp_dir = None
+
+
def pytest_addoption(parser):
parser.addoption(
"--rungui", action="store_true", default=False, help="run GUI tests"
@@ -38,51 +45,60 @@ def pytest_collection_modifyitems(config, items):
@pytest.fixture
-def temp_dir_1024():
+def temp_dir():
+ """Creates a persistent temporary directory for the CLI tests to use"""
+ global test_temp_dir
+ if not test_temp_dir:
+ test_temp_dir = tempfile.mkdtemp()
+ return test_temp_dir
+
+
+@pytest.fixture
+def temp_dir_1024(temp_dir):
""" Create a temporary directory that has a single file of a
particular size (1024 bytes).
"""
- tmp_dir = tempfile.mkdtemp()
- tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir)
+ new_temp_dir = tempfile.mkdtemp(dir=temp_dir)
+ tmp_file, tmp_file_path = tempfile.mkstemp(dir=new_temp_dir)
with open(tmp_file, "wb") as f:
f.write(b"*" * 1024)
- return tmp_dir
+ return new_temp_dir
# pytest > 2.9 only needs @pytest.fixture
@pytest.yield_fixture
-def temp_dir_1024_delete():
+def temp_dir_1024_delete(temp_dir):
""" Create a temporary directory that has a single file of a
particular size (1024 bytes). The temporary directory (including
the file inside) will be deleted after fixture usage.
"""
- with tempfile.TemporaryDirectory() as tmp_dir:
- tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir)
+ with tempfile.TemporaryDirectory(dir=temp_dir) as new_temp_dir:
+ tmp_file, tmp_file_path = tempfile.mkstemp(dir=new_temp_dir)
with open(tmp_file, "wb") as f:
f.write(b"*" * 1024)
- yield tmp_dir
+ yield new_temp_dir
@pytest.fixture
-def temp_file_1024():
+def temp_file_1024(temp_dir):
""" Create a temporary file of a particular size (1024 bytes). """
- with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
+ with tempfile.NamedTemporaryFile(delete=False, dir=temp_dir) as tmp_file:
tmp_file.write(b"*" * 1024)
return tmp_file.name
# pytest > 2.9 only needs @pytest.fixture
@pytest.yield_fixture
-def temp_file_1024_delete():
+def temp_file_1024_delete(temp_dir):
"""
Create a temporary file of a particular size (1024 bytes).
The temporary file will be deleted after fixture usage.
"""
- with tempfile.NamedTemporaryFile() as tmp_file:
+ with tempfile.NamedTemporaryFile(dir=temp_dir) as tmp_file:
tmp_file.write(b"*" * 1024)
tmp_file.flush()
yield tmp_file.name
@@ -108,7 +124,10 @@ def default_zw():
yield zw
zw.close()
tmp_dir = os.path.dirname(zw.zip_filename)
- shutil.rmtree(tmp_dir)
+ try:
+ shutil.rmtree(tmp_dir, ignore_errors=True)
+ except:
+ pass
@pytest.fixture
diff --git a/tests/gui_base_test.py b/tests/gui_base_test.py
new file mode 100644
index 00000000..dc883c05
--- /dev/null
+++ b/tests/gui_base_test.py
@@ -0,0 +1,425 @@
+import pytest
+import unittest
+
+import json
+import os
+import requests
+import shutil
+import base64
+import tempfile
+import secrets
+
+from PyQt5 import QtCore, QtTest, QtWidgets
+
+from onionshare import strings
+from onionshare.common import Common
+from onionshare.settings import Settings
+from onionshare.onion import Onion
+from onionshare.web import Web
+
+from onionshare_gui import Application, MainWindow, GuiCommon
+from onionshare_gui.tab.mode.share_mode import ShareMode
+from onionshare_gui.tab.mode.receive_mode import ReceiveMode
+from onionshare_gui.tab.mode.website_mode import WebsiteMode
+
+
+class GuiBaseTest(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ common = Common(verbose=True)
+
+ # Delete any old test data that might exist
+ shutil.rmtree(common.build_data_dir(), ignore_errors=True)
+
+ qtapp = Application(common)
+ common.gui = GuiCommon(common, qtapp, local_only=True)
+ cls.gui = MainWindow(common, filenames=None)
+ cls.gui.qtapp = qtapp
+
+ # Create some random files to test with
+ cls.tmpdir = tempfile.TemporaryDirectory()
+ cls.tmpfiles = []
+ for _ in range(10):
+ filename = os.path.join(cls.tmpdir.name, f"{secrets.token_hex(4)}.txt")
+ with open(filename, "w") as file:
+ file.write(secrets.token_hex(10))
+ cls.tmpfiles.append(filename)
+
+ # A file called "test.txt"
+ cls.tmpfile_test = os.path.join(cls.tmpdir.name, "test.txt")
+ with open(cls.tmpfile_test, "w") as file:
+ file.write("onionshare")
+
+ # A file called "test2.txt"
+ cls.tmpfile_test2 = os.path.join(cls.tmpdir.name, "test2.txt")
+ with open(cls.tmpfile_test2, "w") as file:
+ file.write("onionshare2")
+
+ # A file called "index.html"
+ cls.tmpfile_index_html = os.path.join(cls.tmpdir.name, "index.html")
+ with open(cls.tmpfile_index_html, "w") as file:
+ file.write(
+ "<html><body><p>This is a test website hosted by OnionShare</p></body></html>"
+ )
+
+ # A large file
+ size = 1024 * 1024 * 155
+ cls.tmpfile_large = os.path.join(cls.tmpdir.name, "large_file")
+ with open(cls.tmpfile_large, "wb") as fout:
+ fout.write(os.urandom(size))
+
+ @classmethod
+ def tearDownClass(cls):
+ # Quit
+ QtCore.QTimer.singleShot(200, cls.gui.close_dialog.accept_button.click)
+ cls.gui.close()
+
+ cls.gui.cleanup()
+
+ # Shared test methods
+
+ def verify_new_tab(self, tab):
+ # Make sure the new tab widget is showing, and no mode has been started
+ QtTest.QTest.qWait(500)
+ self.assertTrue(tab.new_tab.isVisible())
+ self.assertFalse(hasattr(tab, "share_mode"))
+ self.assertFalse(hasattr(tab, "receive_mode"))
+ self.assertFalse(hasattr(tab, "website_mode"))
+
+ def new_share_tab(self):
+ tab = self.gui.tabs.widget(0)
+ self.verify_new_tab(tab)
+
+ # Share files
+ tab.share_button.click()
+ self.assertFalse(tab.new_tab.isVisible())
+ self.assertTrue(tab.share_mode.isVisible())
+
+ return tab
+
+ def new_share_tab_with_files(self):
+ tab = self.new_share_tab()
+
+ # Add files
+ for filename in self.tmpfiles:
+ tab.share_mode.server_status.file_selection.file_list.add_file(filename)
+
+ return tab
+
+ def new_receive_tab(self):
+ tab = self.gui.tabs.widget(0)
+ self.verify_new_tab(tab)
+
+ # Receive files
+ tab.receive_button.click()
+ self.assertFalse(tab.new_tab.isVisible())
+ self.assertTrue(tab.receive_mode.isVisible())
+
+ return tab
+
+ def new_website_tab(self):
+ tab = self.gui.tabs.widget(0)
+ self.verify_new_tab(tab)
+
+ # Publish website
+ tab.website_button.click()
+ self.assertFalse(tab.new_tab.isVisible())
+ self.assertTrue(tab.website_mode.isVisible())
+
+ return tab
+
+ def new_website_tab_with_files(self):
+ tab = self.new_website_tab()
+
+ # Add files
+ for filename in self.tmpfiles:
+ tab.website_mode.server_status.file_selection.file_list.add_file(filename)
+
+ return tab
+
+ def close_all_tabs(self):
+ for _ in range(self.gui.tabs.count()):
+ tab = self.gui.tabs.widget(0)
+ QtCore.QTimer.singleShot(200, tab.close_dialog.accept_button.click)
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+
+ def gui_loaded(self):
+ """Test that the GUI actually is shown"""
+ self.assertTrue(self.gui.show)
+
+ def window_title_seen(self):
+ """Test that the window title is OnionShare"""
+ self.assertEqual(self.gui.windowTitle(), "OnionShare")
+
+ def server_status_bar_is_visible(self):
+ """Test that the status bar is visible"""
+ self.assertTrue(self.gui.status_bar.isVisible())
+
+ def mode_settings_widget_is_visible(self, tab):
+ """Test that the mode settings are visible"""
+ self.assertTrue(tab.get_mode().mode_settings_widget.isVisible())
+
+ def mode_settings_widget_is_hidden(self, tab):
+ """Test that the mode settings are hidden when the server starts"""
+ self.assertFalse(tab.get_mode().mode_settings_widget.isVisible())
+
+ def click_toggle_history(self, tab):
+ """Test that we can toggle Download or Upload history by clicking the toggle button"""
+ currently_visible = tab.get_mode().history.isVisible()
+ tab.get_mode().toggle_history.click()
+ self.assertEqual(tab.get_mode().history.isVisible(), not currently_visible)
+
+ def history_indicator(self, tab, indicator_count="1"):
+ """Test that we can make sure the history is toggled off, do an action, and the indiciator works"""
+ # Make sure history is toggled off
+ if tab.get_mode().history.isVisible():
+ tab.get_mode().toggle_history.click()
+ self.assertFalse(tab.get_mode().history.isVisible())
+
+ # Indicator should not be visible yet
+ self.assertFalse(tab.get_mode().toggle_history.indicator_label.isVisible())
+
+ if type(tab.get_mode()) == ReceiveMode:
+ # Upload a file
+ files = {"file[]": open(self.tmpfiles[0], "rb")}
+ url = f"http://127.0.0.1:{tab.app.port}/upload"
+ if tab.settings.get("general", "public"):
+ requests.post(url, files=files)
+ else:
+ requests.post(
+ url,
+ files=files,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().web.password
+ ),
+ )
+ QtTest.QTest.qWait(2000)
+
+ if type(tab.get_mode()) == ShareMode:
+ # Download files
+ url = f"http://127.0.0.1:{tab.app.port}/download"
+ if tab.settings.get("general", "public"):
+ requests.get(url)
+ else:
+ requests.get(
+ url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().web.password
+ ),
+ )
+ QtTest.QTest.qWait(2000)
+
+ # Indicator should be visible, have a value of "1"
+ self.assertTrue(tab.get_mode().toggle_history.indicator_label.isVisible())
+ self.assertEqual(
+ tab.get_mode().toggle_history.indicator_label.text(), indicator_count
+ )
+
+ # Toggle history back on, indicator should be hidden again
+ tab.get_mode().toggle_history.click()
+ self.assertFalse(tab.get_mode().toggle_history.indicator_label.isVisible())
+
+ def history_is_not_visible(self, tab):
+ """Test that the History section is not visible"""
+ self.assertFalse(tab.get_mode().history.isVisible())
+
+ def history_is_visible(self, tab):
+ """Test that the History section is visible"""
+ self.assertTrue(tab.get_mode().history.isVisible())
+
+ def server_working_on_start_button_pressed(self, tab):
+ """Test we can start the service"""
+ # Should be in SERVER_WORKING state
+ tab.get_mode().server_status.server_button.click()
+ self.assertEqual(tab.get_mode().server_status.status, 1)
+
+ def toggle_indicator_is_reset(self, tab):
+ self.assertEqual(tab.get_mode().toggle_history.indicator_count, 0)
+ self.assertFalse(tab.get_mode().toggle_history.indicator_label.isVisible())
+
+ def server_status_indicator_says_starting(self, tab):
+ """Test that the Server Status indicator shows we are Starting"""
+ self.assertEqual(
+ tab.get_mode().server_status_label.text(),
+ strings._("gui_status_indicator_share_working"),
+ )
+
+ def server_status_indicator_says_scheduled(self, tab):
+ """Test that the Server Status indicator shows we are Scheduled"""
+ self.assertEqual(
+ tab.get_mode().server_status_label.text(),
+ strings._("gui_status_indicator_share_scheduled"),
+ )
+
+ def server_is_started(self, tab, startup_time=2000):
+ """Test that the server has started"""
+ QtTest.QTest.qWait(startup_time)
+ # Should now be in SERVER_STARTED state
+ self.assertEqual(tab.get_mode().server_status.status, 2)
+
+ def web_server_is_running(self, tab):
+ """Test that the web server has started"""
+ try:
+ requests.get(f"http://127.0.0.1:{tab.app.port}/")
+ self.assertTrue(True)
+ except requests.exceptions.ConnectionError:
+ self.assertTrue(False)
+
+ def have_a_password(self, tab):
+ """Test that we have a valid password"""
+ if not tab.settings.get("general", "public"):
+ self.assertRegex(tab.get_mode().server_status.web.password, r"(\w+)-(\w+)")
+ else:
+ self.assertIsNone(tab.get_mode().server_status.web.password, r"(\w+)-(\w+)")
+
+ def add_button_visible(self, tab):
+ """Test that the add button should be visible"""
+ self.assertTrue(
+ tab.get_mode().server_status.file_selection.add_button.isVisible()
+ )
+
+ def url_description_shown(self, tab):
+ """Test that the URL label is showing"""
+ self.assertTrue(tab.get_mode().server_status.url_description.isVisible())
+
+ def have_copy_url_button(self, tab):
+ """Test that the Copy URL button is shown and that the clipboard is correct"""
+ self.assertTrue(tab.get_mode().server_status.copy_url_button.isVisible())
+
+ tab.get_mode().server_status.copy_url_button.click()
+ clipboard = tab.common.gui.qtapp.clipboard()
+ if tab.settings.get("general", "public"):
+ self.assertEqual(clipboard.text(), f"http://127.0.0.1:{tab.app.port}")
+ else:
+ self.assertEqual(
+ clipboard.text(),
+ f"http://onionshare:{tab.get_mode().server_status.web.password}@127.0.0.1:{tab.app.port}",
+ )
+
+ def server_status_indicator_says_started(self, tab):
+ """Test that the Server Status indicator shows we are started"""
+ if type(tab.get_mode()) == ReceiveMode:
+ self.assertEqual(
+ tab.get_mode().server_status_label.text(),
+ strings._("gui_status_indicator_receive_started"),
+ )
+ if type(tab.get_mode()) == ShareMode:
+ self.assertEqual(
+ tab.get_mode().server_status_label.text(),
+ strings._("gui_status_indicator_share_started"),
+ )
+
+ def web_page(self, tab, string):
+ """Test that the web page contains a string"""
+
+ url = f"http://127.0.0.1:{tab.app.port}/"
+ if tab.settings.get("general", "public"):
+ r = requests.get(url)
+ else:
+ r = requests.get(
+ url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().web.password
+ ),
+ )
+
+ self.assertTrue(string in r.text)
+
+ def history_widgets_present(self, tab):
+ """Test that the relevant widgets are present in the history view after activity has taken place"""
+ self.assertFalse(tab.get_mode().history.empty.isVisible())
+ self.assertTrue(tab.get_mode().history.not_empty.isVisible())
+
+ def counter_incremented(self, tab, count):
+ """Test that the counter has incremented"""
+ self.assertEqual(tab.get_mode().history.completed_count, count)
+
+ def server_is_stopped(self, tab):
+ """Test that the server stops when we click Stop"""
+ if (
+ type(tab.get_mode()) == ReceiveMode
+ or (
+ type(tab.get_mode()) == ShareMode
+ and not tab.settings.get("share", "autostop_sharing")
+ )
+ or (type(tab.get_mode()) == WebsiteMode)
+ ):
+ tab.get_mode().server_status.server_button.click()
+ self.assertEqual(tab.get_mode().server_status.status, 0)
+
+ def web_server_is_stopped(self, tab):
+ """Test that the web server also stopped"""
+ QtTest.QTest.qWait(200)
+
+ try:
+ requests.get(f"http://127.0.0.1:{tab.app.port}/")
+ self.assertTrue(False)
+ except requests.exceptions.ConnectionError:
+ self.assertTrue(True)
+
+ def server_status_indicator_says_closed(self, tab):
+ """Test that the Server Status indicator shows we closed"""
+ if type(tab.get_mode()) == ReceiveMode:
+ self.assertEqual(
+ tab.get_mode().server_status_label.text(),
+ strings._("gui_status_indicator_receive_stopped"),
+ )
+ if type(tab.get_mode()) == ShareMode:
+ if not tab.settings.get("share", "autostop_sharing"):
+ self.assertEqual(
+ tab.get_mode().server_status_label.text(),
+ strings._("gui_status_indicator_share_stopped"),
+ )
+ else:
+ self.assertEqual(
+ tab.get_mode().server_status_label.text(),
+ strings._("closing_automatically"),
+ )
+
+ def clear_all_history_items(self, tab, count):
+ if count == 0:
+ tab.get_mode().history.clear_button.click()
+ self.assertEqual(len(tab.get_mode().history.item_list.items.keys()), count)
+
+ def file_selection_widget_has_files(self, tab, num=3):
+ """Test that the number of items in the list is as expected"""
+ self.assertEqual(
+ tab.get_mode().server_status.file_selection.get_num_files(), num
+ )
+
+ def add_delete_buttons_hidden(self, tab):
+ """Test that the add and delete buttons are hidden when the server starts"""
+ self.assertFalse(
+ tab.get_mode().server_status.file_selection.add_button.isVisible()
+ )
+ self.assertFalse(
+ tab.get_mode().server_status.file_selection.delete_button.isVisible()
+ )
+
+ # Auto-stop timer tests
+ def set_timeout(self, tab, timeout):
+ """Test that the timeout can be set"""
+ timer = QtCore.QDateTime.currentDateTime().addSecs(timeout)
+ tab.get_mode().mode_settings_widget.autostop_timer_widget.setDateTime(timer)
+ self.assertTrue(
+ tab.get_mode().mode_settings_widget.autostop_timer_widget.dateTime(), timer
+ )
+
+ def autostop_timer_widget_hidden(self, tab):
+ """Test that the auto-stop timer widget is hidden when share has started"""
+ self.assertFalse(
+ tab.get_mode().mode_settings_widget.autostop_timer_widget.isVisible()
+ )
+
+ def server_timed_out(self, tab, wait):
+ """Test that the server has timed out after the timer ran out"""
+ QtTest.QTest.qWait(wait)
+ # We should have timed out now
+ self.assertEqual(tab.get_mode().server_status.status, 0)
+
+ # Grouped tests follow from here
+
+ def run_all_common_setup_tests(self):
+ self.gui_loaded()
+ self.window_title_seen()
+ self.server_status_bar_is_visible()
diff --git a/tests/local_onionshare_401_public_mode_skips_ratelimit_test.py b/tests/local_onionshare_401_public_mode_skips_ratelimit_test.py
deleted file mode 100644
index 388a424b..00000000
--- a/tests/local_onionshare_401_public_mode_skips_ratelimit_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class Local401PublicModeRateLimitTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": False, "public_mode": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(True, True)
- self.hit_401(True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_401_triggers_ratelimit_test.py b/tests/local_onionshare_401_triggers_ratelimit_test.py
deleted file mode 100644
index cdeb34db..00000000
--- a/tests/local_onionshare_401_triggers_ratelimit_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class Local401RateLimitTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": False}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, True)
- self.hit_401(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_quitting_during_share_prompts_warning_test.py b/tests/local_onionshare_quitting_during_share_prompts_warning_test.py
deleted file mode 100644
index 9a38e24a..00000000
--- a/tests/local_onionshare_quitting_during_share_prompts_warning_test.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-from PyQt5 import QtCore, QtTest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalQuittingDuringSharePromptsWarningTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": False}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, True)
- # Prepare our auto-accept of prompt
- QtCore.QTimer.singleShot(5000, self.accept_dialog)
- # Try to close the app
- self.gui.close()
- # Server should still be running (we've been prompted first)
- self.server_is_started(self.gui.share_mode, 0)
- self.web_server_is_running()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_receive_mode_clear_all_button_test.py b/tests/local_onionshare_receive_mode_clear_all_button_test.py
deleted file mode 100644
index d69c3e59..00000000
--- a/tests/local_onionshare_receive_mode_clear_all_button_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiReceiveTest import GuiReceiveTest
-
-
-class LocalReceiveModeClearAllButtonTest(unittest.TestCase, GuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {}
- cls.gui = GuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_clear_all_button_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_receive_mode_timer_test.py b/tests/local_onionshare_receive_mode_timer_test.py
deleted file mode 100644
index f958a132..00000000
--- a/tests/local_onionshare_receive_mode_timer_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiReceiveTest import GuiReceiveTest
-
-
-class LocalReceiveModeTimerTest(unittest.TestCase, GuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": False, "autostop_timer": True}
- cls.gui = GuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_receive_mode_timer_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py
deleted file mode 100644
index f1451ba0..00000000
--- a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiReceiveTest import GuiReceiveTest
-
-
-class LocalReceiveModeUnwritableTest(unittest.TestCase, GuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"receive_allow_receiver_shutdown": True}
- cls.gui = GuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_receive_mode_unwritable_dir_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py
deleted file mode 100644
index 6f0997f2..00000000
--- a/tests/local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiReceiveTest import GuiReceiveTest
-
-
-class LocalReceivePublicModeUnwritableTest(unittest.TestCase, GuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": True, "receive_allow_receiver_shutdown": True}
- cls.gui = GuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_receive_mode_unwritable_dir_tests(True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_receive_mode_upload_public_mode_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_test.py
deleted file mode 100644
index 818bd593..00000000
--- a/tests/local_onionshare_receive_mode_upload_public_mode_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiReceiveTest import GuiReceiveTest
-
-
-class LocalReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": True, "receive_allow_receiver_shutdown": True}
- cls.gui = GuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_receive_mode_tests(True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_receive_mode_upload_test.py b/tests/local_onionshare_receive_mode_upload_test.py
deleted file mode 100644
index 38888655..00000000
--- a/tests/local_onionshare_receive_mode_upload_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiReceiveTest import GuiReceiveTest
-
-
-class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"receive_allow_receiver_shutdown": True}
- cls.gui = GuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_receive_mode_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_settings_dialog_legacy_tor_test.py b/tests/local_onionshare_settings_dialog_legacy_tor_test.py
deleted file mode 100644
index 72d33241..00000000
--- a/tests/local_onionshare_settings_dialog_legacy_tor_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from onionshare import strings
-from .SettingsGuiBaseTest import SettingsGuiBaseTest, OnionStub
-
-
-class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest):
- @classmethod
- def setUpClass(cls):
- cls.gui = SettingsGuiBaseTest.set_up()
-
- @classmethod
- def tearDownClass(cls):
- SettingsGuiBaseTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui_legacy_tor(self):
- self.gui.onion = OnionStub(True, False)
- self.gui.reload_settings()
- self.run_settings_gui_tests()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_settings_dialog_no_tor_test.py b/tests/local_onionshare_settings_dialog_no_tor_test.py
deleted file mode 100644
index b8c06243..00000000
--- a/tests/local_onionshare_settings_dialog_no_tor_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from onionshare import strings
-from .SettingsGuiBaseTest import SettingsGuiBaseTest, OnionStub
-
-
-class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest):
- @classmethod
- def setUpClass(cls):
- cls.gui = SettingsGuiBaseTest.set_up()
-
- @classmethod
- def tearDownClass(cls):
- SettingsGuiBaseTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui_no_tor(self):
- self.gui.onion = OnionStub(False, False)
- self.gui.reload_settings()
- self.run_settings_gui_tests()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_settings_dialog_v3_tor_test.py b/tests/local_onionshare_settings_dialog_v3_tor_test.py
deleted file mode 100644
index d5abeabc..00000000
--- a/tests/local_onionshare_settings_dialog_v3_tor_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from onionshare import strings
-from .SettingsGuiBaseTest import SettingsGuiBaseTest, OnionStub
-
-
-class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest):
- @classmethod
- def setUpClass(cls):
- cls.gui = SettingsGuiBaseTest.set_up()
-
- @classmethod
- def tearDownClass(cls):
- SettingsGuiBaseTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui_v3_tor(self):
- self.gui.onion = OnionStub(True, True)
- self.gui.reload_settings()
- self.run_settings_gui_tests()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_autostart_and_autostop_timer_mismatch_test.py b/tests/local_onionshare_share_mode_autostart_and_autostop_timer_mismatch_test.py
deleted file mode 100644
index 2a25bef1..00000000
--- a/tests/local_onionshare_share_mode_autostart_and_autostop_timer_mismatch_test.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeAutoStartTimerTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {
- "public_mode": False,
- "autostart_timer": True,
- "autostop_timer": True,
- }
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_autostop_autostart_mismatch_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_autostart_timer_test.py b/tests/local_onionshare_share_mode_autostart_timer_test.py
deleted file mode 100644
index 776cff4f..00000000
--- a/tests/local_onionshare_share_mode_autostart_timer_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeAutoStartTimerTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": False, "autostart_timer": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_autostart_timer_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_autostart_timer_too_short_test.py b/tests/local_onionshare_share_mode_autostart_timer_too_short_test.py
deleted file mode 100644
index 1c2040df..00000000
--- a/tests/local_onionshare_share_mode_autostart_timer_too_short_test.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-from PyQt5 import QtCore, QtTest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeAutoStartTimerTooShortTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": False, "autostart_timer": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_setup_tests()
- # Set a low timeout
- self.set_autostart_timer(self.gui.share_mode, 2)
- QtTest.QTest.qWait(3000)
- QtCore.QTimer.singleShot(4000, self.accept_dialog)
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton
- )
- self.assertEqual(self.gui.share_mode.server_status.status, 0)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_cancel_share_test.py b/tests/local_onionshare_share_mode_cancel_share_test.py
deleted file mode 100644
index d6ee051b..00000000
--- a/tests/local_onionshare_share_mode_cancel_share_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeCancelTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"autostart_timer": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_setup_tests()
- self.cancel_the_share(self.gui.share_mode)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_clear_all_button_test.py b/tests/local_onionshare_share_mode_clear_all_button_test.py
deleted file mode 100644
index 1c11fe81..00000000
--- a/tests/local_onionshare_share_mode_clear_all_button_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeClearAllButtonTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": False}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_clear_all_button_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_download_public_mode_test.py b/tests/local_onionshare_share_mode_download_public_mode_test.py
deleted file mode 100644
index 6661eae7..00000000
--- a/tests/local_onionshare_share_mode_download_public_mode_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModePublicModeTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(True, False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_download_stay_open_test.py b/tests/local_onionshare_share_mode_download_stay_open_test.py
deleted file mode 100644
index 04213865..00000000
--- a/tests/local_onionshare_share_mode_download_stay_open_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeStayOpenTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": False}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_download_test.py b/tests/local_onionshare_share_mode_download_test.py
deleted file mode 100644
index 1c0b69e9..00000000
--- a/tests/local_onionshare_share_mode_download_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_individual_file_view_stay_open_test.py b/tests/local_onionshare_share_mode_individual_file_view_stay_open_test.py
deleted file mode 100644
index 18b3283a..00000000
--- a/tests/local_onionshare_share_mode_individual_file_view_stay_open_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeIndividualFileViewStayOpenTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": False}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_individual_file_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_individual_file_view_test.py b/tests/local_onionshare_share_mode_individual_file_view_test.py
deleted file mode 100644
index d41b2010..00000000
--- a/tests/local_onionshare_share_mode_individual_file_view_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeIndividualFileViewTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_individual_file_tests(False, False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_large_download_test.py b/tests/local_onionshare_share_mode_large_download_test.py
deleted file mode 100644
index a0458d03..00000000
--- a/tests/local_onionshare_share_mode_large_download_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeLargeDownloadTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_large_file_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_password_persistent_test.py b/tests/local_onionshare_share_mode_password_persistent_test.py
deleted file mode 100644
index 067815f7..00000000
--- a/tests/local_onionshare_share_mode_password_persistent_test.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModePersistentPasswordTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {
- "public_mode": False,
- "password": "",
- "save_private_key": True,
- "close_after_first_download": False,
- }
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_persistent_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_timer_test.py b/tests/local_onionshare_share_mode_timer_test.py
deleted file mode 100644
index da200f97..00000000
--- a/tests/local_onionshare_share_mode_timer_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeTimerTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": False, "autostop_timer": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_timer_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_timer_too_short_test.py b/tests/local_onionshare_share_mode_timer_too_short_test.py
deleted file mode 100644
index 63c2fdc2..00000000
--- a/tests/local_onionshare_share_mode_timer_too_short_test.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-from PyQt5 import QtCore, QtTest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeTimerTooShortTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": False, "autostop_timer": True}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_setup_tests()
- # Set a low timeout
- self.set_timeout(self.gui.share_mode, 2)
- QtTest.QTest.qWait(3000)
- QtCore.QTimer.singleShot(4000, self.accept_dialog)
- QtTest.QTest.mouseClick(
- self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton
- )
- self.assertEqual(self.gui.share_mode.server_status.status, 0)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_share_mode_unreadable_file_test.py b/tests/local_onionshare_share_mode_unreadable_file_test.py
deleted file mode 100644
index 80f0fdb8..00000000
--- a/tests/local_onionshare_share_mode_unreadable_file_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiShareTest import GuiShareTest
-
-
-class LocalShareModeUnReadableFileTest(unittest.TestCase, GuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {}
- cls.gui = GuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_unreadable_file_tests()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_website_mode_csp_enabled_test.py b/tests/local_onionshare_website_mode_csp_enabled_test.py
deleted file mode 100644
index f9fdb983..00000000
--- a/tests/local_onionshare_website_mode_csp_enabled_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiWebsiteTest import GuiWebsiteTest
-
-
-class LocalWebsiteModeCSPEnabledTest(unittest.TestCase, GuiWebsiteTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"csp_header_disabled": False}
- cls.gui = GuiWebsiteTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiWebsiteTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- # self.run_all_common_setup_tests()
- self.run_all_website_mode_download_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/local_onionshare_website_mode_test.py b/tests/local_onionshare_website_mode_test.py
deleted file mode 100644
index ba00e780..00000000
--- a/tests/local_onionshare_website_mode_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .GuiWebsiteTest import GuiWebsiteTest
-
-
-class LocalWebsiteModeTest(unittest.TestCase, GuiWebsiteTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"csp_header_disabled": True}
- cls.gui = GuiWebsiteTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- GuiWebsiteTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- # self.run_all_common_setup_tests()
- self.run_all_website_mode_download_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_790_cancel_on_second_share_test.py b/tests/onionshare_790_cancel_on_second_share_test.py
deleted file mode 100644
index 7a87c690..00000000
--- a/tests/onionshare_790_cancel_on_second_share_test.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-# Tests #790 regression
-class ShareModeCancelSecondShareTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": True}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, False)
- self.cancel_the_share(self.gui.share_mode)
- self.server_is_stopped(self.gui.share_mode, False)
- self.web_server_is_stopped()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_receive_mode_upload_public_mode_test.py b/tests/onionshare_receive_mode_upload_public_mode_test.py
deleted file mode 100644
index 31b1a8f6..00000000
--- a/tests/onionshare_receive_mode_upload_public_mode_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiReceiveTest import TorGuiReceiveTest
-
-
-class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": True, "receive_allow_receiver_shutdown": True}
- cls.gui = TorGuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_receive_mode_tests(True, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_receive_mode_upload_test.py b/tests/onionshare_receive_mode_upload_test.py
deleted file mode 100644
index ca695843..00000000
--- a/tests/onionshare_receive_mode_upload_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiReceiveTest import TorGuiReceiveTest
-
-
-class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"receive_allow_receiver_shutdown": True}
- cls.gui = TorGuiReceiveTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiReceiveTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_receive_mode_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_cancel_share_test.py b/tests/onionshare_share_mode_cancel_share_test.py
deleted file mode 100644
index 0483fbe1..00000000
--- a/tests/onionshare_share_mode_cancel_share_test.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModeCancelTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"autostart_timer": True}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_setup_tests()
- self.cancel_the_share(self.gui.share_mode)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_download_public_mode_test.py b/tests/onionshare_share_mode_download_public_mode_test.py
deleted file mode 100644
index 72554f8b..00000000
--- a/tests/onionshare_share_mode_download_public_mode_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModePublicModeTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": True}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(True, False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_download_stay_open_test.py b/tests/onionshare_share_mode_download_stay_open_test.py
deleted file mode 100644
index 923eebf3..00000000
--- a/tests/onionshare_share_mode_download_stay_open_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModeStayOpenTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"close_after_first_download": False}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_download_test.py b/tests/onionshare_share_mode_download_test.py
deleted file mode 100644
index 2bebd098..00000000
--- a/tests/onionshare_share_mode_download_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModeTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_persistent_test.py b/tests/onionshare_share_mode_persistent_test.py
deleted file mode 100644
index c5d44733..00000000
--- a/tests/onionshare_share_mode_persistent_test.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModePersistentPasswordTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {
- "use_legacy_v2_onions": True,
- "public_mode": False,
- "password": "",
- "save_private_key": True,
- "close_after_first_download": False,
- }
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_persistent_tests(False, True)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_stealth_test.py b/tests/onionshare_share_mode_stealth_test.py
deleted file mode 100644
index 3ee743d5..00000000
--- a/tests/onionshare_share_mode_stealth_test.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"use_legacy_v2_onions": True, "use_stealth": True}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_setup_tests()
- self.run_all_share_mode_started_tests(False)
- self.hidserv_auth_string()
- self.copy_have_hidserv_auth_button(self.gui.share_mode)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_timer_test.py b/tests/onionshare_share_mode_timer_test.py
deleted file mode 100644
index 78a70bbf..00000000
--- a/tests/onionshare_share_mode_timer_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModeTimerTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"public_mode": False, "autostop_timer": True}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_timer_tests(False)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_tor_connection_killed_test.py b/tests/onionshare_share_mode_tor_connection_killed_test.py
deleted file mode 100644
index 4702ab3e..00000000
--- a/tests/onionshare_share_mode_tor_connection_killed_test.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModeTorConnectionKilledTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_setup_tests()
- self.run_all_share_mode_started_tests(False)
- self.tor_killed_statusbar_message_shown(self.gui.share_mode)
- self.server_is_stopped(self.gui.share_mode, False)
- self.web_server_is_stopped()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/onionshare_share_mode_v2_onion_test.py b/tests/onionshare_share_mode_v2_onion_test.py
deleted file mode 100644
index 152457ba..00000000
--- a/tests/onionshare_share_mode_v2_onion_test.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import unittest
-
-from .TorGuiShareTest import TorGuiShareTest
-
-
-class ShareModeV2OnionTest(unittest.TestCase, TorGuiShareTest):
- @classmethod
- def setUpClass(cls):
- test_settings = {"use_legacy_v2_onions": True}
- cls.gui = TorGuiShareTest.set_up(test_settings)
-
- @classmethod
- def tearDownClass(cls):
- TorGuiShareTest.tear_down()
-
- @pytest.mark.gui
- @pytest.mark.tor
- @pytest.mark.skipif(pytest.__version__ < "2.9", reason="requires newer pytest")
- def test_gui(self):
- self.run_all_common_setup_tests()
- self.run_all_share_mode_tests(False, False)
- self.have_v2_onion()
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/test_onionshare.py b/tests/test_cli.py
index 0addf6d5..0addf6d5 100644
--- a/tests/test_onionshare.py
+++ b/tests/test_cli.py
diff --git a/tests/test_onionshare_common.py b/tests/test_cli_common.py
index 1f230295..1f230295 100644
--- a/tests/test_onionshare_common.py
+++ b/tests/test_cli_common.py
diff --git a/tests/test_onionshare_settings.py b/tests/test_cli_settings.py
index 1b21ff3b..7a1e8de5 100644
--- a/tests/test_onionshare_settings.py
+++ b/tests/test_cli_settings.py
@@ -27,11 +27,6 @@ from onionshare import common, settings, strings
@pytest.fixture
-def os_path_expanduser(monkeypatch):
- monkeypatch.setattr("os.path.expanduser", lambda path: path)
-
-
-@pytest.fixture
def settings_obj(sys_onionshare_dev_mode, platform_linux):
_common = common.Common()
_common.version = "DUMMY_VERSION_1.2.3"
@@ -69,13 +64,13 @@ class TestSettings:
settings_obj.fill_in_defaults()
assert settings_obj._settings["version"] == "DUMMY_VERSION_1.2.3"
- def test_load(self, settings_obj):
+ def test_load(self, temp_dir, settings_obj):
custom_settings = {
"version": "CUSTOM_VERSION",
"socks_port": 9999,
"use_stealth": True,
}
- tmp_file, tmp_file_path = tempfile.mkstemp()
+ tmp_file, tmp_file_path = tempfile.mkstemp(dir=temp_dir)
with open(tmp_file, "w") as f:
json.dump(custom_settings, f)
settings_obj.filename = tmp_file_path
@@ -88,12 +83,12 @@ class TestSettings:
os.remove(tmp_file_path)
assert os.path.exists(tmp_file_path) is False
- def test_save(self, monkeypatch, settings_obj):
+ def test_save(self, monkeypatch, temp_dir, settings_obj):
monkeypatch.setattr(strings, "_", lambda _: "")
settings_filename = "default_settings.json"
- tmp_dir = tempfile.gettempdir()
- settings_path = os.path.join(tmp_dir, settings_filename)
+ new_temp_dir = tempfile.mkdtemp(dir=temp_dir)
+ settings_path = os.path.join(new_temp_dir, settings_filename)
settings_obj.filename = settings_path
settings_obj.save()
with open(settings_path, "r") as f:
@@ -140,20 +135,17 @@ class TestSettings:
settings_obj.set("socks_port", "NON_INTEGER")
assert settings_obj._settings["socks_port"] == 9050
- def test_filename_darwin(self, monkeypatch, os_path_expanduser, platform_darwin):
+ def test_filename_darwin(self, monkeypatch, platform_darwin):
obj = settings.Settings(common.Common())
- assert (
- obj.filename == "~/Library/Application Support/OnionShare/onionshare.json"
+ assert obj.filename == os.path.expanduser(
+ "~/Library/Application Support/OnionShare-testdata/onionshare.json"
)
- def test_filename_linux(self, monkeypatch, os_path_expanduser, platform_linux):
+ def test_filename_linux(self, monkeypatch, platform_linux):
obj = settings.Settings(common.Common())
- assert obj.filename == "~/.config/onionshare/onionshare.json"
-
- def test_filename_windows(self, monkeypatch, platform_windows):
- monkeypatch.setenv("APPDATA", "C:")
- obj = settings.Settings(common.Common())
- assert obj.filename.replace("/", "\\") == "C:\\OnionShare\\onionshare.json"
+ assert obj.filename == os.path.expanduser(
+ "~/.config/onionshare-testdata/onionshare.json"
+ )
def test_set_custom_bridge(self, settings_obj):
settings_obj.set(
diff --git a/tests/test_onionshare_strings.py b/tests/test_cli_strings.py
index 7ad65191..7ad65191 100644
--- a/tests/test_onionshare_strings.py
+++ b/tests/test_cli_strings.py
diff --git a/tests/test_onionshare_web.py b/tests/test_cli_web.py
index 2ce2f758..2e7d427b 100644
--- a/tests/test_onionshare_web.py
+++ b/tests/test_cli_web.py
@@ -42,7 +42,7 @@ DEFAULT_ZW_FILENAME_REGEX = re.compile(r"^onionshare_[a-z2-7]{6}.zip$")
RANDOM_STR_REGEX = re.compile(r"^[a-z2-7]+$")
-def web_obj(common_obj, mode, num_files=0):
+def web_obj(temp_dir, common_obj, mode, num_files=0):
""" Creates a Web object, in either share mode or receive mode, ready for testing """
common_obj.settings = Settings(common_obj)
strings.load_strings(common_obj)
@@ -58,7 +58,7 @@ def web_obj(common_obj, mode, num_files=0):
# Add files
files = []
for _ in range(num_files):
- with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
+ with tempfile.NamedTemporaryFile(delete=False, dir=temp_dir) as tmp_file:
tmp_file.write(b"*" * 1024)
files.append(tmp_file.name)
web.share_mode.set_file_info(files)
@@ -70,8 +70,8 @@ def web_obj(common_obj, mode, num_files=0):
class TestWeb:
- def test_share_mode(self, common_obj):
- web = web_obj(common_obj, "share", 3)
+ def test_share_mode(self, temp_dir, common_obj):
+ web = web_obj(temp_dir, common_obj, "share", 3)
assert web.mode == "share"
with web.app.test_client() as c:
# Load / without auth
@@ -95,8 +95,8 @@ class TestWeb:
assert res.status_code == 200
assert res.mimetype == "application/zip"
- def test_share_mode_autostop_sharing_on(self, common_obj, temp_file_1024):
- web = web_obj(common_obj, "share", 3)
+ def test_share_mode_autostop_sharing_on(self, temp_dir, common_obj, temp_file_1024):
+ web = web_obj(temp_dir, common_obj, "share", 3)
web.settings.set("share", "autostop_sharing", True)
assert web.running == True
@@ -110,8 +110,8 @@ class TestWeb:
assert web.running == False
- def test_share_mode_autostop_sharing_off(self, common_obj, temp_file_1024):
- web = web_obj(common_obj, "share", 3)
+ def test_share_mode_autostop_sharing_off(self, temp_dir, common_obj, temp_file_1024):
+ web = web_obj(temp_dir, common_obj, "share", 3)
web.settings.set("share", "autostop_sharing", False)
assert web.running == True
@@ -124,8 +124,8 @@ class TestWeb:
assert res.mimetype == "application/zip"
assert web.running == True
- def test_receive_mode(self, common_obj):
- web = web_obj(common_obj, "receive")
+ def test_receive_mode(self, temp_dir, common_obj):
+ web = web_obj(temp_dir, common_obj, "receive")
assert web.mode == "receive"
with web.app.test_client() as c:
@@ -144,8 +144,8 @@ class TestWeb:
res.get_data()
assert res.status_code == 200
- def test_public_mode_on(self, common_obj):
- web = web_obj(common_obj, "receive")
+ def test_public_mode_on(self, temp_dir, common_obj):
+ web = web_obj(temp_dir, common_obj, "receive")
web.settings.set("general", "public", True)
with web.app.test_client() as c:
@@ -154,8 +154,8 @@ class TestWeb:
data1 = res.get_data()
assert res.status_code == 200
- def test_public_mode_off(self, common_obj):
- web = web_obj(common_obj, "receive")
+ def test_public_mode_off(self, temp_dir, common_obj):
+ web = web_obj(temp_dir, common_obj, "receive")
web.settings.set("general", "public", False)
with web.app.test_client() as c:
diff --git a/tests/test_gui_receive.py b/tests/test_gui_receive.py
new file mode 100644
index 00000000..25f5cd3b
--- /dev/null
+++ b/tests/test_gui_receive.py
@@ -0,0 +1,246 @@
+import pytest
+import os
+import requests
+import shutil
+from datetime import datetime, timedelta
+
+from PyQt5 import QtCore, QtTest
+
+from .gui_base_test import GuiBaseTest
+
+
+class TestReceive(GuiBaseTest):
+ # Shared test methods
+
+ def upload_file(
+ self, tab, file_to_upload, expected_basename, identical_files_at_once=False
+ ):
+ """Test that we can upload the file"""
+
+ # Wait 1.1 seconds to make sure the filename, based on timestamp, isn't accidentally reused
+ QtTest.QTest.qWait(1100)
+
+ files = {"file[]": open(file_to_upload, "rb")}
+ url = f"http://127.0.0.1:{tab.app.port}/upload"
+ if tab.settings.get("general", "public"):
+ requests.post(url, files=files)
+ if identical_files_at_once:
+ # Send a duplicate upload to test for collisions
+ requests.post(url, files=files)
+ else:
+ requests.post(
+ url,
+ files=files,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().web.password
+ ),
+ )
+ if identical_files_at_once:
+ # Send a duplicate upload to test for collisions
+ requests.post(
+ url,
+ files=files,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().web.password
+ ),
+ )
+
+ QtTest.QTest.qWait(500)
+
+ # Make sure the file is within the last 10 seconds worth of fileames
+ exists = False
+ now = datetime.now()
+ for _ in range(10):
+ date_dir = now.strftime("%Y-%m-%d")
+ if identical_files_at_once:
+ time_dir = now.strftime("%H.%M.%S-1")
+ else:
+ time_dir = now.strftime("%H.%M.%S")
+ receive_mode_dir = os.path.join(
+ tab.settings.get("receive", "data_dir"), date_dir, time_dir
+ )
+ expected_filename = os.path.join(receive_mode_dir, expected_basename)
+ if os.path.exists(expected_filename):
+ exists = True
+ break
+ now = now - timedelta(seconds=1)
+
+ self.assertTrue(exists)
+
+ def upload_file_should_fail(self, tab):
+ """Test that we can't upload the file when permissions are wrong, and expected content is shown"""
+ files = {"file[]": open(self.tmpfile_test, "rb")}
+ url = f"http://127.0.0.1:{tab.app.port}/upload"
+ if tab.settings.get("general", "public"):
+ r = requests.post(url, files=files)
+ else:
+ r = requests.post(
+ url,
+ files=files,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().web.password
+ ),
+ )
+
+ def accept_dialog():
+ window = tab.common.gui.qtapp.activeWindow()
+ if window:
+ window.close()
+
+ QtCore.QTimer.singleShot(200, accept_dialog)
+ self.assertTrue("Error uploading, please inform the OnionShare user" in r.text)
+
+ def try_without_auth_in_non_public_mode(self, tab):
+ r = requests.post(f"http://127.0.0.1:{tab.app.port}/upload")
+ self.assertEqual(r.status_code, 401)
+ r = requests.get(f"http://127.0.0.1:{tab.app.port}/close")
+ self.assertEqual(r.status_code, 401)
+
+ # 'Grouped' tests follow from here
+
+ def run_all_receive_mode_setup_tests(self, tab):
+ """Set up a share in Receive mode and start it"""
+ self.history_is_not_visible(tab)
+ self.click_toggle_history(tab)
+ self.history_is_visible(tab)
+ self.server_working_on_start_button_pressed(tab)
+ self.server_status_indicator_says_starting(tab)
+ self.server_is_started(tab)
+ self.web_server_is_running(tab)
+ self.have_a_password(tab)
+ self.url_description_shown(tab)
+ self.have_copy_url_button(tab)
+ self.server_status_indicator_says_started(tab)
+ self.web_page(tab, "Select the files you want to send, then click")
+
+ def run_all_receive_mode_tests(self, tab):
+ """Upload files in receive mode and stop the share"""
+ self.run_all_receive_mode_setup_tests(tab)
+ if not tab.settings.get("general", "public"):
+ self.try_without_auth_in_non_public_mode(tab)
+ self.upload_file(tab, self.tmpfile_test, "test.txt")
+ self.history_widgets_present(tab)
+ self.counter_incremented(tab, 1)
+ self.upload_file(tab, self.tmpfile_test, "test.txt")
+ self.counter_incremented(tab, 2)
+ self.upload_file(tab, self.tmpfile_test2, "test2.txt")
+ self.counter_incremented(tab, 3)
+ self.upload_file(tab, self.tmpfile_test2, "test2.txt")
+ self.counter_incremented(tab, 4)
+ # Test uploading the same file twice at the same time, and make sure no collisions
+ self.upload_file(tab, self.tmpfile_test, "test.txt", True)
+ self.counter_incremented(tab, 6)
+ self.history_indicator(tab, "2")
+ self.server_is_stopped(tab)
+ self.web_server_is_stopped(tab)
+ self.server_status_indicator_says_closed(tab)
+ self.server_working_on_start_button_pressed(tab)
+ self.server_is_started(tab)
+ self.history_indicator(tab, "2")
+
+ def run_all_clear_all_button_tests(self, tab):
+ """Test the Clear All history button"""
+ self.run_all_receive_mode_setup_tests(tab)
+ self.upload_file(tab, self.tmpfile_test, "test.txt")
+ self.history_widgets_present(tab)
+ self.clear_all_history_items(tab, 0)
+ self.upload_file(tab, self.tmpfile_test, "test.txt")
+ self.clear_all_history_items(tab, 2)
+
+ def run_all_upload_non_writable_dir_tests(self, tab):
+ """Test uploading a file when the data_dir is non-writable"""
+ upload_dir = os.path.join(self.tmpdir.name, "OnionShare")
+ shutil.rmtree(upload_dir, ignore_errors=True)
+ os.makedirs(upload_dir, 0o700)
+
+ # Set the upload dir setting
+ tab.get_mode().data_dir_lineedit.setText(upload_dir)
+ tab.settings.set("receive", "data_dir", upload_dir)
+
+ self.run_all_receive_mode_setup_tests(tab)
+ os.chmod(upload_dir, 0o400)
+ self.upload_file_should_fail(tab)
+ self.server_is_stopped(tab)
+ self.web_server_is_stopped(tab)
+ self.server_status_indicator_says_closed(tab)
+ os.chmod(upload_dir, 0o700)
+
+ # Tests
+
+ @pytest.mark.gui
+ def test_clear_all_button(self):
+ """
+ Clear all history items should work
+ """
+ tab = self.new_receive_tab()
+
+ self.run_all_common_setup_tests()
+ self.run_all_clear_all_button_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_autostop_timer(self):
+ """
+ Test autostop timer
+ """
+ tab = self.new_receive_tab()
+ tab.get_mode().mode_settings_widget.toggle_advanced_button.click()
+ tab.get_mode().mode_settings_widget.autostop_timer_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_receive_mode_setup_tests(tab)
+ self.set_timeout(tab, 5)
+ self.autostop_timer_widget_hidden(tab)
+ self.server_timed_out(tab, 15000)
+ self.web_server_is_stopped(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_upload(self):
+ """
+ Test uploading files
+ """
+ tab = self.new_receive_tab()
+
+ self.run_all_common_setup_tests()
+ self.run_all_receive_mode_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_upload_non_writable_dir(self):
+ """
+ Test uploading files to a non-writable directory
+ """
+ tab = self.new_receive_tab()
+
+ self.run_all_upload_non_writable_dir_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_public_upload(self):
+ """
+ Test uploading files in public mode
+ """
+ tab = self.new_receive_tab()
+ tab.get_mode().mode_settings_widget.public_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_receive_mode_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_public_upload_non_writable_dir(self):
+ """
+ Test uploading files to a non-writable directory in public mode
+ """
+ tab = self.new_receive_tab()
+ tab.get_mode().mode_settings_widget.public_checkbox.click()
+
+ self.run_all_upload_non_writable_dir_tests(tab)
+
+ self.close_all_tabs()
diff --git a/tests/test_gui_share.py b/tests/test_gui_share.py
new file mode 100644
index 00000000..387931ec
--- /dev/null
+++ b/tests/test_gui_share.py
@@ -0,0 +1,585 @@
+import pytest
+import os
+import requests
+import tempfile
+import zipfile
+
+from PyQt5 import QtCore, QtTest
+
+from .gui_base_test import GuiBaseTest
+
+
+class TestShare(GuiBaseTest):
+ # Shared test methods
+
+ def deleting_all_files_hides_delete_button(self, tab):
+ """Test that clicking on the file item shows the delete button. Test that deleting the only item in the list hides the delete button"""
+ rect = tab.get_mode().server_status.file_selection.file_list.visualItemRect(
+ tab.get_mode().server_status.file_selection.file_list.item(0)
+ )
+ QtTest.QTest.mouseClick(
+ tab.get_mode().server_status.file_selection.file_list.viewport(),
+ QtCore.Qt.LeftButton,
+ pos=rect.center(),
+ )
+ # Delete button should be visible
+ self.assertTrue(
+ tab.get_mode().server_status.file_selection.delete_button.isVisible()
+ )
+ # Click delete, delete button should still be visible since we have one more file
+ tab.get_mode().server_status.file_selection.delete_button.click()
+ rect = tab.get_mode().server_status.file_selection.file_list.visualItemRect(
+ tab.get_mode().server_status.file_selection.file_list.item(0)
+ )
+ QtTest.QTest.mouseClick(
+ tab.get_mode().server_status.file_selection.file_list.viewport(),
+ QtCore.Qt.LeftButton,
+ pos=rect.center(),
+ )
+ self.assertTrue(
+ tab.get_mode().server_status.file_selection.delete_button.isVisible()
+ )
+ tab.get_mode().server_status.file_selection.delete_button.click()
+
+ # No more files, the delete button should be hidden
+ self.assertFalse(
+ tab.get_mode().server_status.file_selection.delete_button.isVisible()
+ )
+
+ def add_a_file_and_delete_using_its_delete_widget(self, tab):
+ """Test that we can also delete a file by clicking on its [X] widget"""
+ num_files = tab.get_mode().server_status.file_selection.get_num_files()
+ tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[0])
+ tab.get_mode().server_status.file_selection.file_list.item(
+ 0
+ ).item_button.click()
+ self.file_selection_widget_has_files(tab, num_files)
+
+ def file_selection_widget_read_files(self, tab):
+ """Re-add some files to the list so we can share"""
+ num_files = tab.get_mode().server_status.file_selection.get_num_files()
+ tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[0])
+ tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[1])
+ self.file_selection_widget_has_files(tab, num_files + 2)
+
+ def download_share(self, tab):
+ """Test that we can download the share"""
+ url = f"http://127.0.0.1:{tab.app.port}/download"
+ if tab.settings.get("general", "public"):
+ r = requests.get(url)
+ else:
+ r = requests.get(
+ url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().server_status.web.password
+ ),
+ )
+
+ tmp_file = tempfile.NamedTemporaryFile()
+ with open(tmp_file.name, "wb") as f:
+ f.write(r.content)
+
+ zip = zipfile.ZipFile(tmp_file.name)
+ QtTest.QTest.qWait(50)
+ self.assertEqual("onionshare", zip.read("test.txt").decode("utf-8"))
+
+ QtTest.QTest.qWait(500)
+
+ def individual_file_is_viewable_or_not(self, tab):
+ """
+ Test that an individual file is viewable (when in autostop_sharing is false) or that it
+ isn't (when not in autostop_sharing is true)
+ """
+ url = f"http://127.0.0.1:{tab.app.port}"
+ download_file_url = f"http://127.0.0.1:{tab.app.port}/test.txt"
+ if tab.settings.get("general", "public"):
+ r = requests.get(url)
+ else:
+ r = requests.get(
+ url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().server_status.web.password
+ ),
+ )
+
+ if tab.settings.get("share", "autostop_sharing"):
+ self.assertFalse('a href="/test.txt"' in r.text)
+ if tab.settings.get("general", "public"):
+ r = requests.get(download_file_url)
+ else:
+ r = requests.get(
+ download_file_url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().server_status.web.password
+ ),
+ )
+ self.assertEqual(r.status_code, 404)
+ self.download_share(tab)
+ else:
+ self.assertTrue('a href="test.txt"' in r.text)
+ if tab.settings.get("general", "public"):
+ r = requests.get(download_file_url)
+ else:
+ r = requests.get(
+ download_file_url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().server_status.web.password
+ ),
+ )
+
+ tmp_file = tempfile.NamedTemporaryFile()
+ with open(tmp_file.name, "wb") as f:
+ f.write(r.content)
+
+ with open(tmp_file.name, "r") as f:
+ self.assertEqual("onionshare", f.read())
+
+ QtTest.QTest.qWait(500)
+
+ def hit_401(self, tab):
+ """Test that the server stops after too many 401s, or doesn't when in public mode"""
+ # In non-public mode, get ready to accept the dialog
+ if not tab.settings.get("general", "public"):
+
+ def accept_dialog():
+ window = tab.common.gui.qtapp.activeWindow()
+ if window:
+ window.close()
+
+ QtCore.QTimer.singleShot(1000, accept_dialog)
+
+ # Make 20 requests with guessed passwords
+ url = f"http://127.0.0.1:{tab.app.port}/"
+ for _ in range(20):
+ password_guess = self.gui.common.build_password()
+ requests.get(
+ url, auth=requests.auth.HTTPBasicAuth("onionshare", password_guess)
+ )
+
+ # In public mode, we should still be running (no rate-limiting)
+ if tab.settings.get("general", "public"):
+ self.web_server_is_running(tab)
+
+ # In non-public mode, we should be shut down (rate-limiting)
+ else:
+ self.web_server_is_stopped(tab)
+
+ def set_autostart_timer(self, tab, timer):
+ """Test that the timer can be set"""
+ schedule = QtCore.QDateTime.currentDateTime().addSecs(timer)
+ tab.get_mode().mode_settings_widget.autostart_timer_widget.setDateTime(schedule)
+ self.assertTrue(
+ tab.get_mode().mode_settings_widget.autostart_timer_widget.dateTime(),
+ schedule,
+ )
+
+ def autostart_timer_widget_hidden(self, tab):
+ """Test that the auto-start timer widget is hidden when share has started"""
+ self.assertFalse(
+ tab.get_mode().mode_settings_widget.autostart_timer_widget.isVisible()
+ )
+
+ def scheduled_service_started(self, tab, wait):
+ """Test that the server has timed out after the timer ran out"""
+ QtTest.QTest.qWait(wait)
+ # We should have started now
+ self.assertEqual(tab.get_mode().server_status.status, 2)
+
+ def cancel_the_share(self, tab):
+ """Test that we can cancel a share before it's started up """
+ self.server_working_on_start_button_pressed(tab)
+ self.server_status_indicator_says_scheduled(tab)
+ self.add_delete_buttons_hidden(tab)
+ self.mode_settings_widget_is_hidden(tab)
+ self.set_autostart_timer(tab, 10)
+ QtTest.QTest.mousePress(
+ tab.get_mode().server_status.server_button, QtCore.Qt.LeftButton
+ )
+ QtTest.QTest.qWait(100)
+ QtTest.QTest.mouseRelease(
+ tab.get_mode().server_status.server_button, QtCore.Qt.LeftButton
+ )
+ self.assertEqual(tab.get_mode().server_status.status, 0)
+ self.server_is_stopped(tab)
+ self.web_server_is_stopped(tab)
+
+ # Grouped tests follow from here
+
+ def run_all_share_mode_setup_tests(self, tab):
+ """Tests in share mode prior to starting a share"""
+ tab.get_mode().server_status.file_selection.file_list.add_file(
+ self.tmpfile_test
+ )
+ tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[0])
+ tab.get_mode().server_status.file_selection.file_list.add_file(self.tmpfiles[1])
+ self.file_selection_widget_has_files(tab, 3)
+ self.history_is_not_visible(tab)
+ self.click_toggle_history(tab)
+ self.history_is_visible(tab)
+ self.deleting_all_files_hides_delete_button(tab)
+ self.add_a_file_and_delete_using_its_delete_widget(tab)
+ self.file_selection_widget_read_files(tab)
+
+ def run_all_share_mode_started_tests(self, tab, startup_time=2000):
+ """Tests in share mode after starting a share"""
+ self.server_working_on_start_button_pressed(tab)
+ self.server_status_indicator_says_starting(tab)
+ self.add_delete_buttons_hidden(tab)
+ self.mode_settings_widget_is_hidden(tab)
+ self.server_is_started(tab, startup_time)
+ self.web_server_is_running(tab)
+ self.have_a_password(tab)
+ self.url_description_shown(tab)
+ self.have_copy_url_button(tab)
+ self.server_status_indicator_says_started(tab)
+
+ def run_all_share_mode_download_tests(self, tab):
+ """Tests in share mode after downloading a share"""
+ tab.get_mode().server_status.file_selection.file_list.add_file(
+ self.tmpfile_test
+ )
+ self.web_page(tab, "Total size")
+ self.download_share(tab)
+ self.history_widgets_present(tab)
+ self.server_is_stopped(tab)
+ self.web_server_is_stopped(tab)
+ self.server_status_indicator_says_closed(tab)
+ self.add_button_visible(tab)
+ self.server_working_on_start_button_pressed(tab)
+ self.toggle_indicator_is_reset(tab)
+ self.server_is_started(tab)
+ self.history_indicator(tab)
+
+ def run_all_share_mode_individual_file_download_tests(self, tab):
+ """Tests in share mode after downloading a share"""
+ self.web_page(tab, "Total size")
+ self.individual_file_is_viewable_or_not(tab)
+ self.history_widgets_present(tab)
+ self.server_is_stopped(tab)
+ self.web_server_is_stopped(tab)
+ self.server_status_indicator_says_closed(tab)
+ self.add_button_visible(tab)
+ self.server_working_on_start_button_pressed(tab)
+ self.server_is_started(tab)
+ self.history_indicator(tab)
+
+ def run_all_share_mode_tests(self, tab):
+ """End-to-end share tests"""
+ self.run_all_share_mode_setup_tests(tab)
+ self.run_all_share_mode_started_tests(tab)
+ self.run_all_share_mode_download_tests(tab)
+
+ def run_all_clear_all_button_tests(self, tab):
+ """Test the Clear All history button"""
+ self.run_all_share_mode_setup_tests(tab)
+ self.run_all_share_mode_started_tests(tab)
+ self.individual_file_is_viewable_or_not(tab)
+ self.history_widgets_present(tab)
+ self.clear_all_history_items(tab, 0)
+ self.individual_file_is_viewable_or_not(tab)
+ self.clear_all_history_items(tab, 2)
+
+ def run_all_share_mode_individual_file_tests(self, tab):
+ """Tests in share mode when viewing an individual file"""
+ self.run_all_share_mode_setup_tests(tab)
+ self.run_all_share_mode_started_tests(tab)
+ self.run_all_share_mode_individual_file_download_tests(tab)
+
+ # Tests
+
+ @pytest.mark.gui
+ def test_autostart_and_autostop_timer_mismatch(self):
+ """
+ If autostart timer is after autostop timer, a warning should be thrown
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.toggle_advanced_button.click()
+ tab.get_mode().mode_settings_widget.autostart_timer_checkbox.click()
+ tab.get_mode().mode_settings_widget.autostop_timer_checkbox.click()
+
+ def accept_dialog():
+ window = tab.common.gui.qtapp.activeWindow()
+ if window:
+ window.close()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_setup_tests(tab)
+ self.set_autostart_timer(tab, 15)
+ self.set_timeout(tab, 5)
+ QtCore.QTimer.singleShot(200, accept_dialog)
+ tab.get_mode().server_status.server_button.click()
+ self.server_is_stopped(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_autostart_timer(self):
+ """
+ Autostart timer should automatically start
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.toggle_advanced_button.click()
+ tab.get_mode().mode_settings_widget.autostart_timer_checkbox.click()
+
+ self.run_all_common_setup_tests()
+
+ self.run_all_share_mode_setup_tests(tab)
+ self.set_autostart_timer(tab, 2)
+ self.server_working_on_start_button_pressed(tab)
+ self.autostart_timer_widget_hidden(tab)
+ self.server_status_indicator_says_scheduled(tab)
+ self.web_server_is_stopped(tab)
+ self.scheduled_service_started(tab, 2200)
+ self.web_server_is_running(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_autostart_timer_too_short(self):
+ """
+ Autostart timer should throw a warning if the scheduled time is too soon
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.toggle_advanced_button.click()
+ tab.get_mode().mode_settings_widget.autostart_timer_checkbox.click()
+
+ def accept_dialog():
+ window = tab.common.gui.qtapp.activeWindow()
+ if window:
+ window.close()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_setup_tests(tab)
+ # Set a low timeout
+ self.set_autostart_timer(tab, 2)
+ QtTest.QTest.qWait(2200)
+ QtCore.QTimer.singleShot(200, accept_dialog)
+ tab.get_mode().server_status.server_button.click()
+ self.assertEqual(tab.get_mode().server_status.status, 0)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_autostart_timer_cancel(self):
+ """
+ Test canceling a scheduled share
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.toggle_advanced_button.click()
+ tab.get_mode().mode_settings_widget.autostart_timer_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_setup_tests(tab)
+ self.cancel_the_share(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_clear_all_button(self):
+ """
+ Test canceling a scheduled share
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().autostop_sharing_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_clear_all_button_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_public_mode(self):
+ """
+ Public mode shouldn't have a password
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.public_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_without_autostop_sharing(self):
+ """
+ Disable autostop sharing after first download
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().autostop_sharing_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_download(self):
+ """
+ Test downloading in share mode
+ """
+ tab = self.new_share_tab()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_individual_files_without_autostop_sharing(self):
+ """
+ Test downloading individual files with autostop sharing disabled
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().autostop_sharing_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_individual_file_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_individual_files(self):
+ """
+ Test downloading individual files
+ """
+ tab = self.new_share_tab()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_individual_file_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_large_download(self):
+ """
+ Test a large download
+ """
+ tab = self.new_share_tab()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_setup_tests(tab)
+ tab.get_mode().server_status.file_selection.file_list.add_file(
+ self.tmpfile_large
+ )
+ self.run_all_share_mode_started_tests(tab, startup_time=15000)
+ self.assertTrue(tab.get_mode().filesize_warning.isVisible())
+ self.download_share(tab)
+ self.server_is_stopped(tab)
+ self.web_server_is_stopped(tab)
+ self.server_status_indicator_says_closed(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_persistent_password(self):
+ """
+ Test a large download
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.persistent_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_setup_tests(tab)
+ self.run_all_share_mode_started_tests(tab)
+ password = tab.get_mode().server_status.web.password
+ self.run_all_share_mode_download_tests(tab)
+ self.run_all_share_mode_started_tests(tab)
+ self.assertEqual(tab.get_mode().server_status.web.password, password)
+ self.run_all_share_mode_download_tests(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_autostop_timer(self):
+ """
+ Test the autostop timer
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.toggle_advanced_button.click()
+ tab.get_mode().mode_settings_widget.autostop_timer_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_setup_tests(tab)
+ self.set_timeout(tab, 5)
+ self.run_all_share_mode_started_tests(tab)
+ self.autostop_timer_widget_hidden(tab)
+ self.server_timed_out(tab, 10000)
+ self.web_server_is_stopped(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_autostop_timer_too_short(self):
+ """
+ Test the autostop timer when the timeout is too short
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().mode_settings_widget.toggle_advanced_button.click()
+ tab.get_mode().mode_settings_widget.autostop_timer_checkbox.click()
+
+ def accept_dialog():
+ window = tab.common.gui.qtapp.activeWindow()
+ if window:
+ window.close()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_setup_tests(tab)
+ # Set a low timeout
+ self.set_timeout(tab, 2)
+ QtTest.QTest.qWait(2100)
+ QtCore.QTimer.singleShot(2200, accept_dialog)
+ tab.get_mode().server_status.server_button.click()
+ self.assertEqual(tab.get_mode().server_status.status, 0)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_unreadable_file(self):
+ """
+ Sharing an unreadable file should throw a warning
+ """
+ tab = self.new_share_tab()
+
+ def accept_dialog():
+ window = tab.common.gui.qtapp.activeWindow()
+ if window:
+ window.close()
+
+ self.run_all_share_mode_setup_tests(tab)
+ QtCore.QTimer.singleShot(200, accept_dialog)
+ tab.get_mode().server_status.file_selection.file_list.add_file(
+ "/tmp/nonexistent.txt"
+ )
+ self.file_selection_widget_has_files(tab, 3)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_401_triggers_ratelimit(self):
+ """
+ Rate limit should be triggered
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().autostop_sharing_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_tests(tab)
+ self.hit_401(tab)
+
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_401_public_skips_ratelimit(self):
+ """
+ Public mode should skip the rate limit
+ """
+ tab = self.new_share_tab()
+ tab.get_mode().autostop_sharing_checkbox.click()
+ tab.get_mode().mode_settings_widget.public_checkbox.click()
+
+ self.run_all_common_setup_tests()
+ self.run_all_share_mode_tests(tab)
+ self.hit_401(tab)
+
+ self.close_all_tabs()
diff --git a/tests/test_gui_tabs.py b/tests/test_gui_tabs.py
new file mode 100644
index 00000000..47a3d75d
--- /dev/null
+++ b/tests/test_gui_tabs.py
@@ -0,0 +1,227 @@
+import pytest
+import os
+
+from PyQt5 import QtCore, QtTest, QtWidgets
+
+from .gui_base_test import GuiBaseTest
+
+
+class TestTabs(GuiBaseTest):
+ # Shared test methods
+
+ def close_tab_with_active_server(self, tab):
+ # Start the server
+ self.assertEqual(
+ tab.get_mode().server_status.status,
+ tab.get_mode().server_status.STATUS_STOPPED,
+ )
+ tab.get_mode().server_status.server_button.click()
+ self.assertEqual(
+ tab.get_mode().server_status.status,
+ tab.get_mode().server_status.STATUS_WORKING,
+ )
+ QtTest.QTest.qWait(500)
+ self.assertEqual(
+ tab.get_mode().server_status.status,
+ tab.get_mode().server_status.STATUS_STARTED,
+ )
+
+ # Prepare to reject the dialog
+ QtCore.QTimer.singleShot(0, tab.close_dialog.reject_button.click)
+
+ # Close tab
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+
+ # The tab should still be open
+ self.assertFalse(tab.new_tab.isVisible())
+ self.assertTrue(tab.get_mode().isVisible())
+
+ # Prepare to accept the dialog
+ QtCore.QTimer.singleShot(0, tab.close_dialog.accept_button.click)
+
+ # Close tab
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+
+ # The tab should be closed
+ self.assertTrue(self.gui.tabs.widget(0).new_tab.isVisible())
+
+ def close_persistent_tab(self, tab):
+ # There shouldn't be a persistent settings file
+ self.assertFalse(os.path.exists(tab.settings.filename))
+
+ # Click the persistent checkbox
+ tab.get_mode().server_status.mode_settings_widget.persistent_checkbox.click()
+ QtTest.QTest.qWait(100)
+
+ # There should be a persistent settings file now
+ self.assertTrue(os.path.exists(tab.settings.filename))
+
+ # Prepare to reject the dialog
+ QtCore.QTimer.singleShot(0, tab.close_dialog.reject_button.click)
+
+ # Close tab
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+
+ # The tab should still be open
+ self.assertFalse(tab.new_tab.isVisible())
+ self.assertTrue(tab.get_mode().isVisible())
+
+ # There should be a persistent settings file still
+ self.assertTrue(os.path.exists(tab.settings.filename))
+
+ # Prepare to accept the dialog
+ QtCore.QTimer.singleShot(0, tab.close_dialog.accept_button.click)
+
+ # Close tab
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+
+ # The tab should be closed
+ self.assertTrue(self.gui.tabs.widget(0).new_tab.isVisible())
+
+ # The persistent settings file should be deleted
+ self.assertFalse(os.path.exists(tab.settings.filename))
+
+ # Tests
+
+ @pytest.mark.gui
+ def test_01_common_tests(self):
+ """Run all common tests"""
+ self.run_all_common_setup_tests()
+
+ @pytest.mark.gui
+ def test_02_starts_with_one_new_tab(self):
+ """There should be one "New Tab" tab open"""
+ self.assertEqual(self.gui.tabs.count(), 1)
+ self.assertTrue(self.gui.tabs.widget(0).new_tab.isVisible())
+
+ @pytest.mark.gui
+ def test_03_new_tab_button_opens_new_tabs(self):
+ """Clicking the "+" button should open new tabs"""
+ self.assertEqual(self.gui.tabs.count(), 1)
+ self.gui.tabs.new_tab_button.click()
+ self.gui.tabs.new_tab_button.click()
+ self.gui.tabs.new_tab_button.click()
+ self.assertEqual(self.gui.tabs.count(), 4)
+
+ @pytest.mark.gui
+ def test_04_close_tab_button_closes_tabs(self):
+ """Clicking the "x" button should close tabs"""
+ self.assertEqual(self.gui.tabs.count(), 4)
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+ self.assertEqual(self.gui.tabs.count(), 1)
+
+ @pytest.mark.gui
+ def test_05_closing_last_tab_opens_new_one(self):
+ """Closing the last tab should open a new tab"""
+ self.assertEqual(self.gui.tabs.count(), 1)
+
+ # Click share button
+ self.gui.tabs.widget(0).share_button.click()
+ self.assertFalse(self.gui.tabs.widget(0).new_tab.isVisible())
+ self.assertTrue(self.gui.tabs.widget(0).share_mode.isVisible())
+
+ # Close the tab
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+
+ # A new tab should be opened
+ self.assertEqual(self.gui.tabs.count(), 1)
+ self.assertTrue(self.gui.tabs.widget(0).new_tab.isVisible())
+
+ @pytest.mark.gui
+ def test_06_new_tab_mode_buttons_show_correct_modes(self):
+ """Clicking the mode buttons in a new tab should change the mode of the tab"""
+
+ # New tab, share files
+ self.gui.tabs.new_tab_button.click()
+ self.gui.tabs.widget(1).share_button.click()
+ self.assertFalse(self.gui.tabs.widget(1).new_tab.isVisible())
+ self.assertTrue(self.gui.tabs.widget(1).share_mode.isVisible())
+
+ # New tab, receive files
+ self.gui.tabs.new_tab_button.click()
+ self.gui.tabs.widget(2).receive_button.click()
+ self.assertFalse(self.gui.tabs.widget(2).new_tab.isVisible())
+ self.assertTrue(self.gui.tabs.widget(2).receive_mode.isVisible())
+
+ # New tab, publish website
+ self.gui.tabs.new_tab_button.click()
+ self.gui.tabs.widget(3).website_button.click()
+ self.assertFalse(self.gui.tabs.widget(3).new_tab.isVisible())
+ self.assertTrue(self.gui.tabs.widget(3).website_mode.isVisible())
+
+ # Close tabs
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+ self.gui.tabs.tabBar().tabButton(0, QtWidgets.QTabBar.RightSide).click()
+
+ @pytest.mark.gui
+ def test_07_close_share_tab_while_server_started_should_warn(self):
+ """Closing a share mode tab when the server is running should throw a warning"""
+ tab = self.new_share_tab_with_files()
+ self.close_tab_with_active_server(tab)
+
+ @pytest.mark.gui
+ def test_08_close_receive_tab_while_server_started_should_warn(self):
+ """Closing a recieve mode tab when the server is running should throw a warning"""
+ tab = self.new_receive_tab()
+ self.close_tab_with_active_server(tab)
+
+ @pytest.mark.gui
+ def test_09_close_website_tab_while_server_started_should_warn(self):
+ """Closing a website mode tab when the server is running should throw a warning"""
+ tab = self.new_website_tab_with_files()
+ self.close_tab_with_active_server(tab)
+
+ @pytest.mark.gui
+ def test_10_close_persistent_share_tab_shows_warning(self):
+ """Closing a share mode tab that's persistent should show a warning"""
+ tab = self.new_share_tab_with_files()
+ self.close_persistent_tab(tab)
+
+ @pytest.mark.gui
+ def test_11_close_persistent_receive_tab_shows_warning(self):
+ """Closing a receive mode tab that's persistent should show a warning"""
+ tab = self.new_receive_tab()
+ self.close_persistent_tab(tab)
+
+ @pytest.mark.gui
+ def test_12_close_persistent_website_tab_shows_warning(self):
+ """Closing a website mode tab that's persistent should show a warning"""
+ tab = self.new_website_tab_with_files()
+ self.close_persistent_tab(tab)
+
+ @pytest.mark.gui
+ def test_13_quit_with_server_started_should_warn(self):
+ """Quitting OnionShare with any active servers should show a warning"""
+ tab = self.new_share_tab()
+
+ # Start the server
+ self.assertEqual(
+ tab.get_mode().server_status.status,
+ tab.get_mode().server_status.STATUS_STOPPED,
+ )
+ tab.get_mode().server_status.server_button.click()
+ self.assertEqual(
+ tab.get_mode().server_status.status,
+ tab.get_mode().server_status.STATUS_WORKING,
+ )
+ QtTest.QTest.qWait(500)
+ self.assertEqual(
+ tab.get_mode().server_status.status,
+ tab.get_mode().server_status.STATUS_STARTED,
+ )
+
+ # Prepare to reject the dialog
+ QtCore.QTimer.singleShot(0, self.gui.close_dialog.reject_button.click)
+
+ # Close the window
+ self.gui.close()
+
+ # The window should still be open
+ self.assertTrue(self.gui.isVisible())
+
+ # Stop the server
+ tab.get_mode().server_status.server_button.click()
diff --git a/tests/test_gui_website.py b/tests/test_gui_website.py
new file mode 100644
index 00000000..c88a4910
--- /dev/null
+++ b/tests/test_gui_website.py
@@ -0,0 +1,106 @@
+import pytest
+import os
+import requests
+import shutil
+from datetime import datetime, timedelta
+
+from PyQt5 import QtCore, QtTest
+
+from .gui_base_test import GuiBaseTest
+
+
+class TestWebsite(GuiBaseTest):
+ # Shared test methods
+
+ def view_website(self, tab):
+ """Test that we can download the share"""
+ url = f"http://127.0.0.1:{tab.app.port}/"
+ if tab.settings.get("general", "public"):
+ r = requests.get(url)
+ else:
+ r = requests.get(
+ url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().server_status.web.password
+ ),
+ )
+
+ QtTest.QTest.qWait(500)
+ self.assertTrue("This is a test website hosted by OnionShare" in r.text)
+
+ def check_csp_header(self, tab):
+ """Test that the CSP header is present when enabled or vice versa"""
+ url = f"http://127.0.0.1:{tab.app.port}/"
+ if tab.settings.get("general", "public"):
+ r = requests.get(url)
+ else:
+ r = requests.get(
+ url,
+ auth=requests.auth.HTTPBasicAuth(
+ "onionshare", tab.get_mode().server_status.web.password
+ ),
+ )
+
+ QtTest.QTest.qWait(500)
+ if tab.settings.get("website", "disable_csp"):
+ self.assertFalse("Content-Security-Policy" in r.headers)
+ else:
+ self.assertTrue("Content-Security-Policy" in r.headers)
+
+ def run_all_website_mode_setup_tests(self, tab):
+ """Tests in website mode prior to starting a share"""
+ tab.get_mode().server_status.file_selection.file_list.add_file(
+ self.tmpfile_index_html
+ )
+ for filename in self.tmpfiles:
+ tab.get_mode().server_status.file_selection.file_list.add_file(filename)
+
+ self.file_selection_widget_has_files(tab, 11)
+ self.history_is_not_visible(tab)
+ self.click_toggle_history(tab)
+ self.history_is_visible(tab)
+
+ def run_all_website_mode_started_tests(self, tab, startup_time=500):
+ """Tests in website mode after starting a share"""
+ self.server_working_on_start_button_pressed(tab)
+ self.server_status_indicator_says_starting(tab)
+ self.add_delete_buttons_hidden(tab)
+ self.server_is_started(tab, startup_time)
+ self.web_server_is_running(tab)
+ self.have_a_password(tab)
+ self.url_description_shown(tab)
+ self.have_copy_url_button(tab)
+ self.server_status_indicator_says_started(tab)
+
+ def run_all_website_mode_download_tests(self, tab):
+ """Tests in website mode after viewing the site"""
+ self.run_all_website_mode_setup_tests(tab)
+ self.run_all_website_mode_started_tests(tab, startup_time=500)
+ self.view_website(tab)
+ self.check_csp_header(tab)
+ self.history_widgets_present(tab)
+ self.server_is_stopped(tab)
+ self.web_server_is_stopped(tab)
+ self.server_status_indicator_says_closed(tab)
+ self.add_button_visible(tab)
+
+ # Tests
+
+ @pytest.mark.gui
+ def test_website(self):
+ """
+ Test website mode
+ """
+ tab = self.new_website_tab()
+ self.run_all_website_mode_download_tests(tab)
+ self.close_all_tabs()
+
+ @pytest.mark.gui
+ def test_csp_enabled(self):
+ """
+ Test disabling CSP
+ """
+ tab = self.new_website_tab()
+ tab.get_mode().disable_csp_checkbox.click()
+ self.run_all_website_mode_download_tests(tab)
+ self.close_all_tabs()
diff --git a/tests/test_helpers.py b/tests/test_helpers.py
deleted file mode 100644
index 387fbf4a..00000000
--- a/tests/test_helpers.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""
-OnionShare | https://onionshare.org/
-
-Copyright (C) 2014-2018 Micah Lee <micah@micahflee.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""
-import tempfile
-import os
-
-
-class MockSubprocess:
- def __init__(self):
- self.last_call = None
-
- def call(self, args):
- self.last_call = args
-
- def last_call_args(self):
- return self.last_call
-
-
-def write_tempfile(text):
- path = os.path.join(tempfile.mkdtemp(), "/test-file.txt")
- with open(path, "w") as f:
- f.write(text)
- return path