From 90ebc3aab424637dbb75017df6b0204b82d6fe69 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 9 Sep 2019 16:35:05 +1000 Subject: Fix the discrepancy between SendBaseModeWeb and Web objects' separate cur_history_id attibutes, ensuring that when we call web.error404() we send a new history_id integer for communicating back to the frontend. Add tests for this --- onionshare/web/send_base_mode.py | 5 ++++- onionshare/web/share_mode.py | 12 +++++++--- onionshare/web/web.py | 7 +----- onionshare_gui/mode/history.py | 10 ++++----- tests/GuiBaseTest.py | 4 ++++ tests/GuiReceiveTest.py | 9 ++++++++ tests/GuiShareTest.py | 9 ++++++++ ...nionshare_receive_mode_clear_all_button_test.py | 25 +++++++++++++++++++++ ..._onionshare_share_mode_clear_all_button_test.py | 26 ++++++++++++++++++++++ 9 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 tests/local_onionshare_receive_mode_clear_all_button_test.py create mode 100644 tests/local_onionshare_share_mode_clear_all_button_test.py diff --git a/onionshare/web/send_base_mode.py b/onionshare/web/send_base_mode.py index a6ad2307..67fb26d0 100644 --- a/onionshare/web/send_base_mode.py +++ b/onionshare/web/send_base_mode.py @@ -29,6 +29,9 @@ class SendBaseModeWeb: # one download at a time. self.download_in_progress = False + # This tracks the history id + self.cur_history_id = 0 + self.define_routes() self.init() @@ -264,4 +267,4 @@ class SendBaseModeWeb: """ Inherited class will implement this. """ - pass \ No newline at end of file + pass diff --git a/onionshare/web/share_mode.py b/onionshare/web/share_mode.py index c9d9b229..f52bc2c7 100644 --- a/onionshare/web/share_mode.py +++ b/onionshare/web/share_mode.py @@ -207,11 +207,15 @@ class ShareModeWeb(SendBaseModeWeb): if self.download_individual_files: return self.stream_individual_file(filesystem_path) else: - return self.web.error404() + history_id = self.cur_history_id + self.cur_history_id += 1 + return self.web.error404(history_id) # If it's not a directory or file, throw a 404 else: - return self.web.error404() + history_id = self.cur_history_id + self.cur_history_id += 1 + return self.web.error404(history_id) else: # Special case loading / @@ -223,7 +227,9 @@ class ShareModeWeb(SendBaseModeWeb): else: # If the path isn't found, throw a 404 - return self.web.error404() + history_id = self.cur_history_id + self.cur_history_id += 1 + return self.web.error404(history_id) def build_zipfile_list(self, filenames, processed_size_callback=None): self.common.log("ShareModeWeb", "build_zipfile_list") diff --git a/onionshare/web/web.py b/onionshare/web/web.py index 6cd30c93..2b0d2812 100644 --- a/onionshare/web/web.py +++ b/onionshare/web/web.py @@ -63,9 +63,6 @@ class Web: self.auth = HTTPBasicAuth() self.auth.error_handler(self.error401) - # This tracks the history id - self.cur_history_id = 0 - # Verbose mode? if self.common.verbose: self.verbose_mode() @@ -204,9 +201,7 @@ class Web: r = make_response(render_template('403.html', static_url_path=self.static_url_path), 403) return self.add_security_headers(r) - def error404(self): - history_id = self.cur_history_id - self.cur_history_id += 1 + def error404(self, history_id): self.add_request(self.REQUEST_INDIVIDUAL_FILE_STARTED, '{}'.format(request.path), { 'id': history_id, 'status_code': 404 diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index 5dad9614..b8baebd1 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -539,17 +539,17 @@ class History(QtWidgets.QWidget): # Header self.header_label = QtWidgets.QLabel(header_text) self.header_label.setStyleSheet(self.common.css['downloads_uploads_label']) - clear_button = QtWidgets.QPushButton(strings._('gui_all_modes_clear_history')) - clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) - clear_button.setFlat(True) - clear_button.clicked.connect(self.reset) + self.clear_button = QtWidgets.QPushButton(strings._('gui_all_modes_clear_history')) + self.clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) + self.clear_button.setFlat(True) + self.clear_button.clicked.connect(self.reset) header_layout = QtWidgets.QHBoxLayout() header_layout.addWidget(self.header_label) header_layout.addStretch() header_layout.addWidget(self.in_progress_label) header_layout.addWidget(self.completed_label) header_layout.addWidget(self.requests_label) - header_layout.addWidget(clear_button) + header_layout.addWidget(self.clear_button) # When there are no items self.empty_image = QtWidgets.QLabel() diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py index 4f087431..3e82769a 100644 --- a/tests/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -285,6 +285,10 @@ class GuiBaseTest(object): 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): diff --git a/tests/GuiReceiveTest.py b/tests/GuiReceiveTest.py index ef420ec2..80e05250 100644 --- a/tests/GuiReceiveTest.py +++ b/tests/GuiReceiveTest.py @@ -127,3 +127,12 @@ class GuiReceiveTest(GuiBaseTest): self.autostop_timer_widget_hidden(self.gui.receive_mode) self.server_timed_out(self.gui.receive_mode, 15000) self.web_server_is_stopped() + + def run_all_clear_all_button_tests(self, public_mode): + """Test the Clear All history button""" + self.run_all_receive_mode_setup_tests(public_mode) + self.upload_file(public_mode, '/tmp/test.txt', 'test.txt') + self.history_widgets_present(self.gui.receive_mode) + self.clear_all_history_items(self.gui.receive_mode, 0) + self.upload_file(public_mode, '/tmp/test.txt', 'test.txt') + self.clear_all_history_items(self.gui.receive_mode, 2) diff --git a/tests/GuiShareTest.py b/tests/GuiShareTest.py index 038f052b..6925defa 100644 --- a/tests/GuiShareTest.py +++ b/tests/GuiShareTest.py @@ -196,6 +196,15 @@ class GuiShareTest(GuiBaseTest): 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""" diff --git a/tests/local_onionshare_receive_mode_clear_all_button_test.py b/tests/local_onionshare_receive_mode_clear_all_button_test.py new file mode 100644 index 00000000..f93d4fe1 --- /dev/null +++ b/tests/local_onionshare_receive_mode_clear_all_button_test.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +import pytest +import unittest + +from .GuiReceiveTest import GuiReceiveTest + +class LocalReceiveModeClearAllButtonTest(unittest.TestCase, GuiReceiveTest): + @classmethod + def setUpClass(cls): + test_settings = { + } + cls.gui = GuiReceiveTest.set_up(test_settings) + + @classmethod + def tearDownClass(cls): + GuiReceiveTest.tear_down() + + @pytest.mark.gui + @pytest.mark.skipif(pytest.__version__ < '2.9', reason="requires newer pytest") + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_clear_all_button_tests(False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_share_mode_clear_all_button_test.py b/tests/local_onionshare_share_mode_clear_all_button_test.py new file mode 100644 index 00000000..caed342d --- /dev/null +++ b/tests/local_onionshare_share_mode_clear_all_button_test.py @@ -0,0 +1,26 @@ +#!/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() -- cgit v1.2.3-54-g00ecf