Delete the old tests and replace them with the new tests

This commit is contained in:
Micah Lee 2019-11-10 13:55:15 -08:00
parent 05df88bf89
commit 16245d33e3
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
68 changed files with 32 additions and 3928 deletions

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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",
)

View File

@ -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")
)

View File

@ -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)

View File

@ -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()

View File

@ -3,6 +3,9 @@ import sys
# Force tests to look for resources in the source code tree # Force tests to look for resources in the source code tree
sys.onionshare_dev_mode = True 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 os
import shutil import shutil
import tempfile import tempfile
@ -12,6 +15,10 @@ import pytest
from onionshare import common, web, settings, strings from onionshare import common, web, settings, strings
# The temporary directory for CLI tests
test_temp_dir = None
def pytest_addoption(parser): def pytest_addoption(parser):
parser.addoption( parser.addoption(
"--rungui", action="store_true", default=False, help="run GUI tests" "--rungui", action="store_true", default=False, help="run GUI tests"
@ -38,51 +45,60 @@ def pytest_collection_modifyitems(config, items):
@pytest.fixture @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 """ Create a temporary directory that has a single file of a
particular size (1024 bytes). particular size (1024 bytes).
""" """
tmp_dir = tempfile.mkdtemp() new_temp_dir = tempfile.mkdtemp(dir=temp_dir)
tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) tmp_file, tmp_file_path = tempfile.mkstemp(dir=new_temp_dir)
with open(tmp_file, "wb") as f: with open(tmp_file, "wb") as f:
f.write(b"*" * 1024) f.write(b"*" * 1024)
return tmp_dir return new_temp_dir
# pytest > 2.9 only needs @pytest.fixture # pytest > 2.9 only needs @pytest.fixture
@pytest.yield_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 """ Create a temporary directory that has a single file of a
particular size (1024 bytes). The temporary directory (including particular size (1024 bytes). The temporary directory (including
the file inside) will be deleted after fixture usage. the file inside) will be deleted after fixture usage.
""" """
with tempfile.TemporaryDirectory() as tmp_dir: with tempfile.TemporaryDirectory(dir=temp_dir) as new_temp_dir:
tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) tmp_file, tmp_file_path = tempfile.mkstemp(dir=new_temp_dir)
with open(tmp_file, "wb") as f: with open(tmp_file, "wb") as f:
f.write(b"*" * 1024) f.write(b"*" * 1024)
yield tmp_dir yield new_temp_dir
@pytest.fixture @pytest.fixture
def temp_file_1024(): def temp_file_1024(temp_dir):
""" Create a temporary file of a particular size (1024 bytes). """ """ 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) tmp_file.write(b"*" * 1024)
return tmp_file.name return tmp_file.name
# pytest > 2.9 only needs @pytest.fixture # pytest > 2.9 only needs @pytest.fixture
@pytest.yield_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). Create a temporary file of a particular size (1024 bytes).
The temporary file will be deleted after fixture usage. 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.write(b"*" * 1024)
tmp_file.flush() tmp_file.flush()
yield tmp_file.name yield tmp_file.name
@ -108,7 +124,10 @@ def default_zw():
yield zw yield zw
zw.close() zw.close()
tmp_dir = os.path.dirname(zw.zip_filename) tmp_dir = os.path.dirname(zw.zip_filename)
shutil.rmtree(tmp_dir) try:
shutil.rmtree(tmp_dir, ignore_errors=True)
except:
pass
@pytest.fixture @pytest.fixture

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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 == []

View File

@ -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)

View File

@ -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"
)

View File

@ -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)

View File

@ -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"

View File

View File

@ -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)