Merge branch '991_sharing_code' of github.com:mig5/onionshare into 991_sharing_code

This commit is contained in:
Micah Lee 2019-09-02 19:46:05 -07:00
commit f118ebcb09
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
10 changed files with 283 additions and 9 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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