mirror of
https://github.com/onionshare/onionshare.git
synced 2024-12-28 00:39:37 -05:00
Merge branch '991_sharing_code' of github.com:mig5/onionshare into 991_sharing_code
This commit is contained in:
commit
f118ebcb09
@ -341,6 +341,37 @@ class ReceiveHistoryItem(HistoryItem):
|
||||
self.label.setText(self.get_canceled_label_text(self.started))
|
||||
|
||||
|
||||
class IndividualFileHistoryItem(HistoryItem):
|
||||
"""
|
||||
Individual file history item, for share mode viewing of individual files
|
||||
"""
|
||||
def __init__(self, common, path):
|
||||
super(IndividualFileHistoryItem, self).__init__()
|
||||
self.status = HistoryItem.STATUS_STARTED
|
||||
self.common = common
|
||||
|
||||
self.visited = time.time()
|
||||
self.visited_dt = datetime.fromtimestamp(self.visited)
|
||||
|
||||
# Labels
|
||||
self.timestamp_label = QtWidgets.QLabel(self.visited_dt.strftime("%b %d, %I:%M%p"))
|
||||
self.path_viewed_label = QtWidgets.QLabel(strings._('gui_individual_file_download').format(path))
|
||||
|
||||
# Layout
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
layout.addWidget(self.timestamp_label)
|
||||
layout.addWidget(self.path_viewed_label)
|
||||
self.setLayout(layout)
|
||||
|
||||
|
||||
def update(self):
|
||||
self.label.setText(self.get_finished_label_text(self.started_dt))
|
||||
self.status = HistoryItem.STATUS_FINISHED
|
||||
|
||||
def cancel(self):
|
||||
self.progress_bar.setFormat(strings._('gui_canceled'))
|
||||
self.status = HistoryItem.STATUS_CANCELED
|
||||
|
||||
class VisitHistoryItem(HistoryItem):
|
||||
"""
|
||||
Download history item, for share mode
|
||||
|
@ -28,7 +28,7 @@ from onionshare.web import Web
|
||||
from ..file_selection import FileSelection
|
||||
from .threads import CompressThread
|
||||
from .. import Mode
|
||||
from ..history import History, ToggleHistory, ShareHistoryItem
|
||||
from ..history import History, ToggleHistory, ShareHistoryItem, IndividualFileHistoryItem
|
||||
from ...widgets import Alert
|
||||
|
||||
|
||||
@ -230,6 +230,15 @@ class ShareMode(Mode):
|
||||
Handle REQUEST_LOAD event.
|
||||
"""
|
||||
self.system_tray.showMessage(strings._('systray_page_loaded_title'), strings._('systray_page_loaded_message'))
|
||||
if not self.common.settings.get('close_after_first_download') and not event["path"].startswith(('/favicon.ico', '/download', self.web.static_url_path)) and event["path"] != '/':
|
||||
|
||||
item = IndividualFileHistoryItem(self.common, event["path"])
|
||||
|
||||
self.history.add(0, item)
|
||||
self.toggle_history.update_indicator(True)
|
||||
self.history.completed_count += 1
|
||||
self.history.update_completed()
|
||||
self.system_tray.showMessage(strings._('systray_individual_file_downloaded_title'), strings._('systray_individual_file_downloaded_message').format(event["path"]))
|
||||
|
||||
def handle_request_started(self, event):
|
||||
"""
|
||||
|
@ -160,6 +160,8 @@
|
||||
"systray_receive_started_message": "Someone is sending files to you",
|
||||
"systray_website_started_title": "Starting sharing website",
|
||||
"systray_website_started_message": "Someone is visiting your website",
|
||||
"systray_individual_file_downloaded_title": "Individual file loaded",
|
||||
"systray_individual_file_downloaded_message": "Individual file {} viewed",
|
||||
"gui_all_modes_history": "History",
|
||||
"gui_all_modes_clear_history": "Clear All",
|
||||
"gui_all_modes_transfer_started": "Started {}",
|
||||
@ -176,6 +178,7 @@
|
||||
"gui_receive_mode_no_files": "No Files Received Yet",
|
||||
"gui_receive_mode_autostop_timer_waiting": "Waiting to finish receiving",
|
||||
"gui_visit_started": "Someone has visited your website {}",
|
||||
"gui_individual_file_download": "Viewed {}",
|
||||
"receive_mode_upload_starting": "Upload of total size {} is starting",
|
||||
"days_first_letter": "d",
|
||||
"hours_first_letter": "h",
|
||||
|
@ -14,6 +14,7 @@ from onionshare.web import Web
|
||||
from onionshare_gui import Application, OnionShare, OnionShareGui
|
||||
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):
|
||||
@ -103,6 +104,9 @@ class GuiBaseTest(object):
|
||||
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):
|
||||
@ -198,6 +202,9 @@ class GuiBaseTest(object):
|
||||
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'''
|
||||
@ -249,7 +256,7 @@ class GuiBaseTest(object):
|
||||
|
||||
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):
|
||||
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)
|
||||
|
||||
|
@ -81,6 +81,40 @@ class GuiShareTest(GuiBaseTest):
|
||||
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 = "http://127.0.0.1:{}".format(self.gui.app.port)
|
||||
download_file_url = "http://127.0.0.1:{}/test.txt".format(self.gui.app.port)
|
||||
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 = "http://127.0.0.1:{}/".format(self.gui.app.port)
|
||||
@ -101,11 +135,6 @@ class GuiShareTest(GuiBaseTest):
|
||||
self.web_server_is_stopped()
|
||||
|
||||
|
||||
def add_button_visible(self):
|
||||
'''Test that the add button should be visible'''
|
||||
self.assertTrue(self.gui.share_mode.server_status.file_selection.add_button.isVisible())
|
||||
|
||||
|
||||
# 'Grouped' tests follow from here
|
||||
|
||||
def run_all_share_mode_setup_tests(self):
|
||||
@ -142,11 +171,23 @@ class GuiShareTest(GuiBaseTest):
|
||||
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.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_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"""
|
||||
@ -155,6 +196,12 @@ class GuiShareTest(GuiBaseTest):
|
||||
self.run_all_share_mode_download_tests(public_mode, stay_open)
|
||||
|
||||
|
||||
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()
|
||||
|
100
tests/GuiWebsiteTest.py
Normal file
100
tests/GuiWebsiteTest.py
Normal file
@ -0,0 +1,100 @@
|
||||
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, OnionShareGui
|
||||
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 = OnionShareGui(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 = "http://127.0.0.1:{}/".format(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 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.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)
|
||||
|
@ -67,7 +67,7 @@ class TorGuiShareTest(TorGuiBaseTest, GuiShareTest):
|
||||
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.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)
|
||||
|
@ -0,0 +1,26 @@
|
||||
#!/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()
|
@ -0,0 +1,26 @@
|
||||
#!/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()
|
25
tests/local_onionshare_website_mode_test.py
Normal file
25
tests/local_onionshare_website_mode_test.py
Normal file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
import pytest
|
||||
import unittest
|
||||
|
||||
from .GuiWebsiteTest import GuiWebsiteTest
|
||||
|
||||
class LocalWebsiteModeTest(unittest.TestCase, GuiWebsiteTest):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
test_settings = {
|
||||
}
|
||||
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()
|
Loading…
Reference in New Issue
Block a user