mirror of
https://github.com/onionshare/onionshare.git
synced 2024-12-26 15:59:48 -05:00
Delete the old tests and replace them with the new tests
This commit is contained in:
parent
05df88bf89
commit
16245d33e3
@ -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()
|
@ -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)
|
@ -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)
|
@ -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)
|
@ -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",
|
||||
)
|
@ -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")
|
||||
)
|
@ -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)
|
@ -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()
|
@ -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
|
||||
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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
|
@ -1,75 +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 os
|
||||
|
||||
import pytest
|
||||
|
||||
from onionshare import OnionShare
|
||||
from onionshare.common import Common
|
||||
from onionshare.mode_settings import ModeSettings
|
||||
|
||||
|
||||
class MyOnion:
|
||||
def __init__(self):
|
||||
self.auth_string = "TestHidServAuth"
|
||||
self.private_key = ""
|
||||
self.scheduled_key = None
|
||||
|
||||
@staticmethod
|
||||
def start_onion_service(self, await_publication=True, save_scheduled_key=False):
|
||||
return "test_service_id.onion"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def onionshare_obj():
|
||||
common = Common()
|
||||
return OnionShare(common, MyOnion())
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mode_settings_obj():
|
||||
common = Common()
|
||||
return ModeSettings(common)
|
||||
|
||||
|
||||
class TestOnionShare:
|
||||
def test_init(self, onionshare_obj):
|
||||
assert onionshare_obj.hidserv_dir is None
|
||||
assert onionshare_obj.onion_host is None
|
||||
assert onionshare_obj.cleanup_filenames == []
|
||||
assert onionshare_obj.local_only is False
|
||||
|
||||
def test_start_onion_service(self, onionshare_obj, mode_settings_obj):
|
||||
onionshare_obj.start_onion_service(mode_settings_obj)
|
||||
assert 17600 <= onionshare_obj.port <= 17650
|
||||
assert onionshare_obj.onion_host == "test_service_id.onion"
|
||||
|
||||
def test_start_onion_service_local_only(self, onionshare_obj, mode_settings_obj):
|
||||
onionshare_obj.local_only = True
|
||||
onionshare_obj.start_onion_service(mode_settings_obj)
|
||||
assert onionshare_obj.onion_host == "127.0.0.1:{}".format(onionshare_obj.port)
|
||||
|
||||
def test_cleanup(self, onionshare_obj, temp_dir_1024, temp_file_1024):
|
||||
onionshare_obj.cleanup_filenames = [temp_dir_1024, temp_file_1024]
|
||||
onionshare_obj.cleanup()
|
||||
|
||||
assert os.path.exists(temp_dir_1024) is False
|
||||
assert os.path.exists(temp_dir_1024) is False
|
||||
assert onionshare_obj.cleanup_filenames == []
|
@ -1,312 +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 contextlib
|
||||
import inspect
|
||||
import io
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
import pytest
|
||||
|
||||
LOG_MSG_REGEX = re.compile(
|
||||
r"""
|
||||
^\[Jun\ 06\ 2013\ 11:05:00\]
|
||||
\ TestModule\.<function\ TestLog\.test_output\.<locals>\.dummy_func
|
||||
\ at\ 0x[a-f0-9]+>(:\ TEST_MSG)?$""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
PASSWORD_REGEX = re.compile(r"^([a-z]+)(-[a-z]+)?-([a-z]+)(-[a-z]+)?$")
|
||||
|
||||
|
||||
# TODO: Improve the Common tests to test it all as a single class
|
||||
|
||||
|
||||
class TestBuildPassword:
|
||||
@pytest.mark.parametrize(
|
||||
"test_input,expected",
|
||||
(
|
||||
# VALID, two lowercase words, separated by a hyphen
|
||||
("syrup-enzyme", True),
|
||||
("caution-friday", True),
|
||||
# VALID, two lowercase words, with one hyphenated compound word
|
||||
("drop-down-thimble", True),
|
||||
("unmixed-yo-yo", True),
|
||||
# VALID, two lowercase hyphenated compound words, separated by hyphen
|
||||
("yo-yo-drop-down", True),
|
||||
("felt-tip-t-shirt", True),
|
||||
("hello-world", True),
|
||||
# INVALID
|
||||
("Upper-Case", False),
|
||||
("digits-123", False),
|
||||
("too-many-hyphens-", False),
|
||||
("symbols-!@#$%", False),
|
||||
),
|
||||
)
|
||||
def test_build_password_regex(self, test_input, expected):
|
||||
""" Test that `PASSWORD_REGEX` accounts for the following patterns
|
||||
|
||||
There are a few hyphenated words in `wordlist.txt`:
|
||||
* drop-down
|
||||
* felt-tip
|
||||
* t-shirt
|
||||
* yo-yo
|
||||
|
||||
These words cause a few extra potential password patterns:
|
||||
* word-word
|
||||
* hyphenated-word-word
|
||||
* word-hyphenated-word
|
||||
* hyphenated-word-hyphenated-word
|
||||
"""
|
||||
|
||||
assert bool(PASSWORD_REGEX.match(test_input)) == expected
|
||||
|
||||
def test_build_password_unique(self, common_obj, sys_onionshare_dev_mode):
|
||||
assert common_obj.build_password() != common_obj.build_password()
|
||||
|
||||
|
||||
class TestDirSize:
|
||||
def test_temp_dir_size(self, common_obj, temp_dir_1024_delete):
|
||||
""" dir_size() should return the total size (in bytes) of all files
|
||||
in a particular directory.
|
||||
"""
|
||||
|
||||
assert common_obj.dir_size(temp_dir_1024_delete) == 1024
|
||||
|
||||
|
||||
class TestEstimatedTimeRemaining:
|
||||
@pytest.mark.parametrize(
|
||||
"test_input,expected",
|
||||
(
|
||||
((2, 676, 12), "8h14m16s"),
|
||||
((14, 1049, 30), "1h26m15s"),
|
||||
((21, 450, 1), "33m42s"),
|
||||
((31, 1115, 80), "11m39s"),
|
||||
((336, 989, 32), "2m12s"),
|
||||
((603, 949, 38), "36s"),
|
||||
((971, 1009, 83), "1s"),
|
||||
),
|
||||
)
|
||||
def test_estimated_time_remaining(
|
||||
self, common_obj, test_input, expected, time_time_100
|
||||
):
|
||||
assert common_obj.estimated_time_remaining(*test_input) == expected
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_input",
|
||||
(
|
||||
(10, 20, 100), # if `time_elapsed == 0`
|
||||
(0, 37, 99), # if `download_rate == 0`
|
||||
),
|
||||
)
|
||||
def test_raises_zero_division_error(self, common_obj, test_input, time_time_100):
|
||||
with pytest.raises(ZeroDivisionError):
|
||||
common_obj.estimated_time_remaining(*test_input)
|
||||
|
||||
|
||||
class TestFormatSeconds:
|
||||
@pytest.mark.parametrize(
|
||||
"test_input,expected",
|
||||
(
|
||||
(0, "0s"),
|
||||
(26, "26s"),
|
||||
(60, "1m"),
|
||||
(947.35, "15m47s"),
|
||||
(1847, "30m47s"),
|
||||
(2193.94, "36m34s"),
|
||||
(3600, "1h"),
|
||||
(13426.83, "3h43m47s"),
|
||||
(16293, "4h31m33s"),
|
||||
(18392.14, "5h6m32s"),
|
||||
(86400, "1d"),
|
||||
(129674, "1d12h1m14s"),
|
||||
(56404.12, "15h40m4s"),
|
||||
),
|
||||
)
|
||||
def test_format_seconds(self, common_obj, test_input, expected):
|
||||
assert common_obj.format_seconds(test_input) == expected
|
||||
|
||||
# TODO: test negative numbers?
|
||||
@pytest.mark.parametrize("test_input", ("string", lambda: None, [], {}, set()))
|
||||
def test_invalid_input_types(self, common_obj, test_input):
|
||||
with pytest.raises(TypeError):
|
||||
common_obj.format_seconds(test_input)
|
||||
|
||||
|
||||
class TestGetAvailablePort:
|
||||
@pytest.mark.parametrize(
|
||||
"port_min,port_max",
|
||||
((random.randint(1024, 1500), random.randint(1800, 2048)) for _ in range(50)),
|
||||
)
|
||||
def test_returns_an_open_port(self, common_obj, port_min, port_max):
|
||||
""" get_available_port() should return an open port within the range """
|
||||
|
||||
port = common_obj.get_available_port(port_min, port_max)
|
||||
assert port_min <= port <= port_max
|
||||
with socket.socket() as tmpsock:
|
||||
tmpsock.bind(("127.0.0.1", port))
|
||||
|
||||
|
||||
class TestGetPlatform:
|
||||
def test_darwin(self, platform_darwin, common_obj):
|
||||
assert common_obj.platform == "Darwin"
|
||||
|
||||
def test_linux(self, platform_linux, common_obj):
|
||||
assert common_obj.platform == "Linux"
|
||||
|
||||
def test_windows(self, platform_windows, common_obj):
|
||||
assert common_obj.platform == "Windows"
|
||||
|
||||
|
||||
# TODO: double-check these tests
|
||||
class TestGetResourcePath:
|
||||
def test_onionshare_dev_mode(self, common_obj, sys_onionshare_dev_mode):
|
||||
prefix = os.path.join(
|
||||
os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.abspath(inspect.getfile(inspect.currentframe()))
|
||||
)
|
||||
),
|
||||
"share",
|
||||
)
|
||||
assert common_obj.get_resource_path(
|
||||
os.path.join(prefix, "test_filename")
|
||||
) == os.path.join(prefix, "test_filename")
|
||||
|
||||
def test_linux(self, common_obj, platform_linux, sys_argv_sys_prefix):
|
||||
prefix = os.path.join(sys.prefix, "share/onionshare")
|
||||
assert common_obj.get_resource_path(
|
||||
os.path.join(prefix, "test_filename")
|
||||
) == os.path.join(prefix, "test_filename")
|
||||
|
||||
def test_frozen_darwin(self, common_obj, platform_darwin, sys_frozen, sys_meipass):
|
||||
prefix = os.path.join(sys._MEIPASS, "share")
|
||||
assert common_obj.get_resource_path(
|
||||
os.path.join(prefix, "test_filename")
|
||||
) == os.path.join(prefix, "test_filename")
|
||||
|
||||
|
||||
class TestGetTorPaths:
|
||||
# @pytest.mark.skipif(sys.platform != 'Darwin', reason='requires MacOS') ?
|
||||
def test_get_tor_paths_darwin(
|
||||
self, platform_darwin, common_obj, sys_frozen, sys_meipass
|
||||
):
|
||||
base_path = os.path.dirname(
|
||||
os.path.dirname(os.path.dirname(common_obj.get_resource_path("")))
|
||||
)
|
||||
tor_path = os.path.join(base_path, "Resources", "Tor", "tor")
|
||||
tor_geo_ip_file_path = os.path.join(base_path, "Resources", "Tor", "geoip")
|
||||
tor_geo_ipv6_file_path = os.path.join(base_path, "Resources", "Tor", "geoip6")
|
||||
obfs4proxy_file_path = os.path.join(base_path, "Resources", "Tor", "obfs4proxy")
|
||||
assert common_obj.get_tor_paths() == (
|
||||
tor_path,
|
||||
tor_geo_ip_file_path,
|
||||
tor_geo_ipv6_file_path,
|
||||
obfs4proxy_file_path,
|
||||
)
|
||||
|
||||
# @pytest.mark.skipif(sys.platform != 'Linux', reason='requires Linux') ?
|
||||
def test_get_tor_paths_linux(self, platform_linux, common_obj):
|
||||
assert common_obj.get_tor_paths() == (
|
||||
"/usr/bin/tor",
|
||||
"/usr/share/tor/geoip",
|
||||
"/usr/share/tor/geoip6",
|
||||
"/usr/bin/obfs4proxy",
|
||||
)
|
||||
|
||||
# @pytest.mark.skipif(sys.platform != 'Windows', reason='requires Windows') ?
|
||||
def test_get_tor_paths_windows(self, platform_windows, common_obj, sys_frozen):
|
||||
base_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(common_obj.get_resource_path(""))), "tor"
|
||||
)
|
||||
tor_path = os.path.join(os.path.join(base_path, "Tor"), "tor.exe")
|
||||
obfs4proxy_file_path = os.path.join(
|
||||
os.path.join(base_path, "Tor"), "obfs4proxy.exe"
|
||||
)
|
||||
tor_geo_ip_file_path = os.path.join(
|
||||
os.path.join(os.path.join(base_path, "Data"), "Tor"), "geoip"
|
||||
)
|
||||
tor_geo_ipv6_file_path = os.path.join(
|
||||
os.path.join(os.path.join(base_path, "Data"), "Tor"), "geoip6"
|
||||
)
|
||||
assert common_obj.get_tor_paths() == (
|
||||
tor_path,
|
||||
tor_geo_ip_file_path,
|
||||
tor_geo_ipv6_file_path,
|
||||
obfs4proxy_file_path,
|
||||
)
|
||||
|
||||
|
||||
class TestHumanReadableFilesize:
|
||||
@pytest.mark.parametrize(
|
||||
"test_input,expected",
|
||||
(
|
||||
(1024 ** 0, "1.0 B"),
|
||||
(1024 ** 1, "1.0 KiB"),
|
||||
(1024 ** 2, "1.0 MiB"),
|
||||
(1024 ** 3, "1.0 GiB"),
|
||||
(1024 ** 4, "1.0 TiB"),
|
||||
(1024 ** 5, "1.0 PiB"),
|
||||
(1024 ** 6, "1.0 EiB"),
|
||||
(1024 ** 7, "1.0 ZiB"),
|
||||
(1024 ** 8, "1.0 YiB"),
|
||||
),
|
||||
)
|
||||
def test_human_readable_filesize(self, common_obj, test_input, expected):
|
||||
assert common_obj.human_readable_filesize(test_input) == expected
|
||||
|
||||
|
||||
class TestLog:
|
||||
@pytest.mark.parametrize(
|
||||
"test_input",
|
||||
(
|
||||
(
|
||||
"[Jun 06 2013 11:05:00]"
|
||||
" TestModule.<function TestLog.test_output.<locals>.dummy_func"
|
||||
" at 0xdeadbeef>"
|
||||
),
|
||||
(
|
||||
"[Jun 06 2013 11:05:00]"
|
||||
" TestModule.<function TestLog.test_output.<locals>.dummy_func"
|
||||
" at 0xdeadbeef>: TEST_MSG"
|
||||
),
|
||||
),
|
||||
)
|
||||
def test_log_msg_regex(self, test_input):
|
||||
assert bool(LOG_MSG_REGEX.match(test_input))
|
||||
|
||||
def test_output(self, common_obj, time_strftime):
|
||||
def dummy_func():
|
||||
pass
|
||||
|
||||
common_obj.verbose = True
|
||||
|
||||
# From: https://stackoverflow.com/questions/1218933
|
||||
with io.StringIO() as buf, contextlib.redirect_stdout(buf):
|
||||
common_obj.log("TestModule", dummy_func)
|
||||
common_obj.log("TestModule", dummy_func, "TEST_MSG")
|
||||
output = buf.getvalue()
|
||||
|
||||
line_one, line_two, _ = output.split("\n")
|
||||
assert LOG_MSG_REGEX.match(line_one)
|
||||
assert LOG_MSG_REGEX.match(line_two)
|
@ -1,166 +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 json
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
|
||||
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"
|
||||
return settings.Settings(_common)
|
||||
|
||||
|
||||
class TestSettings:
|
||||
def test_init(self, settings_obj):
|
||||
expected_settings = {
|
||||
"version": "DUMMY_VERSION_1.2.3",
|
||||
"connection_type": "bundled",
|
||||
"control_port_address": "127.0.0.1",
|
||||
"control_port_port": 9051,
|
||||
"socks_address": "127.0.0.1",
|
||||
"socks_port": 9050,
|
||||
"socket_file_path": "/var/run/tor/control",
|
||||
"auth_type": "no_auth",
|
||||
"auth_password": "",
|
||||
"use_autoupdate": True,
|
||||
"autoupdate_timestamp": None,
|
||||
"no_bridges": True,
|
||||
"tor_bridges_use_obfs4": False,
|
||||
"tor_bridges_use_meek_lite_azure": False,
|
||||
"tor_bridges_use_custom_bridges": "",
|
||||
"persistent_tabs": [],
|
||||
}
|
||||
for key in settings_obj._settings:
|
||||
# Skip locale, it will not always default to the same thing
|
||||
if key != "locale":
|
||||
assert settings_obj._settings[key] == settings_obj.default_settings[key]
|
||||
assert settings_obj._settings[key] == expected_settings[key]
|
||||
|
||||
def test_fill_in_defaults(self, settings_obj):
|
||||
del settings_obj._settings["version"]
|
||||
settings_obj.fill_in_defaults()
|
||||
assert settings_obj._settings["version"] == "DUMMY_VERSION_1.2.3"
|
||||
|
||||
def test_load(self, settings_obj):
|
||||
custom_settings = {
|
||||
"version": "CUSTOM_VERSION",
|
||||
"socks_port": 9999,
|
||||
"use_stealth": True,
|
||||
}
|
||||
tmp_file, tmp_file_path = tempfile.mkstemp()
|
||||
with open(tmp_file, "w") as f:
|
||||
json.dump(custom_settings, f)
|
||||
settings_obj.filename = tmp_file_path
|
||||
settings_obj.load()
|
||||
|
||||
assert settings_obj._settings["version"] == "CUSTOM_VERSION"
|
||||
assert settings_obj._settings["socks_port"] == 9999
|
||||
assert settings_obj._settings["use_stealth"] is True
|
||||
|
||||
os.remove(tmp_file_path)
|
||||
assert os.path.exists(tmp_file_path) is False
|
||||
|
||||
def test_save(self, monkeypatch, settings_obj):
|
||||
monkeypatch.setattr(strings, "_", lambda _: "")
|
||||
|
||||
settings_filename = "default_settings.json"
|
||||
tmp_dir = tempfile.gettempdir()
|
||||
settings_path = os.path.join(tmp_dir, settings_filename)
|
||||
settings_obj.filename = settings_path
|
||||
settings_obj.save()
|
||||
with open(settings_path, "r") as f:
|
||||
settings = json.load(f)
|
||||
|
||||
assert settings_obj._settings == settings
|
||||
|
||||
os.remove(settings_path)
|
||||
assert os.path.exists(settings_path) is False
|
||||
|
||||
def test_get(self, settings_obj):
|
||||
assert settings_obj.get("version") == "DUMMY_VERSION_1.2.3"
|
||||
assert settings_obj.get("connection_type") == "bundled"
|
||||
assert settings_obj.get("control_port_address") == "127.0.0.1"
|
||||
assert settings_obj.get("control_port_port") == 9051
|
||||
assert settings_obj.get("socks_address") == "127.0.0.1"
|
||||
assert settings_obj.get("socks_port") == 9050
|
||||
assert settings_obj.get("socket_file_path") == "/var/run/tor/control"
|
||||
assert settings_obj.get("auth_type") == "no_auth"
|
||||
assert settings_obj.get("auth_password") == ""
|
||||
assert settings_obj.get("use_autoupdate") is True
|
||||
assert settings_obj.get("autoupdate_timestamp") is None
|
||||
assert settings_obj.get("autoupdate_timestamp") is None
|
||||
assert settings_obj.get("no_bridges") is True
|
||||
assert settings_obj.get("tor_bridges_use_obfs4") is False
|
||||
assert settings_obj.get("tor_bridges_use_meek_lite_azure") is False
|
||||
assert settings_obj.get("tor_bridges_use_custom_bridges") == ""
|
||||
|
||||
def test_set_version(self, settings_obj):
|
||||
settings_obj.set("version", "CUSTOM_VERSION")
|
||||
assert settings_obj._settings["version"] == "CUSTOM_VERSION"
|
||||
|
||||
def test_set_control_port_port(self, settings_obj):
|
||||
settings_obj.set("control_port_port", 999)
|
||||
assert settings_obj._settings["control_port_port"] == 999
|
||||
|
||||
settings_obj.set("control_port_port", "NON_INTEGER")
|
||||
assert settings_obj._settings["control_port_port"] == 9051
|
||||
|
||||
def test_set_socks_port(self, settings_obj):
|
||||
settings_obj.set("socks_port", 888)
|
||||
assert settings_obj._settings["socks_port"] == 888
|
||||
|
||||
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):
|
||||
obj = settings.Settings(common.Common())
|
||||
assert (
|
||||
obj.filename == "~/Library/Application Support/OnionShare/onionshare.json"
|
||||
)
|
||||
|
||||
def test_filename_linux(self, monkeypatch, os_path_expanduser, 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"
|
||||
|
||||
def test_set_custom_bridge(self, settings_obj):
|
||||
settings_obj.set(
|
||||
"tor_bridges_use_custom_bridges",
|
||||
"Bridge 45.3.20.65:9050 21300AD88890A49C429A6CB9959CFD44490A8F6E",
|
||||
)
|
||||
assert (
|
||||
settings_obj._settings["tor_bridges_use_custom_bridges"]
|
||||
== "Bridge 45.3.20.65:9050 21300AD88890A49C429A6CB9959CFD44490A8F6E"
|
||||
)
|
@ -1,65 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
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 types
|
||||
|
||||
import pytest
|
||||
|
||||
from onionshare import strings
|
||||
from onionshare.settings import Settings
|
||||
|
||||
# # Stub get_resource_path so it finds the correct path while running tests
|
||||
# def get_resource_path(filename):
|
||||
# resources_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'share')
|
||||
# path = os.path.join(resources_dir, filename)
|
||||
# return path
|
||||
# common.get_resource_path = get_resource_path
|
||||
|
||||
|
||||
def test_underscore_is_function():
|
||||
assert callable(strings._) and isinstance(strings._, types.FunctionType)
|
||||
|
||||
|
||||
class TestLoadStrings:
|
||||
def test_load_strings_defaults_to_english(
|
||||
self, common_obj, locale_en, sys_onionshare_dev_mode
|
||||
):
|
||||
""" load_strings() loads English by default """
|
||||
common_obj.settings = Settings(common_obj)
|
||||
strings.load_strings(common_obj)
|
||||
assert strings._("preparing_files") == "Compressing files."
|
||||
|
||||
def test_load_strings_loads_other_languages(
|
||||
self, common_obj, locale_fr, sys_onionshare_dev_mode
|
||||
):
|
||||
""" load_strings() loads other languages in different locales """
|
||||
common_obj.settings = Settings(common_obj)
|
||||
common_obj.settings.set("locale", "fr")
|
||||
strings.load_strings(common_obj)
|
||||
assert strings._("preparing_files") == "Compression des fichiers."
|
||||
|
||||
def test_load_invalid_locale(
|
||||
self, common_obj, locale_invalid, sys_onionshare_dev_mode
|
||||
):
|
||||
""" load_strings() raises a KeyError for an invalid locale """
|
||||
with pytest.raises(KeyError):
|
||||
common_obj.settings = Settings(common_obj)
|
||||
common_obj.settings.set("locale", "XX")
|
||||
strings.load_strings(common_obj)
|
@ -1,241 +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 contextlib
|
||||
import inspect
|
||||
import io
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
import zipfile
|
||||
import tempfile
|
||||
import base64
|
||||
|
||||
import pytest
|
||||
from werkzeug.datastructures import Headers
|
||||
|
||||
from onionshare.common import Common
|
||||
from onionshare import strings
|
||||
from onionshare.web import Web
|
||||
from onionshare.settings import Settings
|
||||
from onionshare.mode_settings import ModeSettings
|
||||
|
||||
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):
|
||||
""" 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)
|
||||
mode_settings = ModeSettings(common_obj)
|
||||
web = Web(common_obj, False, mode_settings, mode)
|
||||
web.generate_password()
|
||||
web.running = True
|
||||
|
||||
web.app.testing = True
|
||||
|
||||
# Share mode
|
||||
if mode == "share":
|
||||
# Add files
|
||||
files = []
|
||||
for _ in range(num_files):
|
||||
with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
|
||||
tmp_file.write(b"*" * 1024)
|
||||
files.append(tmp_file.name)
|
||||
web.share_mode.set_file_info(files)
|
||||
# Receive mode
|
||||
else:
|
||||
pass
|
||||
|
||||
return web
|
||||
|
||||
|
||||
class TestWeb:
|
||||
def test_share_mode(self, common_obj):
|
||||
web = web_obj(common_obj, "share", 3)
|
||||
assert web.mode == "share"
|
||||
with web.app.test_client() as c:
|
||||
# Load / without auth
|
||||
res = c.get("/")
|
||||
res.get_data()
|
||||
assert res.status_code == 401
|
||||
|
||||
# Load / with invalid auth
|
||||
res = c.get("/", headers=self._make_auth_headers("invalid"))
|
||||
res.get_data()
|
||||
assert res.status_code == 401
|
||||
|
||||
# Load / with valid auth
|
||||
res = c.get("/", headers=self._make_auth_headers(web.password))
|
||||
res.get_data()
|
||||
assert res.status_code == 200
|
||||
|
||||
# Download
|
||||
res = c.get("/download", headers=self._make_auth_headers(web.password))
|
||||
res.get_data()
|
||||
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)
|
||||
web.settings.set("share", "autostop_sharing", True)
|
||||
|
||||
assert web.running == True
|
||||
|
||||
with web.app.test_client() as c:
|
||||
# Download the first time
|
||||
res = c.get("/download", headers=self._make_auth_headers(web.password))
|
||||
res.get_data()
|
||||
assert res.status_code == 200
|
||||
assert res.mimetype == "application/zip"
|
||||
|
||||
assert web.running == False
|
||||
|
||||
def test_share_mode_autostop_sharing_off(self, common_obj, temp_file_1024):
|
||||
web = web_obj(common_obj, "share", 3)
|
||||
web.settings.set("share", "autostop_sharing", False)
|
||||
|
||||
assert web.running == True
|
||||
|
||||
with web.app.test_client() as c:
|
||||
# Download the first time
|
||||
res = c.get("/download", headers=self._make_auth_headers(web.password))
|
||||
res.get_data()
|
||||
assert res.status_code == 200
|
||||
assert res.mimetype == "application/zip"
|
||||
assert web.running == True
|
||||
|
||||
def test_receive_mode(self, common_obj):
|
||||
web = web_obj(common_obj, "receive")
|
||||
assert web.mode == "receive"
|
||||
|
||||
with web.app.test_client() as c:
|
||||
# Load / without auth
|
||||
res = c.get("/")
|
||||
res.get_data()
|
||||
assert res.status_code == 401
|
||||
|
||||
# Load / with invalid auth
|
||||
res = c.get("/", headers=self._make_auth_headers("invalid"))
|
||||
res.get_data()
|
||||
assert res.status_code == 401
|
||||
|
||||
# Load / with valid auth
|
||||
res = c.get("/", headers=self._make_auth_headers(web.password))
|
||||
res.get_data()
|
||||
assert res.status_code == 200
|
||||
|
||||
def test_public_mode_on(self, common_obj):
|
||||
web = web_obj(common_obj, "receive")
|
||||
web.settings.set("general", "public", True)
|
||||
|
||||
with web.app.test_client() as c:
|
||||
# Loading / should work without auth
|
||||
res = c.get("/")
|
||||
data1 = res.get_data()
|
||||
assert res.status_code == 200
|
||||
|
||||
def test_public_mode_off(self, common_obj):
|
||||
web = web_obj(common_obj, "receive")
|
||||
web.settings.set("general", "public", False)
|
||||
|
||||
with web.app.test_client() as c:
|
||||
# Load / without auth
|
||||
res = c.get("/")
|
||||
res.get_data()
|
||||
assert res.status_code == 401
|
||||
|
||||
# But static resources should work without auth
|
||||
res = c.get(f"{web.static_url_path}/css/style.css")
|
||||
res.get_data()
|
||||
assert res.status_code == 200
|
||||
|
||||
# Load / with valid auth
|
||||
res = c.get("/", headers=self._make_auth_headers(web.password))
|
||||
res.get_data()
|
||||
assert res.status_code == 200
|
||||
|
||||
def _make_auth_headers(self, password):
|
||||
auth = base64.b64encode(b"onionshare:" + password.encode()).decode()
|
||||
h = Headers()
|
||||
h.add("Authorization", "Basic " + auth)
|
||||
return h
|
||||
|
||||
|
||||
class TestZipWriterDefault:
|
||||
@pytest.mark.parametrize(
|
||||
"test_input",
|
||||
(
|
||||
f"onionshare_{''.join(random.choice('abcdefghijklmnopqrstuvwxyz234567') for _ in range(6))}.zip"
|
||||
for _ in range(50)
|
||||
),
|
||||
)
|
||||
def test_default_zw_filename_regex(self, test_input):
|
||||
assert bool(DEFAULT_ZW_FILENAME_REGEX.match(test_input))
|
||||
|
||||
def test_zw_filename(self, default_zw):
|
||||
zw_filename = os.path.basename(default_zw.zip_filename)
|
||||
assert bool(DEFAULT_ZW_FILENAME_REGEX.match(zw_filename))
|
||||
|
||||
def test_zipfile_filename_matches_zipwriter_filename(self, default_zw):
|
||||
assert default_zw.z.filename == default_zw.zip_filename
|
||||
|
||||
def test_zipfile_allow_zip64(self, default_zw):
|
||||
assert default_zw.z._allowZip64 is True
|
||||
|
||||
def test_zipfile_mode(self, default_zw):
|
||||
assert default_zw.z.mode == "w"
|
||||
|
||||
def test_callback(self, default_zw):
|
||||
assert default_zw.processed_size_callback(None) is None
|
||||
|
||||
def test_add_file(self, default_zw, temp_file_1024_delete):
|
||||
default_zw.add_file(temp_file_1024_delete)
|
||||
zipfile_info = default_zw.z.getinfo(os.path.basename(temp_file_1024_delete))
|
||||
|
||||
assert zipfile_info.compress_type == zipfile.ZIP_DEFLATED
|
||||
assert zipfile_info.file_size == 1024
|
||||
|
||||
def test_add_directory(self, temp_dir_1024_delete, default_zw):
|
||||
previous_size = default_zw._size # size before adding directory
|
||||
default_zw.add_dir(temp_dir_1024_delete)
|
||||
assert default_zw._size == previous_size + 1024
|
||||
|
||||
|
||||
class TestZipWriterCustom:
|
||||
@pytest.mark.parametrize(
|
||||
"test_input",
|
||||
(
|
||||
Common.random_string(
|
||||
random.randint(2, 50), random.choice((None, random.randint(2, 50)))
|
||||
)
|
||||
for _ in range(50)
|
||||
),
|
||||
)
|
||||
def test_random_string_regex(self, test_input):
|
||||
assert bool(RANDOM_STR_REGEX.match(test_input))
|
||||
|
||||
def test_custom_filename(self, custom_zw):
|
||||
assert bool(RANDOM_STR_REGEX.match(custom_zw.zip_filename))
|
||||
|
||||
def test_custom_callback(self, custom_zw):
|
||||
assert custom_zw.processed_size_callback(None) == "custom_callback"
|
@ -1,208 +0,0 @@
|
||||
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
|
||||
|
||||
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"
|
||||
)
|
||||
parser.addoption(
|
||||
"--runtor", action="store_true", default=False, help="run tor tests"
|
||||
)
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(config, items):
|
||||
if not config.getoption("--runtor"):
|
||||
# --runtor given in cli: do not skip tor tests
|
||||
skip_tor = pytest.mark.skip(reason="need --runtor option to run")
|
||||
for item in items:
|
||||
if "tor" in item.keywords:
|
||||
item.add_marker(skip_tor)
|
||||
|
||||
if not config.getoption("--rungui"):
|
||||
# --rungui given in cli: do not skip GUI tests
|
||||
skip_gui = pytest.mark.skip(reason="need --rungui option to run")
|
||||
for item in items:
|
||||
if "gui" in item.keywords:
|
||||
item.add_marker(skip_gui)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
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).
|
||||
"""
|
||||
|
||||
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 new_temp_dir
|
||||
|
||||
|
||||
# pytest > 2.9 only needs @pytest.fixture
|
||||
@pytest.yield_fixture
|
||||
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(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 new_temp_dir
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def temp_file_1024(temp_dir):
|
||||
""" Create a temporary file of a particular size (1024 bytes). """
|
||||
|
||||
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(temp_dir):
|
||||
"""
|
||||
Create a temporary file of a particular size (1024 bytes).
|
||||
The temporary file will be deleted after fixture usage.
|
||||
"""
|
||||
|
||||
with tempfile.NamedTemporaryFile(dir=temp_dir) as tmp_file:
|
||||
tmp_file.write(b"*" * 1024)
|
||||
tmp_file.flush()
|
||||
yield tmp_file.name
|
||||
|
||||
|
||||
# pytest > 2.9 only needs @pytest.fixture
|
||||
@pytest.yield_fixture(scope="session")
|
||||
def custom_zw():
|
||||
zw = web.share_mode.ZipWriter(
|
||||
common.Common(),
|
||||
zip_filename=common.Common.random_string(4, 6),
|
||||
processed_size_callback=lambda _: "custom_callback",
|
||||
)
|
||||
yield zw
|
||||
zw.close()
|
||||
os.remove(zw.zip_filename)
|
||||
|
||||
|
||||
# pytest > 2.9 only needs @pytest.fixture
|
||||
@pytest.yield_fixture(scope="session")
|
||||
def default_zw():
|
||||
zw = web.share_mode.ZipWriter(common.Common())
|
||||
yield zw
|
||||
zw.close()
|
||||
tmp_dir = os.path.dirname(zw.zip_filename)
|
||||
try:
|
||||
shutil.rmtree(tmp_dir, ignore_errors=True)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def locale_en(monkeypatch):
|
||||
monkeypatch.setattr("locale.getdefaultlocale", lambda: ("en_US", "UTF-8"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def locale_fr(monkeypatch):
|
||||
monkeypatch.setattr("locale.getdefaultlocale", lambda: ("fr_FR", "UTF-8"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def locale_invalid(monkeypatch):
|
||||
monkeypatch.setattr("locale.getdefaultlocale", lambda: ("xx_XX", "UTF-8"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def locale_ru(monkeypatch):
|
||||
monkeypatch.setattr("locale.getdefaultlocale", lambda: ("ru_RU", "UTF-8"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def platform_darwin(monkeypatch):
|
||||
monkeypatch.setattr("platform.system", lambda: "Darwin")
|
||||
|
||||
|
||||
@pytest.fixture # (scope="session")
|
||||
def platform_linux(monkeypatch):
|
||||
monkeypatch.setattr("platform.system", lambda: "Linux")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def platform_windows(monkeypatch):
|
||||
monkeypatch.setattr("platform.system", lambda: "Windows")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sys_argv_sys_prefix(monkeypatch):
|
||||
monkeypatch.setattr("sys.argv", [sys.prefix])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sys_frozen(monkeypatch):
|
||||
monkeypatch.setattr("sys.frozen", True, raising=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sys_meipass(monkeypatch):
|
||||
monkeypatch.setattr("sys._MEIPASS", os.path.expanduser("~"), raising=False)
|
||||
|
||||
|
||||
@pytest.fixture # (scope="session")
|
||||
def sys_onionshare_dev_mode(monkeypatch):
|
||||
monkeypatch.setattr("sys.onionshare_dev_mode", True, raising=False)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def time_time_100(monkeypatch):
|
||||
monkeypatch.setattr("time.time", lambda: 100)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def time_strftime(monkeypatch):
|
||||
monkeypatch.setattr("time.strftime", lambda _: "Jun 06 2013 11:05:00")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def common_obj():
|
||||
return common.Common()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def settings_obj(sys_onionshare_dev_mode, platform_linux):
|
||||
_common = common.Common()
|
||||
_common.version = "DUMMY_VERSION_1.2.3"
|
||||
strings.load_strings(_common)
|
||||
return settings.Settings(_common)
|
Loading…
Reference in New Issue
Block a user