From 6797fa18abeb6204b8f50533b2ebd9a2f37d94a1 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 12:51:30 -0700 Subject: [PATCH 001/142] Refactor how Mode layouts work, so the downstream Mode has more control over the UI --- onionshare_gui/mode.py | 19 ++++++------------- onionshare_gui/receive_mode/__init__.py | 16 ++++++++++++---- onionshare_gui/share_mode/__init__.py | 14 +++++++++++--- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/onionshare_gui/mode.py b/onionshare_gui/mode.py index 6b156f7e..d91b2e64 100644 --- a/onionshare_gui/mode.py +++ b/onionshare_gui/mode.py @@ -72,24 +72,17 @@ class Mode(QtWidgets.QWidget): self.starting_server_step3.connect(self.start_server_step3) self.starting_server_error.connect(self.start_server_error) - # Primary action layout + # Primary action + # Note: It's up to the downstream Mode to add this to its layout self.primary_action_layout = QtWidgets.QVBoxLayout() self.primary_action_layout.addWidget(self.server_status) self.primary_action = QtWidgets.QWidget() self.primary_action.setLayout(self.primary_action_layout) - # Layout - self.layout = QtWidgets.QVBoxLayout() - self.layout.addWidget(self.primary_action) - # Hack to allow a minimum width on self.layout - min_width_widget = QtWidgets.QWidget() - min_width_widget.setMinimumWidth(450) - self.layout.addWidget(min_width_widget) - - self.horizontal_layout_wrapper = QtWidgets.QHBoxLayout() - self.horizontal_layout_wrapper.addLayout(self.layout) - - self.setLayout(self.horizontal_layout_wrapper) + # Hack to allow a minimum width on the main layout + # Note: It's up to the downstream Mode to add this to its layout + self.min_width_widget = QtWidgets.QWidget() + self.min_width_widget.setMinimumWidth(450) def init(self): """ diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index 590dec65..f2a82e54 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -76,11 +76,19 @@ class ReceiveMode(Mode): self.receive_info.setMinimumHeight(80) self.receive_info.setWordWrap(True) + # Main layout + self.main_layout = QtWidgets.QVBoxLayout() + self.main_layout.addWidget(self.info_widget) + self.main_layout.addWidget(self.receive_info) + self.main_layout.addWidget(self.primary_action) + self.main_layout.addStretch() + self.main_layout.addWidget(self.min_width_widget) + # Layout - self.layout.insertWidget(0, self.receive_info) - self.layout.insertWidget(0, self.info_widget) - self.layout.addStretch() - self.horizontal_layout_wrapper.addWidget(self.uploads) + self.layout = QtWidgets.QHBoxLayout() + self.layout.addLayout(self.main_layout) + self.layout.addWidget(self.uploads) + self.setLayout(self.layout) def get_stop_server_shutdown_timeout_text(self): """ diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index 90fce49a..8a937f1d 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -106,10 +106,18 @@ class ShareMode(Mode): # Status bar, zip progress bar self._zip_progress_bar = None + # Main layout + self.main_layout = QtWidgets.QVBoxLayout() + self.main_layout.addWidget(self.info_widget) + self.main_layout.addLayout(self.file_selection) + self.main_layout.addWidget(self.primary_action) + self.main_layout.addWidget(self.min_width_widget) + # Layout - self.layout.insertLayout(0, self.file_selection) - self.layout.insertWidget(0, self.info_widget) - self.horizontal_layout_wrapper.addWidget(self.downloads) + self.layout = QtWidgets.QHBoxLayout() + self.layout.addLayout(self.main_layout) + self.layout.addWidget(self.downloads) + self.setLayout(self.layout) # Always start with focus on file selection self.file_selection.setFocus() From b9409795c81a2a0d33e23383b5b91c669ab03b60 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 13:18:18 -0700 Subject: [PATCH 002/142] Hide the uploads and downloads by default, and make the mode switcher hide before showing, to prevent weird window resizing --- onionshare_gui/onionshare_gui.py | 3 +-- onionshare_gui/receive_mode/__init__.py | 1 + onionshare_gui/share_mode/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 83f3a7e0..79565edd 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -55,7 +55,6 @@ class OnionShareGui(QtWidgets.QMainWindow): self.setWindowTitle('OnionShare') self.setWindowIcon(QtGui.QIcon(self.common.get_resource_path('images/logo.png'))) - self.setMinimumWidth(850) # Load settings self.config = config @@ -194,8 +193,8 @@ class OnionShareGui(QtWidgets.QMainWindow): self.share_mode_button.setStyleSheet(self.common.css['mode_switcher_selected_style']) self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) - self.share_mode.show() self.receive_mode.hide() + self.share_mode.show() else: self.share_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_selected_style']) diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index f2a82e54..80bd9cad 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -48,6 +48,7 @@ class ReceiveMode(Mode): # Uploads self.uploads = Uploads(self.common) + self.uploads.hide() self.uploads_in_progress = 0 self.uploads_completed = 0 self.new_upload = False # For scrolling to the bottom of the uploads list diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index 8a937f1d..c097d75a 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -72,6 +72,7 @@ class ShareMode(Mode): # Downloads self.downloads = Downloads(self.common) + self.downloads.hide() self.downloads_in_progress = 0 self.downloads_completed = 0 @@ -96,7 +97,6 @@ class ShareMode(Mode): self.info_widget = QtWidgets.QWidget() self.info_widget.setLayout(self.info_layout) - self.info_widget.hide() # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) From ea30b49269039cff00b441677d1ce837f2d8eafd Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 13:24:44 -0700 Subject: [PATCH 003/142] Add a toggle downloads button to share mode, and add new toggle upload and download images --- onionshare_gui/share_mode/__init__.py | 15 +++++++++++++++ share/images/downloads_toggle.png | Bin 0 -> 380 bytes share/images/downloads_toggle_selected.png | Bin 0 -> 468 bytes share/images/uploads_toggle.png | Bin 0 -> 389 bytes share/images/uploads_toggle_selected.png | Bin 0 -> 473 bytes 5 files changed, 15 insertions(+) create mode 100644 share/images/downloads_toggle.png create mode 100644 share/images/downloads_toggle_selected.png create mode 100644 share/images/uploads_toggle.png create mode 100644 share/images/uploads_toggle_selected.png diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index c097d75a..7e444137 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -89,11 +89,20 @@ class ShareMode(Mode): self.update_downloads_completed() self.update_downloads_in_progress() + self.info_toggle_button = QtWidgets.QPushButton() + self.info_toggle_button.setDefault(False) + self.info_toggle_button.setFixedWidth(30) + self.info_toggle_button.setFixedHeight(30) + self.info_toggle_button.setFlat(True) + self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) + self.info_toggle_button.clicked.connect(self.toggle_downloads) + self.info_layout = QtWidgets.QHBoxLayout() self.info_layout.addWidget(self.info_label) self.info_layout.addStretch() self.info_layout.addWidget(self.info_in_progress_downloads_count) self.info_layout.addWidget(self.info_completed_downloads_count) + self.info_layout.addWidget(self.info_toggle_button) self.info_widget = QtWidgets.QWidget() self.info_widget.setLayout(self.info_layout) @@ -353,6 +362,12 @@ class ShareMode(Mode): self.info_in_progress_downloads_count.setText(' {1:d}'.format(image, self.downloads_in_progress)) self.info_in_progress_downloads_count.setToolTip(strings._('info_in_progress_downloads_tooltip', True).format(self.downloads_in_progress)) + def toggle_downloads(self): + """ + Toggle showing and hiding the Downloads widget + """ + pass + @staticmethod def _compute_total_size(filenames): total_size = 0 diff --git a/share/images/downloads_toggle.png b/share/images/downloads_toggle.png new file mode 100644 index 0000000000000000000000000000000000000000..846ececb367e96250c0f48218be55aba4a76b1a1 GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPdr;G@g6&%$AH35qVFC(D|_}@I;7oC^gF*}4f}GxzNVDIkBl-}8P}UM9tkP>Ccm={ zp7egs;qUqZ4NE323GCb)BE)Q3@L*2#$9w(7d-4wc`8)r!%rtJc`3L+>IMv zCQrGYDRDJ;$Ghi8irFUlHEvh=cfC1N%VcwV3D@<+$NQq*T@Je(pV4a3{Mm=I_Xlga XzWd9M4j1nN!->Ju)z4*}Q$iB}!flz# literal 0 HcmV?d00001 diff --git a/share/images/downloads_toggle_selected.png b/share/images/downloads_toggle_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..127ce20806c715eaecbfce44f6a5907f5c769abc GIT binary patch literal 468 zcmV;_0W1EAP)!ax{?-(K5mfWe8FsFPvnLZ}hLPatt~Xq(QCCj1c=V)QQnmVwRxU?{|B zNE{548X^G(Bcyj}&p{ywrSx6y%Xi=V*D08|`Z`>#Ma%Yg7 zl4HzXXI;Sr0RV|gVLF#SZ9Fs{6DQFrImUc2_W&SuoGM0{{{d{nzLsQZuzD#1arl?S z_jO~l+pGbAvS|2k{uKy95Qv0%s>Me+p_VVuj4O6IuqBWH0000< KMNUMnLSTX_O~}&# literal 0 HcmV?d00001 diff --git a/share/images/uploads_toggle.png b/share/images/uploads_toggle.png new file mode 100644 index 0000000000000000000000000000000000000000..87303c9ffb4b08be932a0f38109ab8559b8ed668 GIT binary patch literal 389 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPdr;G@%@Twi_92giFg*;sxLo81BPEz!CaTGXS|K7&p zf=X6^-m1WsgGrlyFdj+TZ5Fxl#M0G=I@Jzu`OUzdcG=Z&Tf`Pg(+YV9maRRT_H6%s z@Ave(bAO)CFHhgDpd1>@E?2uVJuP1|J}~$X%bKbe%r`t8#e|L?KcKsT^G`(ur-i`8 zN{)w?+yPgEA28iuh-*xJAYH-u>%hK_5@!y6(S}uVjP3`-3)s&zIQz$2ZQy^?b)t;p zq1*yt*#rh1CShZ1{rI!V!ryuRJu*z-;yL?9?Yq%D>0R5IBxc^6!nQL#gz?EeOXi>7 z%d%_sW;Dm0yRwpTP3p6^OIIa_%3iPRI#I*4XZj~?yK};|Gp1G-@Yeit&sw~8ncSA3 gnx@T1M5VrR%L@9=OnY-s8W>;zopr0Bru3NdN!< literal 0 HcmV?d00001 diff --git a/share/images/uploads_toggle_selected.png b/share/images/uploads_toggle_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba52cffb17cc54bd2870e13b946544be6326818 GIT binary patch literal 473 zcmV;~0Ve*5P)u`GL1Cu-RzAm`=b`fGgw0I|c^3t{Aa^|rbNfcRP^Fp1dWicnVScd6-ffTEC z$K5)1pgZo?S&G$s0%3a&f}2Z2Sq`MY|E@dO?%w9vp#Q%h=jDN%mj_WC;<~^V5y;fz z;s^kUKt8;Mol&O=0I^NLm>GAVa6rNLG}w$D;-1(#kdCE$Zwrz5{C$1^GdYWv3kMYo P00000NkvXXu0mjf=2^q% literal 0 HcmV?d00001 From e1bd0b5bab6a209008b3ac7f747db10b6bc49d63 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 13:43:10 -0700 Subject: [PATCH 004/142] Toggle showing uploads and downloads for both share and receive modes --- onionshare_gui/mode.py | 1 + onionshare_gui/onionshare_gui.py | 7 +++++++ onionshare_gui/receive_mode/__init__.py | 28 ++++++++++++++++++++++++- onionshare_gui/share_mode/__init__.py | 19 ++++++++++++++--- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/onionshare_gui/mode.py b/onionshare_gui/mode.py index d91b2e64..6da83318 100644 --- a/onionshare_gui/mode.py +++ b/onionshare_gui/mode.py @@ -36,6 +36,7 @@ class Mode(QtWidgets.QWidget): starting_server_step3 = QtCore.pyqtSignal() starting_server_error = QtCore.pyqtSignal(str) set_server_active = QtCore.pyqtSignal(bool) + adjust_size = QtCore.pyqtSignal() def __init__(self, common, qtapp, app, status_bar, server_status_label, system_tray, filenames=None, local_only=False): super(Mode, self).__init__() diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 79565edd..a95b75c9 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -132,6 +132,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.share_mode.server_status.url_copied.connect(self.copy_url) self.share_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) self.share_mode.set_server_active.connect(self.set_server_active) + self.share_mode.adjust_size.connect(self.adjust_size) # Receive mode self.receive_mode = ReceiveMode(self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray, None, self.local_only) @@ -146,6 +147,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.receive_mode.server_status.url_copied.connect(self.copy_url) self.receive_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) self.receive_mode.set_server_active.connect(self.set_server_active) + self.receive_mode.adjust_size.connect(self.adjust_size) self.update_mode_switcher() self.update_server_status_indicator() @@ -442,6 +444,11 @@ class OnionShareGui(QtWidgets.QMainWindow): # Disable settings menu action when server is active self.settings_action.setEnabled(not active) + def adjust_size(self): + self.share_mode.adjustSize() + self.receive_mode.adjustSize() + self.adjustSize() + def closeEvent(self, e): self.common.log('OnionShareGui', 'closeEvent') try: diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index 80bd9cad..efad618a 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -63,10 +63,19 @@ class ReceiveMode(Mode): self.update_uploads_completed() self.update_uploads_in_progress() + self.info_toggle_button = QtWidgets.QPushButton() + self.info_toggle_button.setDefault(False) + self.info_toggle_button.setFixedWidth(30) + self.info_toggle_button.setFixedHeight(30) + self.info_toggle_button.setFlat(True) + self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) + self.info_toggle_button.clicked.connect(self.toggle_uploads) + self.info_layout = QtWidgets.QHBoxLayout() self.info_layout.addStretch() self.info_layout.addWidget(self.info_in_progress_uploads_count) self.info_layout.addWidget(self.info_completed_uploads_count) + self.info_layout.addWidget(self.info_toggle_button) self.info_widget = QtWidgets.QWidget() self.info_widget.setLayout(self.info_layout) @@ -226,4 +235,21 @@ class ReceiveMode(Mode): self.info_widget.hide() # Resize window - self.adjustSize() + self.adjust_size.emit() + + def toggle_uploads(self): + """ + Toggle showing and hiding the Uploads widget + """ + self.common.log('ReceiveMode', 'toggle_uploads') + + if self.uploads.isVisible(): + self.uploads.hide() + self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) + self.info_toggle_button.setFlat(True) + else: + self.uploads.show() + self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle_selected.png')) ) + self.info_toggle_button.setFlat(False) + + self.adjust_size.emit() diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index 7e444137..cf33e8b1 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -226,7 +226,7 @@ class ShareMode(Mode): Stop the compression thread on cancel """ if self.compress_thread: - self.common.log('OnionShareGui', 'cancel_server: quitting compress thread') + self.common.log('ShareMode', 'cancel_server: quitting compress thread') self.compress_thread.quit() def handle_tor_broke_custom(self): @@ -305,6 +305,8 @@ class ShareMode(Mode): self.info_widget.show() def update_primary_action(self): + self.common.log('ShareMode', 'update_primary_action') + # Show or hide primary action layout file_count = self.file_selection.file_list.count() if file_count > 0: @@ -328,7 +330,7 @@ class ShareMode(Mode): self.info_widget.hide() # Resize window - self.adjustSize() + self.adjust_size.emit() def reset_info_counters(self): """ @@ -366,7 +368,18 @@ class ShareMode(Mode): """ Toggle showing and hiding the Downloads widget """ - pass + self.common.log('ShareMode', 'toggle_downloads') + + if self.downloads.isVisible(): + self.downloads.hide() + self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) + self.info_toggle_button.setFlat(True) + else: + self.downloads.show() + self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) ) + self.info_toggle_button.setFlat(False) + + self.adjust_size.emit() @staticmethod def _compute_total_size(filenames): From 7bd5f686a9a9a57015de45c5a6c828c70c8cfd6d Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 15:05:43 -0700 Subject: [PATCH 005/142] OnionShareGui.adjust_size now recursively runs adjustSize() on all widgets --- onionshare_gui/onionshare_gui.py | 31 +++++++++++++++++++++++-- onionshare_gui/receive_mode/__init__.py | 10 ++++---- onionshare_gui/share_mode/__init__.py | 10 ++++---- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index a95b75c9..5469c57c 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -445,8 +445,35 @@ class OnionShareGui(QtWidgets.QMainWindow): self.settings_action.setEnabled(not active) def adjust_size(self): - self.share_mode.adjustSize() - self.receive_mode.adjustSize() + """ + Recursively adjust size on all widgets + """ + # Recursively adjust sizes for the modes + def adjust_size_layout(layout): + count = layout.count() + for i in range(count): + item = layout.itemAt(i) + if item: + child_widget = item.widget() + if child_widget: + adjust_size_widget(child_widget) + child_layout = item.layout() + if child_layout: + adjust_size_layout(child_layout) + + def adjust_size_widget(widget): + layout = widget.layout() + if layout: + adjust_size_layout(layout) + # Processing Qt events before adjusting size makes each .adjustSize() actually count + self.qtapp.processEvents() + widget.adjustSize() + + # Adjust sizes of each mode + for mode in [self.share_mode, self.receive_mode]: + adjust_size_widget(mode) + + # Adjust window size self.adjustSize() def closeEvent(self, e): diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index efad618a..dab37ef2 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -94,11 +94,11 @@ class ReceiveMode(Mode): self.main_layout.addStretch() self.main_layout.addWidget(self.min_width_widget) - # Layout - self.layout = QtWidgets.QHBoxLayout() - self.layout.addLayout(self.main_layout) - self.layout.addWidget(self.uploads) - self.setLayout(self.layout) + # Wrapper layout + self.wrapper_layout = QtWidgets.QHBoxLayout() + self.wrapper_layout.addLayout(self.main_layout) + self.wrapper_layout.addWidget(self.uploads) + self.setLayout(self.wrapper_layout) def get_stop_server_shutdown_timeout_text(self): """ diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index cf33e8b1..c0cb6d39 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -122,11 +122,11 @@ class ShareMode(Mode): self.main_layout.addWidget(self.primary_action) self.main_layout.addWidget(self.min_width_widget) - # Layout - self.layout = QtWidgets.QHBoxLayout() - self.layout.addLayout(self.main_layout) - self.layout.addWidget(self.downloads) - self.setLayout(self.layout) + # Wrapper layout + self.wrapper_layout = QtWidgets.QHBoxLayout() + self.wrapper_layout.addLayout(self.main_layout) + self.wrapper_layout.addWidget(self.downloads) + self.setLayout(self.wrapper_layout) # Always start with focus on file selection self.file_selection.setFocus() From 75f0f55dd8d3cb437e79d3cf3c5c968d61278aff Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 15:30:37 -0700 Subject: [PATCH 006/142] Modes now get to choose a new minimum window width when resizing --- onionshare_gui/mode.py | 21 ++++++++++++++++++++- onionshare_gui/onionshare_gui.py | 14 ++++++++++---- onionshare_gui/receive_mode/__init__.py | 10 ++++++++-- onionshare_gui/share_mode/__init__.py | 10 ++++++++-- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/onionshare_gui/mode.py b/onionshare_gui/mode.py index 6da83318..bd247568 100644 --- a/onionshare_gui/mode.py +++ b/onionshare_gui/mode.py @@ -36,7 +36,7 @@ class Mode(QtWidgets.QWidget): starting_server_step3 = QtCore.pyqtSignal() starting_server_error = QtCore.pyqtSignal(str) set_server_active = QtCore.pyqtSignal(bool) - adjust_size = QtCore.pyqtSignal() + adjust_size = QtCore.pyqtSignal(int) def __init__(self, common, qtapp, app, status_bar, server_status_label, system_tray, filenames=None, local_only=False): super(Mode, self).__init__() @@ -332,3 +332,22 @@ class Mode(QtWidgets.QWidget): Handle REQUEST_UPLOAD_FINISHED event. """ pass + + def resize_window(self): + """ + We call this to force the OnionShare window to resize itself to be smaller. + For this to do anything, the Mode needs to override it and call: + + self.adjust_size.emit(min_width) + + It can calculate min_width (the new minimum window width) based on what + widgets are visible. + """ + pass + + def show(self): + """ + Always resize the window after showing this Mode widget. + """ + super(Mode, self).show() + self.resize_window() diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 5469c57c..e2d95dab 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -168,6 +168,9 @@ class OnionShareGui(QtWidgets.QMainWindow): self.setCentralWidget(central_widget) self.show() + # Adjust window size, to start with a minimum window width + self.adjust_size(450) + # The server isn't active yet self.set_server_active(False) @@ -444,10 +447,14 @@ class OnionShareGui(QtWidgets.QMainWindow): # Disable settings menu action when server is active self.settings_action.setEnabled(not active) - def adjust_size(self): + def adjust_size(self, min_width): """ - Recursively adjust size on all widgets + Recursively adjust size on all widgets. min_width is the new minimum width + of the window. """ + self.common.log("OnionShareGui", "adjust_size", "min_width={}".format(min_width)) + self.setMinimumWidth(min_width) + # Recursively adjust sizes for the modes def adjust_size_layout(layout): count = layout.count() @@ -465,8 +472,6 @@ class OnionShareGui(QtWidgets.QMainWindow): layout = widget.layout() if layout: adjust_size_layout(layout) - # Processing Qt events before adjusting size makes each .adjustSize() actually count - self.qtapp.processEvents() widget.adjustSize() # Adjust sizes of each mode @@ -474,6 +479,7 @@ class OnionShareGui(QtWidgets.QMainWindow): adjust_size_widget(mode) # Adjust window size + self.qtapp.processEvents() self.adjustSize() def closeEvent(self, e): diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index dab37ef2..e30ef519 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -235,7 +235,7 @@ class ReceiveMode(Mode): self.info_widget.hide() # Resize window - self.adjust_size.emit() + self.resize_window() def toggle_uploads(self): """ @@ -252,4 +252,10 @@ class ReceiveMode(Mode): self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle_selected.png')) ) self.info_toggle_button.setFlat(False) - self.adjust_size.emit() + self.resize_window() + + def resize_window(self): + min_width = 450 + if self.uploads.isVisible(): + min_width += 300 + self.adjust_size.emit(min_width) diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index c0cb6d39..cc0a9f32 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -330,7 +330,7 @@ class ShareMode(Mode): self.info_widget.hide() # Resize window - self.adjust_size.emit() + self.resize_window() def reset_info_counters(self): """ @@ -379,7 +379,13 @@ class ShareMode(Mode): self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) ) self.info_toggle_button.setFlat(False) - self.adjust_size.emit() + self.resize_window() + + def resize_window(self): + min_width = 450 + if self.downloads.isVisible(): + min_width += 300 + self.adjust_size.emit(min_width) @staticmethod def _compute_total_size(filenames): From 7a322a6a29bc436e9b18c4a291923641660e666b Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 15:47:49 -0700 Subject: [PATCH 007/142] Refactor share mode info widget into its own file and custom class, and run .show_more() and .show_less() instead of .show() and .hide() --- onionshare_gui/share_mode/__init__.py | 100 ++++----------------- onionshare_gui/share_mode/info.py | 120 ++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 83 deletions(-) create mode 100644 onionshare_gui/share_mode/info.py diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index cc0a9f32..a8828497 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -28,6 +28,7 @@ from onionshare.web import Web from .file_selection import FileSelection from .downloads import Downloads from .threads import CompressThread +from .info import Info from ..mode import Mode from ..widgets import Alert @@ -77,35 +78,7 @@ class ShareMode(Mode): self.downloads_completed = 0 # Information about share, and show downloads button - self.info_label = QtWidgets.QLabel() - self.info_label.setStyleSheet(self.common.css['mode_info_label']) - - self.info_in_progress_downloads_count = QtWidgets.QLabel() - self.info_in_progress_downloads_count.setStyleSheet(self.common.css['mode_info_label']) - - self.info_completed_downloads_count = QtWidgets.QLabel() - self.info_completed_downloads_count.setStyleSheet(self.common.css['mode_info_label']) - - self.update_downloads_completed() - self.update_downloads_in_progress() - - self.info_toggle_button = QtWidgets.QPushButton() - self.info_toggle_button.setDefault(False) - self.info_toggle_button.setFixedWidth(30) - self.info_toggle_button.setFixedHeight(30) - self.info_toggle_button.setFlat(True) - self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) - self.info_toggle_button.clicked.connect(self.toggle_downloads) - - self.info_layout = QtWidgets.QHBoxLayout() - self.info_layout.addWidget(self.info_label) - self.info_layout.addStretch() - self.info_layout.addWidget(self.info_in_progress_downloads_count) - self.info_layout.addWidget(self.info_completed_downloads_count) - self.info_layout.addWidget(self.info_toggle_button) - - self.info_widget = QtWidgets.QWidget() - self.info_widget.setLayout(self.info_layout) + self.info = Info(self.common, self) # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) @@ -117,7 +90,7 @@ class ShareMode(Mode): # Main layout self.main_layout = QtWidgets.QVBoxLayout() - self.main_layout.addWidget(self.info_widget) + self.main_layout.addWidget(self.info) self.main_layout.addLayout(self.file_selection) self.main_layout.addWidget(self.primary_action) self.main_layout.addWidget(self.min_width_widget) @@ -218,7 +191,7 @@ class ShareMode(Mode): self.filesize_warning.hide() self.downloads_in_progress = 0 self.downloads_completed = 0 - self.update_downloads_in_progress() + self.info.update_downloads_in_progress() self.file_selection.file_list.adjustSize() def cancel_server_custom(self): @@ -234,7 +207,7 @@ class ShareMode(Mode): Connection to Tor broke. """ self.primary_action.hide() - self.info_widget.hide() + self.info.show_less() def handle_request_load(self, event): """ @@ -252,7 +225,7 @@ class ShareMode(Mode): filesize = self.web.share_mode.download_filesize self.downloads.add(event["data"]["id"], filesize) self.downloads_in_progress += 1 - self.update_downloads_in_progress() + self.info.update_downloads_in_progress() self.system_tray.showMessage(strings._('systray_download_started_title', True), strings._('systray_download_started_message', True)) @@ -268,10 +241,10 @@ class ShareMode(Mode): # Update the total 'completed downloads' info self.downloads_completed += 1 - self.update_downloads_completed() + self.info.update_downloads_completed() # Update the 'in progress downloads' info self.downloads_in_progress -= 1 - self.update_downloads_in_progress() + self.info.update_downloads_in_progress() # Close on finish? if self.common.settings.get('close_after_first_download'): @@ -282,7 +255,7 @@ class ShareMode(Mode): if self.server_status.status == self.server_status.STATUS_STOPPED: self.downloads.cancel(event["data"]["id"]) self.downloads_in_progress = 0 - self.update_downloads_in_progress() + self.info.update_downloads_in_progress() def handle_request_canceled(self, event): """ @@ -292,7 +265,7 @@ class ShareMode(Mode): # Update the 'in progress downloads' info self.downloads_in_progress -= 1 - self.update_downloads_in_progress() + self.info.update_downloads_in_progress() self.system_tray.showMessage(strings._('systray_download_canceled_title', True), strings._('systray_download_canceled_message', True)) def on_reload_settings(self): @@ -302,7 +275,7 @@ class ShareMode(Mode): """ if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() - self.info_widget.show() + self.info.show_more() def update_primary_action(self): self.common.log('ShareMode', 'update_primary_action') @@ -311,7 +284,7 @@ class ShareMode(Mode): file_count = self.file_selection.file_list.count() if file_count > 0: self.primary_action.show() - self.info_widget.show() + self.info.show_more() # Update the file count in the info label total_size_bytes = 0 @@ -321,13 +294,13 @@ class ShareMode(Mode): total_size_readable = self.common.human_readable_filesize(total_size_bytes) if file_count > 1: - self.info_label.setText(strings._('gui_file_info', True).format(file_count, total_size_readable)) + self.info.update_label(strings._('gui_file_info', True).format(file_count, total_size_readable)) else: - self.info_label.setText(strings._('gui_file_info_single', True).format(file_count, total_size_readable)) + self.info.update_label(strings._('gui_file_info_single', True).format(file_count, total_size_readable)) else: self.primary_action.hide() - self.info_widget.hide() + self.info.show_less() # Resize window self.resize_window() @@ -338,49 +311,10 @@ class ShareMode(Mode): """ self.downloads_completed = 0 self.downloads_in_progress = 0 - self.update_downloads_completed() - self.update_downloads_in_progress() + self.info.update_downloads_completed() + self.info.update_downloads_in_progress() self.downloads.reset() - def update_downloads_completed(self): - """ - Update the 'Downloads completed' info widget. - """ - if self.downloads_completed == 0: - image = self.common.get_resource_path('images/share_completed_none.png') - else: - image = self.common.get_resource_path('images/share_completed.png') - self.info_completed_downloads_count.setText(' {1:d}'.format(image, self.downloads_completed)) - self.info_completed_downloads_count.setToolTip(strings._('info_completed_downloads_tooltip', True).format(self.downloads_completed)) - - def update_downloads_in_progress(self): - """ - Update the 'Downloads in progress' info widget. - """ - if self.downloads_in_progress == 0: - image = self.common.get_resource_path('images/share_in_progress_none.png') - else: - image = self.common.get_resource_path('images/share_in_progress.png') - self.info_in_progress_downloads_count.setText(' {1:d}'.format(image, self.downloads_in_progress)) - self.info_in_progress_downloads_count.setToolTip(strings._('info_in_progress_downloads_tooltip', True).format(self.downloads_in_progress)) - - def toggle_downloads(self): - """ - Toggle showing and hiding the Downloads widget - """ - self.common.log('ShareMode', 'toggle_downloads') - - if self.downloads.isVisible(): - self.downloads.hide() - self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) - self.info_toggle_button.setFlat(True) - else: - self.downloads.show() - self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) ) - self.info_toggle_button.setFlat(False) - - self.resize_window() - def resize_window(self): min_width = 450 if self.downloads.isVisible(): diff --git a/onionshare_gui/share_mode/info.py b/onionshare_gui/share_mode/info.py new file mode 100644 index 00000000..548d70e3 --- /dev/null +++ b/onionshare_gui/share_mode/info.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2018 Micah Lee + +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 . +""" +from PyQt5 import QtCore, QtWidgets, QtGui + +from onionshare import strings + + +class Info(QtWidgets.QWidget): + """ + Share mode information widget + """ + def __init__(self, common, share_mode): + super(Info, self).__init__() + self.common = common + self.share_mode = share_mode + + # Label + self.label = QtWidgets.QLabel() + self.label.setStyleSheet(self.common.css['mode_info_label']) + + # In prorgess and completed labels + self.in_progress_downloads_count = QtWidgets.QLabel() + self.in_progress_downloads_count.setStyleSheet(self.common.css['mode_info_label']) + self.completed_downloads_count = QtWidgets.QLabel() + self.completed_downloads_count.setStyleSheet(self.common.css['mode_info_label']) + + # Toggle button + self.toggle_button = QtWidgets.QPushButton() + self.toggle_button.setDefault(False) + self.toggle_button.setFixedWidth(30) + self.toggle_button.setFixedHeight(30) + self.toggle_button.setFlat(True) + self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) + self.toggle_button.clicked.connect(self.toggle_downloads) + + # Info layout + layout = QtWidgets.QHBoxLayout() + layout.addWidget(self.label) + layout.addStretch() + layout.addWidget(self.in_progress_downloads_count) + layout.addWidget(self.completed_downloads_count) + layout.addWidget(self.toggle_button) + self.setLayout(layout) + + self.update_downloads_completed() + self.update_downloads_in_progress() + + def update_label(self, s): + """ + Updates the text of the label. + """ + self.label.setText(s) + + def update_downloads_completed(self): + """ + Update the 'Downloads completed' info widget. + """ + if self.share_mode.downloads_completed == 0: + image = self.common.get_resource_path('images/share_completed_none.png') + else: + image = self.common.get_resource_path('images/share_completed.png') + self.completed_downloads_count.setText(' {1:d}'.format(image, self.share_mode.downloads_completed)) + self.completed_downloads_count.setToolTip(strings._('info_completed_downloads_tooltip', True).format(self.share_mode.downloads_completed)) + + def update_downloads_in_progress(self): + """ + Update the 'Downloads in progress' info widget. + """ + if self.share_mode.downloads_in_progress == 0: + image = self.common.get_resource_path('images/share_in_progress_none.png') + else: + image = self.common.get_resource_path('images/share_in_progress.png') + self.in_progress_downloads_count.setText(' {1:d}'.format(image, self.share_mode.downloads_in_progress)) + self.in_progress_downloads_count.setToolTip(strings._('info_in_progress_downloads_tooltip', True).format(self.share_mode.downloads_in_progress)) + + def toggle_downloads(self): + """ + Toggle showing and hiding the Downloads widget + """ + self.common.log('ShareMode', 'toggle_downloads') + + if self.share_mode.downloads.isVisible(): + self.share_mode.downloads.hide() + self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) + self.toggle_button.setFlat(True) + else: + self.share_mode.downloads.show() + self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) ) + self.toggle_button.setFlat(False) + + self.share_mode.resize_window() + + def show_less(self): + """ + Remove clutter widgets that aren't necessary. + """ + self.label.hide() + + def show_more(self): + """ + Show all widgets. + """ + self.label.show() From 6bbb918380fc7bde94ac4cd5c355f99f1c19ce53 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 16:00:22 -0700 Subject: [PATCH 008/142] Refactor receive mode into using an info widget too --- onionshare_gui/onionshare_gui.py | 1 - onionshare_gui/receive_mode/__init__.py | 88 +++---------------- onionshare_gui/receive_mode/info.py | 109 ++++++++++++++++++++++++ onionshare_gui/share_mode/__init__.py | 4 +- onionshare_gui/share_mode/info.py | 16 ++-- 5 files changed, 133 insertions(+), 85 deletions(-) create mode 100644 onionshare_gui/receive_mode/info.py diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index e2d95dab..7cc368b8 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -452,7 +452,6 @@ class OnionShareGui(QtWidgets.QMainWindow): Recursively adjust size on all widgets. min_width is the new minimum width of the window. """ - self.common.log("OnionShareGui", "adjust_size", "min_width={}".format(min_width)) self.setMinimumWidth(min_width) # Recursively adjust sizes for the modes diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index e30ef519..83113805 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -23,6 +23,7 @@ from onionshare import strings from onionshare.web import Web from .uploads import Uploads +from .info import ReceiveModeInfo from ..mode import Mode class ReceiveMode(Mode): @@ -54,32 +55,8 @@ class ReceiveMode(Mode): self.new_upload = False # For scrolling to the bottom of the uploads list # Information about share, and show uploads button - self.info_in_progress_uploads_count = QtWidgets.QLabel() - self.info_in_progress_uploads_count.setStyleSheet(self.common.css['mode_info_label']) - - self.info_completed_uploads_count = QtWidgets.QLabel() - self.info_completed_uploads_count.setStyleSheet(self.common.css['mode_info_label']) - - self.update_uploads_completed() - self.update_uploads_in_progress() - - self.info_toggle_button = QtWidgets.QPushButton() - self.info_toggle_button.setDefault(False) - self.info_toggle_button.setFixedWidth(30) - self.info_toggle_button.setFixedHeight(30) - self.info_toggle_button.setFlat(True) - self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) - self.info_toggle_button.clicked.connect(self.toggle_uploads) - - self.info_layout = QtWidgets.QHBoxLayout() - self.info_layout.addStretch() - self.info_layout.addWidget(self.info_in_progress_uploads_count) - self.info_layout.addWidget(self.info_completed_uploads_count) - self.info_layout.addWidget(self.info_toggle_button) - - self.info_widget = QtWidgets.QWidget() - self.info_widget.setLayout(self.info_layout) - self.info_widget.hide() + self.info = ReceiveModeInfo(self.common, self) + self.info.show_less() # Receive mode info self.receive_info = QtWidgets.QLabel(strings._('gui_receive_mode_warning', True)) @@ -88,7 +65,7 @@ class ReceiveMode(Mode): # Main layout self.main_layout = QtWidgets.QVBoxLayout() - self.main_layout.addWidget(self.info_widget) + self.main_layout.addWidget(self.info) self.main_layout.addWidget(self.receive_info) self.main_layout.addWidget(self.primary_action) self.main_layout.addStretch() @@ -137,7 +114,7 @@ class ReceiveMode(Mode): Connection to Tor broke. """ self.primary_action.hide() - self.info_widget.hide() + self.info.show_less() def handle_request_load(self, event): """ @@ -151,7 +128,7 @@ class ReceiveMode(Mode): """ self.uploads.add(event["data"]["id"], event["data"]["content_length"]) self.uploads_in_progress += 1 - self.update_uploads_in_progress() + self.info.update_uploads_in_progress() self.system_tray.showMessage(strings._('systray_upload_started_title', True), strings._('systray_upload_started_message', True)) @@ -181,17 +158,17 @@ class ReceiveMode(Mode): self.uploads.finished(event["data"]["id"]) # Update the total 'completed uploads' info self.uploads_completed += 1 - self.update_uploads_completed() + self.info.update_uploads_completed() # Update the 'in progress uploads' info self.uploads_in_progress -= 1 - self.update_uploads_in_progress() + self.info.update_uploads_in_progress() def on_reload_settings(self): """ We should be ok to re-enable the 'Start Receive Mode' button now. """ self.primary_action.show() - self.info_widget.show() + self.info.show_more() def reset_info_counters(self): """ @@ -199,61 +176,22 @@ class ReceiveMode(Mode): """ self.uploads_completed = 0 self.uploads_in_progress = 0 - self.update_uploads_completed() - self.update_uploads_in_progress() + self.info.update_uploads_completed() + self.info.update_uploads_in_progress() self.uploads.reset() - def update_uploads_completed(self): - """ - Update the 'Uploads completed' info widget. - """ - if self.uploads_completed == 0: - image = self.common.get_resource_path('images/share_completed_none.png') - else: - image = self.common.get_resource_path('images/share_completed.png') - self.info_completed_uploads_count.setText(' {1:d}'.format(image, self.uploads_completed)) - self.info_completed_uploads_count.setToolTip(strings._('info_completed_uploads_tooltip', True).format(self.uploads_completed)) - - def update_uploads_in_progress(self): - """ - Update the 'Uploads in progress' info widget. - """ - if self.uploads_in_progress == 0: - image = self.common.get_resource_path('images/share_in_progress_none.png') - else: - image = self.common.get_resource_path('images/share_in_progress.png') - self.info_in_progress_uploads_count.setText(' {1:d}'.format(image, self.uploads_in_progress)) - self.info_in_progress_uploads_count.setToolTip(strings._('info_in_progress_uploads_tooltip', True).format(self.uploads_in_progress)) - def update_primary_action(self): self.common.log('ReceiveMode', 'update_primary_action') # Show the info widget when the server is active if self.server_status.status == self.server_status.STATUS_STARTED: - self.info_widget.show() + self.info.show_more() else: - self.info_widget.hide() + self.info.show_less() # Resize window self.resize_window() - def toggle_uploads(self): - """ - Toggle showing and hiding the Uploads widget - """ - self.common.log('ReceiveMode', 'toggle_uploads') - - if self.uploads.isVisible(): - self.uploads.hide() - self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) - self.info_toggle_button.setFlat(True) - else: - self.uploads.show() - self.info_toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle_selected.png')) ) - self.info_toggle_button.setFlat(False) - - self.resize_window() - def resize_window(self): min_width = 450 if self.uploads.isVisible(): diff --git a/onionshare_gui/receive_mode/info.py b/onionshare_gui/receive_mode/info.py new file mode 100644 index 00000000..0f5bc298 --- /dev/null +++ b/onionshare_gui/receive_mode/info.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2018 Micah Lee + +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 . +""" +from PyQt5 import QtCore, QtWidgets, QtGui + +from onionshare import strings + + +class ReceiveModeInfo(QtWidgets.QWidget): + """ + Receive mode information widget + """ + def __init__(self, common, receive_mode): + super(ReceiveModeInfo, self).__init__() + self.common = common + self.receive_mode = receive_mode + + # In progress and completed labels + self.in_progress_uploads_count = QtWidgets.QLabel() + self.in_progress_uploads_count.setStyleSheet(self.common.css['mode_info_label']) + self.completed_uploads_count = QtWidgets.QLabel() + self.completed_uploads_count.setStyleSheet(self.common.css['mode_info_label']) + + # Toggle button + self.toggle_button = QtWidgets.QPushButton() + self.toggle_button.setDefault(False) + self.toggle_button.setFixedWidth(30) + self.toggle_button.setFixedHeight(30) + self.toggle_button.setFlat(True) + self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) + self.toggle_button.clicked.connect(self.toggle_uploads) + + # Layout + layout = QtWidgets.QHBoxLayout() + layout.addStretch() + layout.addWidget(self.in_progress_uploads_count) + layout.addWidget(self.completed_uploads_count) + layout.addWidget(self.toggle_button) + self.setLayout(layout) + + self.update_uploads_completed() + self.update_uploads_in_progress() + + def update_uploads_completed(self): + """ + Update the 'Uploads completed' info widget. + """ + if self.receive_mode.uploads_completed == 0: + image = self.common.get_resource_path('images/share_completed_none.png') + else: + image = self.common.get_resource_path('images/share_completed.png') + self.completed_uploads_count.setText(' {1:d}'.format(image, self.receive_mode.uploads_completed)) + self.completed_uploads_count.setToolTip(strings._('info_completed_uploads_tooltip', True).format(self.receive_mode.uploads_completed)) + + def update_uploads_in_progress(self): + """ + Update the 'Uploads in progress' info widget. + """ + if self.receive_mode.uploads_in_progress == 0: + image = self.common.get_resource_path('images/share_in_progress_none.png') + else: + image = self.common.get_resource_path('images/share_in_progress.png') + self.in_progress_uploads_count.setText(' {1:d}'.format(image, self.receive_mode.uploads_in_progress)) + self.in_progress_uploads_count.setToolTip(strings._('info_in_progress_uploads_tooltip', True).format(self.receive_mode.uploads_in_progress)) + + def toggle_uploads(self): + """ + Toggle showing and hiding the Uploads widget + """ + self.common.log('ReceiveModeInfo', 'toggle_uploads') + + if self.receive_mode.uploads.isVisible(): + self.receive_mode.uploads.hide() + self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) + self.toggle_button.setFlat(True) + else: + self.receive_mode.uploads.show() + self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle_selected.png')) ) + self.toggle_button.setFlat(False) + + self.receive_mode.resize_window() + + def show_less(self): + """ + Remove clutter widgets that aren't necessary. + """ + pass + + def show_more(self): + """ + Show all widgets. + """ + pass diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index a8828497..0504b529 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -28,7 +28,7 @@ from onionshare.web import Web from .file_selection import FileSelection from .downloads import Downloads from .threads import CompressThread -from .info import Info +from .info import ShareModeInfo from ..mode import Mode from ..widgets import Alert @@ -78,7 +78,7 @@ class ShareMode(Mode): self.downloads_completed = 0 # Information about share, and show downloads button - self.info = Info(self.common, self) + self.info = ShareModeInfo(self.common, self) # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) diff --git a/onionshare_gui/share_mode/info.py b/onionshare_gui/share_mode/info.py index 548d70e3..3ee12a95 100644 --- a/onionshare_gui/share_mode/info.py +++ b/onionshare_gui/share_mode/info.py @@ -22,20 +22,21 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings -class Info(QtWidgets.QWidget): +class ShareModeInfo(QtWidgets.QWidget): """ Share mode information widget """ def __init__(self, common, share_mode): - super(Info, self).__init__() + super(ShareModeInfo, self).__init__() self.common = common self.share_mode = share_mode # Label + self.label_text = "" self.label = QtWidgets.QLabel() self.label.setStyleSheet(self.common.css['mode_info_label']) - # In prorgess and completed labels + # In progress and completed labels self.in_progress_downloads_count = QtWidgets.QLabel() self.in_progress_downloads_count.setStyleSheet(self.common.css['mode_info_label']) self.completed_downloads_count = QtWidgets.QLabel() @@ -66,7 +67,8 @@ class Info(QtWidgets.QWidget): """ Updates the text of the label. """ - self.label.setText(s) + self.label_text = s + self.label.setText(self.label_text) def update_downloads_completed(self): """ @@ -94,7 +96,7 @@ class Info(QtWidgets.QWidget): """ Toggle showing and hiding the Downloads widget """ - self.common.log('ShareMode', 'toggle_downloads') + self.common.log('ShareModeInfo', 'toggle_downloads') if self.share_mode.downloads.isVisible(): self.share_mode.downloads.hide() @@ -111,10 +113,10 @@ class Info(QtWidgets.QWidget): """ Remove clutter widgets that aren't necessary. """ - self.label.hide() + self.label.setText("") def show_more(self): """ Show all widgets. """ - self.label.show() + self.label.setText(self.label_text) From 42a91d23e4587049fdb0b002f49f685afe251eca Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 16:06:14 -0700 Subject: [PATCH 009/142] Process Qt events once more, to prevent weird size issues before adjusting size --- onionshare_gui/mode.py | 1 + onionshare_gui/onionshare_gui.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/mode.py b/onionshare_gui/mode.py index bd247568..0fba029b 100644 --- a/onionshare_gui/mode.py +++ b/onionshare_gui/mode.py @@ -350,4 +350,5 @@ class Mode(QtWidgets.QWidget): Always resize the window after showing this Mode widget. """ super(Mode, self).show() + self.qtapp.processEvents() self.resize_window() diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 7cc368b8..51190ea3 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -454,7 +454,6 @@ class OnionShareGui(QtWidgets.QMainWindow): """ self.setMinimumWidth(min_width) - # Recursively adjust sizes for the modes def adjust_size_layout(layout): count = layout.count() for i in range(count): From 481bc8bdc1a950025605c54af78e1dfb1d9804dd Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 17:01:48 -0700 Subject: [PATCH 010/142] Attempting to redesign Downloads --- onionshare/common.py | 15 +++++ onionshare_gui/share_mode/downloads.py | 74 +++++++++++++++++-------- share/images/downloads.png | Bin 0 -> 2120 bytes share/images/downloads_transparent.png | Bin 0 -> 2138 bytes share/images/uploads.png | Bin 0 -> 2076 bytes share/images/uploads_transparent.png | Bin 0 -> 2096 bytes share/locale/en.json | 4 +- 7 files changed, 69 insertions(+), 24 deletions(-) create mode 100644 share/images/downloads.png create mode 100644 share/images/downloads_transparent.png create mode 100644 share/images/uploads.png create mode 100644 share/images/uploads_transparent.png diff --git a/onionshare/common.py b/onionshare/common.py index 28b282c2..78b6e2d7 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -248,6 +248,15 @@ class Common(object): border-radius: 5px; }""", + 'downloads_uploads': """ + background-color: #ffffff; + """, + + 'downloads_uploads_empty_text': """ + QLabel { + color: #999999; + }""", + 'downloads_uploads_label': """ QLabel { font-weight: bold; @@ -255,6 +264,12 @@ class Common(object): text-align: center; }""", + 'downloads_uploads_clear': """ + QPushButton { + color: #3f7fcf; + } + """, + 'downloads_uploads_progress_bar': """ QProgressBar { border: 1px solid #4e064f; diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index a34796f1..3da88bc4 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -89,33 +89,64 @@ class Downloads(QtWidgets.QScrollArea): self.downloads = {} - self.setWindowTitle(strings._('gui_downloads', True)) - self.setWidgetResizable(True) - self.setMinimumHeight(150) self.setMinimumWidth(350) - self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png'))) - self.setWindowFlags(QtCore.Qt.Sheet | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.CustomizeWindowHint) + self.setStyleSheet(self.common.css['downloads_uploads']) + + # Scroll bar self.vbar = self.verticalScrollBar() self.vbar.rangeChanged.connect(self.resizeScroll) + # When there are no downloads + empty_image = QtWidgets.QLabel() + empty_image.setAlignment(QtCore.Qt.AlignCenter) + empty_image.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/downloads_transparent.png')))) + empty_text = QtWidgets.QLabel(strings._('gui_no_downloads', True)) + empty_text.setAlignment(QtCore.Qt.AlignCenter) + empty_text.setStyleSheet(self.common.css['downloads_uploads_empty_text']) + empty_layout = QtWidgets.QVBoxLayout() + empty_layout.addStretch() + empty_layout.addWidget(empty_image) + empty_layout.addWidget(empty_text) + empty_layout.addStretch() + self.empty = QtWidgets.QWidget() + self.empty.setLayout(empty_layout) + + # When there are downloads downloads_label = QtWidgets.QLabel(strings._('gui_downloads', True)) downloads_label.setStyleSheet(self.common.css['downloads_uploads_label']) - self.no_downloads_label = QtWidgets.QLabel(strings._('gui_no_downloads', True)) - self.clear_history_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) - self.clear_history_button.clicked.connect(self.reset) - self.clear_history_button.hide() + clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) + clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) + clear_button.setFlat(True) + clear_button.clicked.connect(self.reset) + download_header = QtWidgets.QHBoxLayout() + download_header.addWidget(downloads_label) + download_header.addStretch() + download_header.addWidget(clear_button) + self.not_empty = QtWidgets.QWidget() + self.not_empty.setLayout(download_header) self.downloads_layout = QtWidgets.QVBoxLayout() - widget = QtWidgets.QWidget() + # Layout + self.widget = QtWidgets.QWidget() layout = QtWidgets.QVBoxLayout() - layout.addWidget(downloads_label) - layout.addWidget(self.no_downloads_label) - layout.addWidget(self.clear_history_button) + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(self.empty) + layout.addWidget(self.not_empty) layout.addLayout(self.downloads_layout) layout.addStretch() - widget.setLayout(layout) - self.setWidget(widget) + self.widget.setLayout(layout) + self.setWidget(self.widget) + + # Reset once at the beginning + self.reset() + + def resizeEvent(self, event): + """ + When the widget resizes, resize the inner widget to match + """ + #self.empty.resize(self.width()-2, self.width()-2) + pass def resizeScroll(self, minimum, maximum): """ @@ -127,10 +158,9 @@ class Downloads(QtWidgets.QScrollArea): """ Add a new download progress bar. """ - # Hide the no_downloads_label - self.no_downloads_label.hide() - # Show the clear_history_button - self.clear_history_button.show() + # Hide empty, show not empty + self.empty.hide() + self.not_empty.show() # Add it to the list download = Download(self.common, download_id, total_bytes) @@ -158,6 +188,6 @@ class Downloads(QtWidgets.QScrollArea): download.progress_bar.close() self.downloads = {} - self.no_downloads_label.show() - self.clear_history_button.hide() - self.resize(self.sizeHint()) + # Hide not empty, show empty + self.not_empty.hide() + self.empty.show() diff --git a/share/images/downloads.png b/share/images/downloads.png new file mode 100644 index 0000000000000000000000000000000000000000..ad879b6e0f80dbfa3c82459e645d52f1412caf3a GIT binary patch literal 2120 zcmV-O2)Fl%P)T2h~YL zK~#9!?VVp}Th|@OKf01F)%Kl{W9HOJRQTP1#AYs39JVKz!snZXaxM?&=_zZ zm;n9(M1XPN0T5L+_1{iigUbPE+kqf(0B{3dgGJ5)kAe4qAyrd9S#tmtS!o4!0mp#~ zi_Oger+~1ksaIAlKt)!3qDkJg0a`YgJAjC)sWVm>kSv1tCU6(H;~+eQ?K{9-QK!=O zK+(U2fhtN<)4(n>`$?CH@a~Ecbu}oeYU;O30-z!*2Z7T-EvrjY!0W1}{@zF-ZiDcC z3-kj%R-b%;67UA?%4XiEQ1HP|n z>SQ4&d5SP}--OviDQbhbHlOJpC|ujWhT)}74I6=&s;NoSny?}(U)j}cTYuI{*Bf2b zt*--Ma(t4Dzq-hkKVGq|Ijfqw(X>%mbh6*Gqvi+SI!I?0UO3pkBtdgr}eWlgz5a*zgIPkQcwXNS+Z^|(y>vT~7#oX4`>6x$E zXUZ`qt5&ecAD~!Ov3+46nM|5;j0M^(nB?t&VJB*tm`|8;j719P1yC$JI*1z?)@8IdwBFK=J6YqRc0!Dg>()9=OX) zE1i9veE8oF7ym+oA^Z(~%dgJg;3qT~T4uYmuhVQZyV3zXZdU32m;34J>st0%TX!3S z*9Y19!dA=RZGB-YgVzUX>uy{2c~@T-{g?aAGFaA57#X0w zr`>dT?LF-bj0{j)pMLVRt$CZ7o>;LESTA^B(5#YEJug+B3J<}zgY=y0F%4eNsUCuF z2k}&R4Areb1(yOmU}v!EcDvbqXg9q>y@t!`9qMKGq20LMZfw>80FQXZY?*bJ%ldbY zBuS!WUkdXwJRz-E^sD?b7LluRZ~yOS4gU0}m^3VVEV|6li!>ty6QIqPxSq=q)B(fCYb zLFM23=RHEtn?6hZsf7M^sHx2$^n8eiUp_48oW^Gwsqxq3Jg&xHQ!u=TUp}+~9>97D zXtSc^;Il!-J|8RSoP2I#p*MQ$^D%>Bn9?#_g-O9h-CAzIvNuFCMef z#1;vVt+a5m<0Rqt!?v#DC6h_Q?}s_ranfp24IZGe8xs1)Jx8?=E9NVkV!V9x7YTjWqvJXgJd^i>b(>1KXzKI8ZEbMtg>>2@66l92C#1Vqu_3wB(wi5MO0I*5K2UGZJ?vnUjY_Pn;I*a0IWqf~$q;At)W^(0Bc)iehvNox4{^)te{yw&91L-sjG7mnv&K4W4*Ft)eVsuW` z)T4#~3W(Q$rvEc|qpGGh=bSI+Tbi9oCrUthC!Hv#Jy|Jh(w;1VIkSc#&Z?SP(3bdO zCasO=X_D4lvlZ8d)c|9ne;8e31I9-5Y{3P|&^v8wB*e)Xs$`8hjaZJvBOe94fv?0o zakb?ToC1!hnmS;lka7x8gEDR9Q&eaNrM(n34eT%ro~a&~;*D>jC$A`#{0m>BFNXG; yU2r)Occ}tQfmu!kZz9a{j}e#%bJhPG#{U3#k;&MKJ6Qq%0000Iz^0 literal 0 HcmV?d00001 diff --git a/share/images/downloads_transparent.png b/share/images/downloads_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..9920709707a9dc6e3e9c59f5d5ab9d6a1fc21026 GIT binary patch literal 2138 zcmV-g2&MOlP)=0V#(1<@OiE*7j4;iR5Kw_Yf-r8INVe=$BZP}&P^H+)daJlf zESbKzYQ;mKNt8n6C>NC=IWJL^CbHyFaTB3F7?L;zVGwB^HU-&f8ia-L0)q*@?e<}3 z$r|r^XLjeZ>+E0J7thSO{N_97eCIoJjyAzdRI1o`a^@dw@@VEf20@w^}1O!0LG07Pq3S0n&R876S-~cL;QVmoAJ9KDvDhhlG ze64EgrGf>hNQzf)jv)u2%?I-+a81?J>4E{MNJ=fRRqxC4LAQW2s-~XIYk+$H)&eXd zKQ#rsV`V?-u@GJda36)C>#C-9=LJATQZ@ngfRDn`1n{w{spoP@M9dLh1Mno^rSRkh zWZ5T|h9|=p9S5jLN-OXPg|C&ePhJzA44-$T2`iGa1b9xLDJ&#uz+0-OerM*PZ2YtR z3lJW9o%Y*ifx6}Gw_xg(@0tM)8?{6;7WkY~@akIX==rLLzMFmY-Rz_1s~+lF>YM^7 z>UFhl5YY#WA30I_XJ2}j=B{SS{NGPvmXs}F(^H#}0utx`dCrMq_>2xLq5*gfPK~y8 zEp;??Hc?VqGPj_jNae$oXk!|e&R=q(IDR88j$pt^-sV)>se7i5QmHiU^-`&nx@R0~ z$^hGR23hxk^-h*{`Gd8K_5*rXOi0QF#~EAhNMwm^VII-B$W^)UQaib|)gI-|4}m{?LQ zDzy?zuW12>ii|QUloFu6^e7bhWR4%`tmar?m6f?PcQxM)2K3$RqrJPGz>0wFwF|5W z(B9oXEAQs6W~;NQN(FF-RjD65evrLgduO}zt@U&dcC+sBb+*A<_xL)x2fL|nojrNj z+qIX2#}8VW)s9&Jbth4<%JMes+>m;9zTD5D{zEi|8ZC#{7;5BD{~`R#{VA_+*tx+< zOB520bpqOEt5Uw#^6r&)k(b~rK|-%uH(rHa4H0}LhEK>0=hul|YItmfq7tfoZSC;!6kTn5!aD%Mu8>fu$kLyShFoci!o)~=CRS4Nb5^3M}* z&CbdVs)P8;{Z#+78bPqf;Af_1_~_V2y#D;_PW2LAQTE9{i}%g;H?OlN&T?hs3Xj!4 zhUm3+<}fue#cRKPjo!cXI?_exygUN&O)QRS;QayG9&Ka%#<*o^j^7xk?a?*{-XCzJ z4#~zQ5dSXDQAI{0?5o^o+E+~HxXhI;q@60u2 z>nl3o;~CNaMA;`V1J=4(iiEGYdi`p{_dDR@8PRE1n{cv@1dkYASa-3#{IU19!qq(NO z>xEs^?5@chcmRt_7E`mkhFvf0%67m=%jjN!*K(cOHMTX{7IDr+f*{b?)|gAPh3^mk zNexgx8stna1)XoFk=vTDYz8CpXYM^dWsa%nM}tfi$KW}dN_A{Xy0-RCwz=HaZs#q5 z9LtuHNlJjalXyLwT>9VcCmPK^pFA3k(*JgUwvS&=ch*eWrLpj2_+PS5-j2x=IfgF` zbARRiJh0{g%U9lVabrH~`;2#Ae3!}ZCe1!Rp=#>kbQd$h`4~{l)fc4AKuinV!}+TyNutsne>a{$t*kl_`brWcZ@&lh*+L9~ivaVf15R<*VS0W#%$_}r2K(}dv?r>s;Q=SV0 zl(POLOFv6y)dCtYda`*i>!ui<44;>Maw)K~z~P-XGTK@WFv-Qa39P2@&Jdgc`c+Lm zl}jSUBS3Rh@eta40+yV@BZ#NKO7WMvPa$l)B_Iy+W{Z&7*Gw=0ABUh2rv!Y z0saSsf!n}cU{WaJt77%RQ3PmD0*8S^fD>@(EOH)L0{#Jngd+a4=>WeTPgBup0?2+B-ko?pFXt`kS1j0fQb7oW^nFQ|?a1;2vi11MB{v5cew#nWW zsLpT0z!vPOSs-BKJn1kH-c5By-3Xc#ig?5p0A-K-JK!9!m5rq+@Ul?E-}MyY)Cun| zz-hqE#*-V6eJQ{r6R~tS3q?F+qy>%ueydvl`oCYN{)yEt<>bU9Fa7K#DgoBe2XD34Du8~q@7gU;b&^9?wYWFhi^Gw7P$UuwnzlAsX^Dq(Ios=5 z;5n;W*&1qH7aoAa;h;6tY9+vPnk>-DciZ-!b{d{;DCn8-e~r`e%Z{SIJ3DejRX(+% zW#`AvQ}=kCre~+FPZ8W5vx14Pu_*Rf|m+?{la#uOQw}P~sZ7~zzgDRt}08Lvs zT0^buJF*XFnbWl1Im?{vJF?GgH)ju&oqSF%<%CFb&!oz z!_y6%A3JYG(QT^$s*bavGrJZaFOf(Xa*qYRV!6s}#R3l-S$gMZodx@N(_c(;KXQNF z`|d~XGyTPM!McEKu)IM5UkkyS3jdQf&Xx`5pZ8*yK(0D=Z ztbMeW11Am`3Gfhrq;4^Drcc6Jb@0T&g5X{G@CqHxg$D&Xnmf4i;gy0Q7SgtSR%6*C z?wZ{?{DNQb*ULv`<(NcIzOH1^3_v?a} z3bDVtpQWXxVl4CztN=6$-o-N)b6#IuSS0jHh_1FS!+O!x)z)D{ibXWe9R$x)TXNv$%A{g(A@WPhTLPJ1|*WF9&Mp} zx9%BokA#RZrGZyuOjKJ)QCHag$7_qTgF`07EbwpRf#b9;u1f4W#ycp2iQ zvqBM-%K-ldJYRB=3)0&{5x-w{szN0m>n<4S3PH*SOW7mGDDK%_Tf)oYcP^l@^;!+Sfw8I8U|i9qGETYoBhx4$KUM7TkXZQ#RUmiTD0cFkF(4P4w#>vCvqpk z=;cv9e*5FRo$x$9u&wM?U3Hfc!`M^hq2a=OU4Q68nNjo> zw=#UwhcF})H0V;(i%s~O{kDMzP~on?-|VO9#U`x_Mpj1Y0K>qydK%k!q_G$uxz~^4 zND_@l8ubiYR5szP0M*nWx_04g@z^!rMDDib8Rh9rPoJ{JRD>cnkyJkbOQR?mXS$Dfa-~yNiDVXb@vgE$885M9*@)4t$9bpWVT#0S!a9oY*@6= zntI>pW%TkWvALLS;Kk-*j9wn4_l;gHk4JOmm{~7p!pnueCo3}wZ@%y*Q`e?8tRtO) zLH5OGy{FYf$D1L&i5C4;DB=ZO09A;V9{IP4@;dTw+oTgkmf=Y!N@-8@T3`yyxlIgl zUMQlV#5-DET5CwAN!oP7R_z;R1B|Hi!{{bkFdjm~Mk`(WBsPhQv#zU>)92Jvb2t|6 z_qlwx)c3@VmP0TK92biCqn<)aDL{3~u*j#{pqQ;$fp|9!fRG5>T}i4LWsKZK7n^Lz7ZUQ9{+wiYrk8EkbJrak87F#EzXk z_?o$i9sBzJ$#w8o@{8}e=g-H#bI$MlwTmT`syRA3Ug zqkSfUDIhGX^2Ab=!L4z*Y^Km5KxB zfE%(Ze_gNuC7PS7N9QC8(aM+4N_w>`iL zoT(^q!pwHkWg@(G-~kFlMlO6+h0A319GeDoL%9o5p;x-8Hx4>@z4}~WW zAc|hGOo=F0Z3ig%q~8PUDSTClUa?k*D4*L>g(aV~5@^##3d>0<@TRQFKj?WWAOCFM zGK7a#rhS%Kpk{gdOc;7OT`}Nju9m3B0^96_=U?Nec2h02n`-f|@!JW|t(Db03)DJ{ zpV?J{*U!Dq!#{ucN8eo=y~ayhU$PVAH?k@pHw;j7Rkqk=b)m09cvhtMie{s;>|MW? z@ONRmAbuvRa&O)MH78lJE4S}YypPMZ_-{HlH%D_tvz?YGFXn7#YXf)KmCKG$M^<XHmcZhnaKIiZ?8)^`LCGyeVKeA=SB6`JNC=umC&K9W6 zs@O6y&~?6xz>@*p?**O=&~?7cE-QRMW0G?f-eX6uLSKfc*-(@B`!ySC2z?o{3*w%f z0BVz=md@w-*Z4X0?I|kPRT_?~a$O~-zCC4!ued^ElNq2k4ZqpSTr@u0NcZJ#$}7rE zi?h6t9;geQ-CP67y%j+#WYunzm5!lM06a zHEdN8N`SAFh%%K4U1g=dDU6phT3x1pu|B z$4yqj+y3-+1i|{nIhV^t_4;bo)~&S)qD%COHlBiDCiEMR>k7rt4v(8uC`XhjvlW1!F%E!l>o0~Hwj19h`kaVn*&`dRxW5dUE z`*^pm-eNL5nKj&Gc#>OJ^)2gGuB+tO@G;X3JQd(ZBfoO0cJ1Fq)uUCqtZrmrgtkD= zbC|RR+87xa(Us4tN2}Pif0vm6HzrN7Vt(~C(%?V0|2bXo2G0y~xaF|!bPl&1X7J3Q zE{J;amSZ)p@Q~P_=S~*LuHG^pk27?3h}ZVMmUkS|NHJ;8yd1M~!YOgDv|U=IhH4lr>${chjUp;1mBIc;{b zs|DbvX2;sOvva|(-FLi?_WE|NT)1LceY$et3hnjn^d0Y8V0oQ8JFQ4^wM+6zoj7E% z{O#*+<9l%NO%Ljr%I=!oI7HtIEdQMbR>~)s;XL2RDiwe^Gkf9tK`F-O5=b0kDN2V@ zjZGl2FV1lpGZMx|#RL*Z030E~BbXA#M$HH$&Ycx4FhAXN6u`SvcTEXnqrP@j6~2A* zwkct3?1iTU5=TZIq5hNoOsmrwpHHjP^q=fsa(F4t$dmwtN$d+=dVnYT8F*`eXe7Ge zSu_%5;H?4rPb@9K6nHTp>{cSmjOY~`oHC@l^zTcIe?Ly$V|A=twGx1_|BP|+;7QIN zJ?j+91Bl70Jm3P5e9}|EFN-d+E)C17{6W&G8Y%L~+F{JsNOB~CcKkD5#Fe$$CKXQ} znN4-;&lQp7?6luwmAcRD2C&VHgiFgy+4+Z^G_*9}U*pGH=7l+k&Dzu1yFG4j!OZjw z;qStH{Ev_M@NXaH?1bmAz;@#vY(^4#QXP?Cp1e#uGGE!~f{}=zH2dG^Qa?wae%Y0>y?GzTvTaL3l7w2D}vcOcd zt3jg0K6v41GTpT)nd;h!d{bF$GGM7?FmGv@qy?xsiR1aC($n2TJnlT7JRXnJ)1CK@ zi1AE!&19TFP$J3&(JR)Y^G1$qUtFVdT_q3IK9ums9OA}&^3P9r=hb(J{1DOm`i!i~ zM>9Rl2B#05$6eJil{fzQ2G=iNFIY!94TH>`Pqw%1JaFwmWj%16wT>wf<*MivYk`XU z4Bj`gDxb;fU*-~%c6We!AHh>|xi2ASfSTUKAyfYrE2fn-w;3C~u{&uyoE7k7RsOTC zAz~hh99^c>S=Gv>OL;Hz+kKae4IReud|u4EDk>4>bI~i70aXPK@3UNbThjrixH$g> zYAC!r1ZRLAS(S&3L{hv0)S!x&&^ifV3drI$$RCbyHtKO-;+X2Jg* a#{U3{;?ogoegf_Q0000 Date: Fri, 28 Sep 2018 18:30:32 -0700 Subject: [PATCH 011/142] Got empty Downloads looking good --- onionshare/common.py | 13 +++++++++-- onionshare_gui/share_mode/downloads.py | 31 +++++++++++++------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/onionshare/common.py b/onionshare/common.py index 78b6e2d7..3489c3e6 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -248,8 +248,15 @@ class Common(object): border-radius: 5px; }""", - 'downloads_uploads': """ - background-color: #ffffff; + 'downloads_uploads_empty': """ + QWidget { + background-color: #ffffff; + border: 1px solid #999999; + } + QWidget QLabel { + background-color: none; + border: 0px; + } """, 'downloads_uploads_empty_text': """ @@ -262,6 +269,8 @@ class Common(object): font-weight: bold; font-size 14px; text-align: center; + background-color: none; + border: none; }""", 'downloads_uploads_clear': """ diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index 3da88bc4..fcf8bc8e 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -78,7 +78,7 @@ class Download(object): self.started) -class Downloads(QtWidgets.QScrollArea): +class Downloads(QtWidgets.QWidget): """ The downloads chunk of the GUI. This lists all of the active download progress bars. @@ -90,11 +90,6 @@ class Downloads(QtWidgets.QScrollArea): self.downloads = {} self.setMinimumWidth(350) - self.setStyleSheet(self.common.css['downloads_uploads']) - - # Scroll bar - self.vbar = self.verticalScrollBar() - self.vbar.rangeChanged.connect(self.resizeScroll) # When there are no downloads empty_image = QtWidgets.QLabel() @@ -109,6 +104,7 @@ class Downloads(QtWidgets.QScrollArea): empty_layout.addWidget(empty_text) empty_layout.addStretch() self.empty = QtWidgets.QWidget() + self.empty.setStyleSheet(self.common.css['downloads_uploads_empty']) self.empty.setLayout(empty_layout) # When there are downloads @@ -122,25 +118,29 @@ class Downloads(QtWidgets.QScrollArea): download_header.addWidget(downloads_label) download_header.addStretch() download_header.addWidget(clear_button) - self.not_empty = QtWidgets.QWidget() - self.not_empty.setLayout(download_header) - self.downloads_layout = QtWidgets.QVBoxLayout() + not_empty_layout = QtWidgets.QVBoxLayout() + not_empty_layout.addLayout(download_header) + not_empty_layout.addLayout(self.downloads_layout) + self.not_empty = QtWidgets.QWidget() + self.not_empty.setLayout(not_empty_layout) # Layout - self.widget = QtWidgets.QWidget() layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.empty) layout.addWidget(self.not_empty) - layout.addLayout(self.downloads_layout) - layout.addStretch() - self.widget.setLayout(layout) - self.setWidget(self.widget) + self.setLayout(layout) # Reset once at the beginning self.reset() + """ + # Scroll bar + self.vbar = self.verticalScrollBar() + self.vbar.rangeChanged.connect(self.resizeScroll) + """ + def resizeEvent(self, event): """ When the widget resizes, resize the inner widget to match @@ -152,7 +152,8 @@ class Downloads(QtWidgets.QScrollArea): """ Scroll to the bottom of the window when the range changes. """ - self.vbar.setValue(maximum) + pass + #self.vbar.setValue(maximum) def add(self, download_id, total_bytes): """ From 56a283585b7abd9a020577ecc784752e1921cf2d Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 18:48:12 -0700 Subject: [PATCH 012/142] Refactor Downloads to use an internal QListWidget to list the progess bars --- onionshare_gui/share_mode/downloads.py | 83 +++++++++++++++++++------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index fcf8bc8e..855827b1 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -78,6 +78,59 @@ class Download(object): self.started) +class DownloadList(QtWidgets.QListWidget): + """ + List of download progess bars. + """ + def __init__(self, common): + super(DownloadList, self).__init__() + self.common = common + + self.downloads = {} + + self.setMinimumHeight(205) + self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) + self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) + + def add(self, download_id, total_bytes): + """ + Add a new download progress bar. + """ + download = Download(self.common, download_id, total_bytes) + self.downloads[download_id] = download + + item = QtWidgets.QListWidgetItem() + self.addItem(item) + self.setItemWidget(item, download.progress_bar) + + def update(self, download_id, downloaded_bytes): + """ + Update the progress of a download progress bar. + """ + self.downloads[download_id].update(downloaded_bytes) + + def cancel(self, download_id): + """ + Update a download progress bar to show that it has been canceled. + """ + self.downloads[download_id].cancel() + + def reset(self): + """ + Reset the downloads back to zero + """ + # Remove all items from list + while True: + item = self.takeItem(0) + if not item: + break + + # Close all progress bars + for download in self.downloads.values(): + download.progress_bar.close() + self.downloads = {} + + class Downloads(QtWidgets.QWidget): """ The downloads chunk of the GUI. This lists all of the active download @@ -87,8 +140,6 @@ class Downloads(QtWidgets.QWidget): super(Downloads, self).__init__() self.common = common - self.downloads = {} - self.setMinimumWidth(350) # When there are no downloads @@ -108,6 +159,9 @@ class Downloads(QtWidgets.QWidget): self.empty.setLayout(empty_layout) # When there are downloads + self.download_list = DownloadList(self.common) + + # Download header downloads_label = QtWidgets.QLabel(strings._('gui_downloads', True)) downloads_label.setStyleSheet(self.common.css['downloads_uploads_label']) clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) @@ -118,10 +172,11 @@ class Downloads(QtWidgets.QWidget): download_header.addWidget(downloads_label) download_header.addStretch() download_header.addWidget(clear_button) - self.downloads_layout = QtWidgets.QVBoxLayout() + + # Download layout not_empty_layout = QtWidgets.QVBoxLayout() not_empty_layout.addLayout(download_header) - not_empty_layout.addLayout(self.downloads_layout) + not_empty_layout.addWidget(self.download_list) self.not_empty = QtWidgets.QWidget() self.not_empty.setLayout(not_empty_layout) @@ -141,13 +196,6 @@ class Downloads(QtWidgets.QWidget): self.vbar.rangeChanged.connect(self.resizeScroll) """ - def resizeEvent(self, event): - """ - When the widget resizes, resize the inner widget to match - """ - #self.empty.resize(self.width()-2, self.width()-2) - pass - def resizeScroll(self, minimum, maximum): """ Scroll to the bottom of the window when the range changes. @@ -164,30 +212,25 @@ class Downloads(QtWidgets.QWidget): self.not_empty.show() # Add it to the list - download = Download(self.common, download_id, total_bytes) - self.downloads[download_id] = download - self.downloads_layout.addWidget(download.progress_bar) + self.download_list.add(download_id, total_bytes) def update(self, download_id, downloaded_bytes): """ Update the progress of a download progress bar. """ - self.downloads[download_id].update(downloaded_bytes) + self.download_list.update(download_id, downloaded_bytes) def cancel(self, download_id): """ Update a download progress bar to show that it has been canceled. """ - self.downloads[download_id].cancel() + self.download_list.cancel(download_id) def reset(self): """ Reset the downloads back to zero """ - for download in self.downloads.values(): - self.downloads_layout.removeWidget(download.progress_bar) - download.progress_bar.close() - self.downloads = {} + self.download_list.reset() # Hide not empty, show empty self.not_empty.hide() From b7137d4bf6ef7bbc6c65e2c42c866507492213e7 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 19:05:26 -0700 Subject: [PATCH 013/142] Slightly improve Downloads progress bar style, but still needs spacing --- onionshare/common.py | 2 +- onionshare_gui/share_mode/downloads.py | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/onionshare/common.py b/onionshare/common.py index 3489c3e6..6662ca4e 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -285,7 +285,7 @@ class Common(object): background-color: #ffffff !important; text-align: center; color: #9b9b9b; - font-size: 12px; + font-size: 14px; } QProgressBar::chunk { background-color: #4e064f; diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index 855827b1..73e8faf5 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -190,19 +190,6 @@ class Downloads(QtWidgets.QWidget): # Reset once at the beginning self.reset() - """ - # Scroll bar - self.vbar = self.verticalScrollBar() - self.vbar.rangeChanged.connect(self.resizeScroll) - """ - - def resizeScroll(self, minimum, maximum): - """ - Scroll to the bottom of the window when the range changes. - """ - pass - #self.vbar.setValue(maximum) - def add(self, download_id, total_bytes): """ Add a new download progress bar. From 5632fffc5fabc8d0139e9ed42fcd0a8d9db47bc2 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 19:54:46 -0700 Subject: [PATCH 014/142] Added an indicator count for share mode --- onionshare/common.py | 10 ++++++++++ onionshare_gui/share_mode/__init__.py | 1 + onionshare_gui/share_mode/info.py | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/onionshare/common.py b/onionshare/common.py index 6662ca4e..43a6ac43 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -279,6 +279,16 @@ class Common(object): } """, + 'download_uploads_indicator': """ + QLabel { + color: #ffffff; + background-color: #f44449; + font-weight: bold; + padding: 5px; + border-radius: 5px; + font-size: 10px; + }""", + 'downloads_uploads_progress_bar': """ QProgressBar { border: 1px solid #4e064f; diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index 0504b529..58801c45 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -224,6 +224,7 @@ class ShareMode(Mode): else: filesize = self.web.share_mode.download_filesize self.downloads.add(event["data"]["id"], filesize) + self.info.update_indicator(True) self.downloads_in_progress += 1 self.info.update_downloads_in_progress() diff --git a/onionshare_gui/share_mode/info.py b/onionshare_gui/share_mode/info.py index 3ee12a95..a191933d 100644 --- a/onionshare_gui/share_mode/info.py +++ b/onionshare_gui/share_mode/info.py @@ -51,12 +51,19 @@ class ShareModeInfo(QtWidgets.QWidget): self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) self.toggle_button.clicked.connect(self.toggle_downloads) + # Keep track of indicator + self.indicator_count = 0 + self.indicator_label = QtWidgets.QLabel() + self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) + self.update_indicator() + # Info layout layout = QtWidgets.QHBoxLayout() layout.addWidget(self.label) layout.addStretch() layout.addWidget(self.in_progress_downloads_count) layout.addWidget(self.completed_downloads_count) + layout.addWidget(self.indicator_label) layout.addWidget(self.toggle_button) self.setLayout(layout) @@ -70,6 +77,21 @@ class ShareModeInfo(QtWidgets.QWidget): self.label_text = s self.label.setText(self.label_text) + def update_indicator(self, increment=False): + """ + Update the display of the indicator count. If increment is True, then + only increment the counter if Downloads is hidden. + """ + if increment and not self.share_mode.downloads.isVisible(): + self.indicator_count += 1 + + self.indicator_label.setText("{}".format(self.indicator_count)) + + if self.indicator_count == 0: + self.indicator_label.hide() + else: + self.indicator_label.show() + def update_downloads_completed(self): """ Update the 'Downloads completed' info widget. @@ -107,6 +129,10 @@ class ShareModeInfo(QtWidgets.QWidget): self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) ) self.toggle_button.setFlat(False) + # Reset the indicator count + self.indicator_count = 0 + self.update_indicator() + self.share_mode.resize_window() def show_less(self): From a121312156c3479ce43370c721d8e717b189555e Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 28 Sep 2018 22:03:48 -0700 Subject: [PATCH 015/142] Starting to implement the new Uploads UI, but not done --- onionshare_gui/receive_mode/__init__.py | 1 + onionshare_gui/receive_mode/info.py | 26 ++++ onionshare_gui/receive_mode/uploads.py | 191 ++++++++++++++++-------- onionshare_gui/share_mode/downloads.py | 2 + onionshare_gui/share_mode/info.py | 2 +- share/locale/en.json | 2 +- 6 files changed, 157 insertions(+), 67 deletions(-) diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index 83113805..2f61b2ca 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -127,6 +127,7 @@ class ReceiveMode(Mode): Handle REQUEST_STARTED event. """ self.uploads.add(event["data"]["id"], event["data"]["content_length"]) + self.info.update_indicator(True) self.uploads_in_progress += 1 self.info.update_uploads_in_progress() diff --git a/onionshare_gui/receive_mode/info.py b/onionshare_gui/receive_mode/info.py index 0f5bc298..bc4aada8 100644 --- a/onionshare_gui/receive_mode/info.py +++ b/onionshare_gui/receive_mode/info.py @@ -46,17 +46,39 @@ class ReceiveModeInfo(QtWidgets.QWidget): self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) self.toggle_button.clicked.connect(self.toggle_uploads) + # Keep track of indicator + self.indicator_count = 0 + self.indicator_label = QtWidgets.QLabel() + self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) + self.update_indicator() + # Layout layout = QtWidgets.QHBoxLayout() layout.addStretch() layout.addWidget(self.in_progress_uploads_count) layout.addWidget(self.completed_uploads_count) + layout.addWidget(self.indicator_label) layout.addWidget(self.toggle_button) self.setLayout(layout) self.update_uploads_completed() self.update_uploads_in_progress() + def update_indicator(self, increment=False): + """ + Update the display of the indicator count. If increment is True, then + only increment the counter if Uploads is hidden. + """ + if increment and not self.receive_mode.uploads.isVisible(): + self.indicator_count += 1 + + self.indicator_label.setText("{}".format(self.indicator_count)) + + if self.indicator_count == 0: + self.indicator_label.hide() + else: + self.indicator_label.show() + def update_uploads_completed(self): """ Update the 'Uploads completed' info widget. @@ -94,6 +116,10 @@ class ReceiveModeInfo(QtWidgets.QWidget): self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle_selected.png')) ) self.toggle_button.setFlat(False) + # Reset the indicator count + self.indicator_count = 0 + self.update_indicator() + self.receive_mode.resize_window() def show_less(self): diff --git a/onionshare_gui/receive_mode/uploads.py b/onionshare_gui/receive_mode/uploads.py index 48574cc7..8cda2e61 100644 --- a/onionshare_gui/receive_mode/uploads.py +++ b/onionshare_gui/receive_mode/uploads.py @@ -206,69 +206,30 @@ class Upload(QtWidgets.QWidget): self.label.setText(text) -class Uploads(QtWidgets.QScrollArea): +class UploadList(QtWidgets.QListWidget): """ - The uploads chunk of the GUI. This lists all of the active upload - progress bars, as well as information about each upload. + List of upload progess bars. """ def __init__(self, common): - super(Uploads, self).__init__() + super(UploadList, self).__init__() self.common = common - self.common.log('Uploads', '__init__') - - self.resizeEvent = None self.uploads = {} - self.setWindowTitle(strings._('gui_uploads', True)) - self.setWidgetResizable(True) - self.setMinimumHeight(150) - self.setMinimumWidth(350) - self.setWindowIcon(QtGui.QIcon(common.get_resource_path('images/logo.png'))) - self.setWindowFlags(QtCore.Qt.Sheet | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.CustomizeWindowHint) - self.vbar = self.verticalScrollBar() - self.vbar.rangeChanged.connect(self.resizeScroll) - - uploads_label = QtWidgets.QLabel(strings._('gui_uploads', True)) - uploads_label.setStyleSheet(self.common.css['downloads_uploads_label']) - self.no_uploads_label = QtWidgets.QLabel(strings._('gui_no_uploads', True)) - self.clear_history_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) - self.clear_history_button.clicked.connect(self.reset) - self.clear_history_button.hide() - - - self.uploads_layout = QtWidgets.QVBoxLayout() - - widget = QtWidgets.QWidget() - layout = QtWidgets.QVBoxLayout() - layout.addWidget(uploads_label) - layout.addWidget(self.no_uploads_label) - layout.addWidget(self.clear_history_button) - layout.addLayout(self.uploads_layout) - layout.addStretch() - widget.setLayout(layout) - self.setWidget(widget) - - def resizeScroll(self, minimum, maximum): - """ - Scroll to the bottom of the window when the range changes. - """ - self.vbar.setValue(maximum) + self.setMinimumHeight(205) + self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) + self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) def add(self, upload_id, content_length): """ - Add a new upload. + Add a new upload progress bar. """ - self.common.log('Uploads', 'add', 'upload_id: {}, content_length: {}'.format(upload_id, content_length)) - # Hide the no_uploads_label - self.no_uploads_label.hide() - # Show the clear_history_button - self.clear_history_button.show() - - # Add it to the list upload = Upload(self.common, upload_id, content_length) self.uploads[upload_id] = upload - self.uploads_layout.addWidget(upload) + + item = QtWidgets.QListWidgetItem() + self.addItem(item) + self.setItemWidget(item, upload) def update(self, upload_id, progress): """ @@ -299,22 +260,122 @@ class Uploads(QtWidgets.QScrollArea): """ Reset the uploads back to zero """ - self.common.log('Uploads', 'reset') + # Remove all items from list + while True: + item = self.takeItem(0) + if not item: + break + + # Close all progress bars for upload in self.uploads.values(): - upload.close() - self.uploads_layout.removeWidget(upload) + upload.progress_bar.close() self.uploads = {} - self.no_uploads_label.show() - self.clear_history_button.hide() - self.resize(self.sizeHint()) - def resizeEvent(self, event): - width = self.frameGeometry().width() - try: - for upload in self.uploads.values(): - for item in upload.files.values(): - item.filename_label.setText(textwrap.fill(item.filename, 30)) - item.adjustSize() - except: - pass +class Uploads(QtWidgets.QWidget): + """ + The uploads chunk of the GUI. This lists all of the active upload + progress bars, as well as information about each upload. + """ + def __init__(self, common): + super(Uploads, self).__init__() + self.common = common + self.common.log('Uploads', '__init__') + + self.setMinimumWidth(350) + + # When there are no uploads + empty_image = QtWidgets.QLabel() + empty_image.setAlignment(QtCore.Qt.AlignCenter) + empty_image.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/uploads_transparent.png')))) + empty_text = QtWidgets.QLabel(strings._('gui_no_uploads', True)) + empty_text.setAlignment(QtCore.Qt.AlignCenter) + empty_text.setStyleSheet(self.common.css['downloads_uploads_empty_text']) + empty_layout = QtWidgets.QVBoxLayout() + empty_layout.addStretch() + empty_layout.addWidget(empty_image) + empty_layout.addWidget(empty_text) + empty_layout.addStretch() + self.empty = QtWidgets.QWidget() + self.empty.setStyleSheet(self.common.css['downloads_uploads_empty']) + self.empty.setLayout(empty_layout) + + # When there are uploads + self.upload_list = UploadList(self.common) + + # Upload header + uploads_label = QtWidgets.QLabel(strings._('gui_uploads', True)) + uploads_label.setStyleSheet(self.common.css['downloads_uploads_label']) + clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) + clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) + clear_button.setFlat(True) + clear_button.clicked.connect(self.reset) + upload_header = QtWidgets.QHBoxLayout() + upload_header.addWidget(uploads_label) + upload_header.addStretch() + upload_header.addWidget(clear_button) + + # Upload layout + not_empty_layout = QtWidgets.QVBoxLayout() + not_empty_layout.addLayout(upload_header) + not_empty_layout.addWidget(self.upload_list) + self.not_empty = QtWidgets.QWidget() + self.not_empty.setLayout(not_empty_layout) + + # Layout + layout = QtWidgets.QVBoxLayout() + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(self.empty) + layout.addWidget(self.not_empty) + self.setLayout(layout) + + # Reset once at the beginning + self.reset() + + def add(self, upload_id, content_length): + """ + Add a new upload. + """ + self.common.log('Uploads', 'add', 'upload_id: {}, content_length: {}'.format(upload_id, content_length)) + + # Hide empty, show not empty + self.empty.hide() + self.not_empty.show() + + # Add it to the list + self.upload_list.add(upload_id, content_length) + + def update(self, upload_id, progress): + """ + Update the progress of an upload. + """ + self.upload_list.update(upload_id, progress) + + def rename(self, upload_id, old_filename, new_filename): + """ + Rename a file, which happens if the filename already exists in downloads_dir. + """ + self.upload_list.rename(upload_id, old_filename, new_filename) + + def finished(self, upload_id): + """ + An upload has finished. + """ + self.upload_list.finished(upload_id) + + def cancel(self, upload_id): + """ + Update an upload progress bar to show that it has been canceled. + """ + self.common.log('Uploads', 'cancel', 'upload_id: {}'.format(upload_id)) + self.upload_list.cancel(upload_id) + + def reset(self): + """ + Reset the uploads back to zero + """ + self.upload_list.reset() + + # Hide not empty, show empty + self.not_empty.hide() + self.empty.show() diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index 73e8faf5..bb2376ef 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -194,6 +194,8 @@ class Downloads(QtWidgets.QWidget): """ Add a new download progress bar. """ + self.common.log('Downloads', 'add', 'download_id: {}, content_length: {}'.format(download_id, content_length)) + # Hide empty, show not empty self.empty.hide() self.not_empty.show() diff --git a/onionshare_gui/share_mode/info.py b/onionshare_gui/share_mode/info.py index a191933d..f8a68df7 100644 --- a/onionshare_gui/share_mode/info.py +++ b/onionshare_gui/share_mode/info.py @@ -57,7 +57,7 @@ class ShareModeInfo(QtWidgets.QWidget): self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) self.update_indicator() - # Info layout + # Layout layout = QtWidgets.QHBoxLayout() layout.addWidget(self.label) layout.addStretch() diff --git a/share/locale/en.json b/share/locale/en.json index 5821eea2..c7beb6ba 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -175,7 +175,7 @@ "systray_download_page_loaded_message": "A user loaded the download page", "systray_upload_page_loaded_message": "A user loaded the upload page", "gui_uploads": "Upload History", - "gui_no_uploads": "No uploads yet.", + "gui_no_uploads": "No Uploads Yet", "gui_clear_history": "Clear All", "gui_upload_in_progress": "Upload Started {}", "gui_upload_finished_range": "Uploaded {} to {}", From aeda4da5975e051a4cd25f667df5825ed07596f9 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 12:00:22 -0700 Subject: [PATCH 016/142] Use correct variable name for Downloads --- onionshare_gui/share_mode/downloads.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index bb2376ef..e567443a 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -92,11 +92,11 @@ class DownloadList(QtWidgets.QListWidget): self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) - def add(self, download_id, total_bytes): + def add(self, download_id, content_length): """ Add a new download progress bar. """ - download = Download(self.common, download_id, total_bytes) + download = Download(self.common, download_id, content_length) self.downloads[download_id] = download item = QtWidgets.QListWidgetItem() @@ -190,7 +190,7 @@ class Downloads(QtWidgets.QWidget): # Reset once at the beginning self.reset() - def add(self, download_id, total_bytes): + def add(self, download_id, content_length): """ Add a new download progress bar. """ @@ -201,7 +201,7 @@ class Downloads(QtWidgets.QWidget): self.not_empty.show() # Add it to the list - self.download_list.add(download_id, total_bytes) + self.download_list.add(download_id, content_length) def update(self, download_id, downloaded_bytes): """ From b697e51d21988b2632fa517d70aeff024e909dc9 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 12:19:01 -0700 Subject: [PATCH 017/142] Switch Downloads from QListWidget to QScrollArea --- onionshare_gui/share_mode/downloads.py | 44 ++++++++++++++++---------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index e567443a..8eade23c 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -23,8 +23,9 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings -class Download(object): +class Download(QtWidgets.QWidget): def __init__(self, common, download_id, total_bytes): + super(Download, self).__init__() self.common = common self.download_id = download_id @@ -32,6 +33,8 @@ class Download(object): self.total_bytes = total_bytes self.downloaded_bytes = 0 + self.setStyleSheet('QWidget { border: 1px solid red; }') + # Progress bar self.progress_bar = QtWidgets.QProgressBar() self.progress_bar.setTextVisible(True) @@ -43,6 +46,11 @@ class Download(object): self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar']) self.progress_bar.total_bytes = total_bytes + # Layout + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.progress_bar) + self.setLayout(layout) + # Start at 0 self.update(0) @@ -78,9 +86,9 @@ class Download(object): self.started) -class DownloadList(QtWidgets.QListWidget): +class DownloadList(QtWidgets.QScrollArea): """ - List of download progess bars. + List of download progress bars. """ def __init__(self, common): super(DownloadList, self).__init__() @@ -88,9 +96,20 @@ class DownloadList(QtWidgets.QListWidget): self.downloads = {} - self.setMinimumHeight(205) - self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) - self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) + self.downloads_layout = QtWidgets.QVBoxLayout() + self.downloads_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) + widget = QtWidgets.QWidget() + widget.setLayout(self.downloads_layout) + self.setWidget(widget) + + self.setBackgroundRole(QtGui.QPalette.Light) + self.verticalScrollBar().rangeChanged.connect(self.resizeScroll) + + def resizeScroll(self, minimum, maximum): + """ + Scroll to the bottom of the window when the range changes. + """ + self.verticalScrollBar().setValue(maximum) def add(self, download_id, content_length): """ @@ -98,10 +117,7 @@ class DownloadList(QtWidgets.QListWidget): """ download = Download(self.common, download_id, content_length) self.downloads[download_id] = download - - item = QtWidgets.QListWidgetItem() - self.addItem(item) - self.setItemWidget(item, download.progress_bar) + self.downloads_layout.addWidget(download) def update(self, download_id, downloaded_bytes): """ @@ -119,14 +135,8 @@ class DownloadList(QtWidgets.QListWidget): """ Reset the downloads back to zero """ - # Remove all items from list - while True: - item = self.takeItem(0) - if not item: - break - - # Close all progress bars for download in self.downloads.values(): + self.downloads_layout.removeWidget(download.progress_bar) download.progress_bar.close() self.downloads = {} From 05ec529d966cf312bbca4f03610a6fecbbf9893b Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 13:41:12 -0700 Subject: [PATCH 018/142] Fix Downloads scroll area so internal widget is always the right size --- onionshare_gui/share_mode/downloads.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index 8eade23c..50e7f0ef 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -96,12 +96,24 @@ class DownloadList(QtWidgets.QScrollArea): self.downloads = {} + # The layout that holds all of the downloads self.downloads_layout = QtWidgets.QVBoxLayout() + self.downloads_layout.setContentsMargins(0, 0, 0, 0) self.downloads_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) - widget = QtWidgets.QWidget() - widget.setLayout(self.downloads_layout) - self.setWidget(widget) + # Wrapper layout that also contains a stretch + wrapper_layout = QtWidgets.QVBoxLayout() + wrapper_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) + wrapper_layout.addLayout(self.downloads_layout) + wrapper_layout.addStretch() + + # The internal widget of the scroll area + widget = QtWidgets.QWidget() + widget.setLayout(wrapper_layout) + self.setWidget(widget) + self.setWidgetResizable(True) + + # Other scroll area settings self.setBackgroundRole(QtGui.QPalette.Light) self.verticalScrollBar().rangeChanged.connect(self.resizeScroll) From cbe882f2ebf17e6ff22aa34330e49b7de157e206 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 13:47:00 -0700 Subject: [PATCH 019/142] Convert Uploads to a QScrollArea also --- onionshare_gui/receive_mode/uploads.py | 44 +++++++++++++++++--------- onionshare_gui/share_mode/downloads.py | 2 +- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/onionshare_gui/receive_mode/uploads.py b/onionshare_gui/receive_mode/uploads.py index 8cda2e61..f08b35cc 100644 --- a/onionshare_gui/receive_mode/uploads.py +++ b/onionshare_gui/receive_mode/uploads.py @@ -206,7 +206,7 @@ class Upload(QtWidgets.QWidget): self.label.setText(text) -class UploadList(QtWidgets.QListWidget): +class UploadList(QtWidgets.QScrollArea): """ List of upload progess bars. """ @@ -216,9 +216,32 @@ class UploadList(QtWidgets.QListWidget): self.uploads = {} - self.setMinimumHeight(205) - self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) - self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) + # The layout that holds all of the uploads + self.uploads_layout = QtWidgets.QVBoxLayout() + self.uploads_layout.setContentsMargins(0, 0, 0, 0) + self.uploads_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) + + # Wrapper layout that also contains a stretch + wrapper_layout = QtWidgets.QVBoxLayout() + wrapper_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) + wrapper_layout.addLayout(self.uploads_layout) + wrapper_layout.addStretch() + + # The internal widget of the scroll area + widget = QtWidgets.QWidget() + widget.setLayout(wrapper_layout) + self.setWidget(widget) + self.setWidgetResizable(True) + + # Other scroll area settings + self.setBackgroundRole(QtGui.QPalette.Light) + self.verticalScrollBar().rangeChanged.connect(self.resizeScroll) + + def resizeScroll(self, minimum, maximum): + """ + Scroll to the bottom of the window when the range changes. + """ + self.verticalScrollBar().setValue(maximum) def add(self, upload_id, content_length): """ @@ -226,10 +249,7 @@ class UploadList(QtWidgets.QListWidget): """ upload = Upload(self.common, upload_id, content_length) self.uploads[upload_id] = upload - - item = QtWidgets.QListWidgetItem() - self.addItem(item) - self.setItemWidget(item, upload) + self.uploads_layout.addWidget(upload) def update(self, upload_id, progress): """ @@ -260,14 +280,8 @@ class UploadList(QtWidgets.QListWidget): """ Reset the uploads back to zero """ - # Remove all items from list - while True: - item = self.takeItem(0) - if not item: - break - - # Close all progress bars for upload in self.uploads.values(): + self.uploads_layout.removeWidget(upload) upload.progress_bar.close() self.uploads = {} diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index 50e7f0ef..e78231ad 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -148,7 +148,7 @@ class DownloadList(QtWidgets.QScrollArea): Reset the downloads back to zero """ for download in self.downloads.values(): - self.downloads_layout.removeWidget(download.progress_bar) + self.downloads_layout.removeWidget(download) download.progress_bar.close() self.downloads = {} From 554f6e1b48bdf93ccc9fa18213eee96a6ca021cc Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 14:40:55 -0700 Subject: [PATCH 020/142] Got the indicator label to display in the correct location for share mode --- onionshare/common.py | 5 +++-- onionshare_gui/share_mode/info.py | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/onionshare/common.py b/onionshare/common.py index 43a6ac43..fb3b1e7a 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -284,9 +284,10 @@ class Common(object): color: #ffffff; background-color: #f44449; font-weight: bold; - padding: 5px; - border-radius: 5px; font-size: 10px; + padding: 2px; + border-radius: 8px; + text-align: center; }""", 'downloads_uploads_progress_bar': """ diff --git a/onionshare_gui/share_mode/info.py b/onionshare_gui/share_mode/info.py index f8a68df7..b69820d6 100644 --- a/onionshare_gui/share_mode/info.py +++ b/onionshare_gui/share_mode/info.py @@ -45,7 +45,7 @@ class ShareModeInfo(QtWidgets.QWidget): # Toggle button self.toggle_button = QtWidgets.QPushButton() self.toggle_button.setDefault(False) - self.toggle_button.setFixedWidth(30) + self.toggle_button.setFixedWidth(35) self.toggle_button.setFixedHeight(30) self.toggle_button.setFlat(True) self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) @@ -53,17 +53,24 @@ class ShareModeInfo(QtWidgets.QWidget): # Keep track of indicator self.indicator_count = 0 - self.indicator_label = QtWidgets.QLabel() + self.indicator_label = QtWidgets.QLabel(parent=self.toggle_button) self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) self.update_indicator() + """ + # Add it to the toggle button + toggle_button_layout = QtWidgets.QHBoxLayout() + toggle_button_layout.addSpacing(10) + toggle_button_layout.addWidget(self.indicator_label) + self.toggle_button.setLayout(toggle_button_layout) + """ + # Layout layout = QtWidgets.QHBoxLayout() layout.addWidget(self.label) layout.addStretch() layout.addWidget(self.in_progress_downloads_count) layout.addWidget(self.completed_downloads_count) - layout.addWidget(self.indicator_label) layout.addWidget(self.toggle_button) self.setLayout(layout) @@ -90,6 +97,8 @@ class ShareModeInfo(QtWidgets.QWidget): if self.indicator_count == 0: self.indicator_label.hide() else: + size = self.indicator_label.sizeHint() + self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) self.indicator_label.show() def update_downloads_completed(self): From 3f3ec611b2c607628af3ceb3994c4594f7e46219 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 14:43:13 -0700 Subject: [PATCH 021/142] Fix indicator label display for receive mode --- onionshare_gui/receive_mode/info.py | 7 ++++--- onionshare_gui/share_mode/info.py | 8 -------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/onionshare_gui/receive_mode/info.py b/onionshare_gui/receive_mode/info.py index bc4aada8..c23f8496 100644 --- a/onionshare_gui/receive_mode/info.py +++ b/onionshare_gui/receive_mode/info.py @@ -40,7 +40,7 @@ class ReceiveModeInfo(QtWidgets.QWidget): # Toggle button self.toggle_button = QtWidgets.QPushButton() self.toggle_button.setDefault(False) - self.toggle_button.setFixedWidth(30) + self.toggle_button.setFixedWidth(35) self.toggle_button.setFixedHeight(30) self.toggle_button.setFlat(True) self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) @@ -48,7 +48,7 @@ class ReceiveModeInfo(QtWidgets.QWidget): # Keep track of indicator self.indicator_count = 0 - self.indicator_label = QtWidgets.QLabel() + self.indicator_label = QtWidgets.QLabel(parent=self.toggle_button) self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) self.update_indicator() @@ -57,7 +57,6 @@ class ReceiveModeInfo(QtWidgets.QWidget): layout.addStretch() layout.addWidget(self.in_progress_uploads_count) layout.addWidget(self.completed_uploads_count) - layout.addWidget(self.indicator_label) layout.addWidget(self.toggle_button) self.setLayout(layout) @@ -77,6 +76,8 @@ class ReceiveModeInfo(QtWidgets.QWidget): if self.indicator_count == 0: self.indicator_label.hide() else: + size = self.indicator_label.sizeHint() + self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) self.indicator_label.show() def update_uploads_completed(self): diff --git a/onionshare_gui/share_mode/info.py b/onionshare_gui/share_mode/info.py index b69820d6..c692649c 100644 --- a/onionshare_gui/share_mode/info.py +++ b/onionshare_gui/share_mode/info.py @@ -57,14 +57,6 @@ class ShareModeInfo(QtWidgets.QWidget): self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) self.update_indicator() - """ - # Add it to the toggle button - toggle_button_layout = QtWidgets.QHBoxLayout() - toggle_button_layout.addSpacing(10) - toggle_button_layout.addWidget(self.indicator_label) - self.toggle_button.setLayout(toggle_button_layout) - """ - # Layout layout = QtWidgets.QHBoxLayout() layout.addWidget(self.label) From f9568caf818598197dd26647c5367199ac67cc7e Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 14:49:06 -0700 Subject: [PATCH 022/142] Fix crash when clicking Help from the systray --- onionshare_gui/onionshare_gui.py | 2 +- onionshare_gui/settings_dialog.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 51190ea3..dd15fe12 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -65,7 +65,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.settings_action = menu.addAction(strings._('gui_settings_window_title', True)) self.settings_action.triggered.connect(self.open_settings) help_action = menu.addAction(strings._('gui_settings_button_help', True)) - help_action.triggered.connect(SettingsDialog.help_clicked) + help_action.triggered.connect(SettingsDialog.open_help) exit_action = menu.addAction(strings._('systray_menu_exit', True)) exit_action.triggered.connect(self.close) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 3cd25d31..39f08128 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -883,8 +883,12 @@ class SettingsDialog(QtWidgets.QDialog): Help button clicked. """ self.common.log('SettingsDialog', 'help_clicked') - help_site = 'https://github.com/micahflee/onionshare/wiki' - QtGui.QDesktopServices.openUrl(QtCore.QUrl(help_site)) + SettingsDialog.open_help() + + @staticmethod + def open_help(): + help_url = 'https://github.com/micahflee/onionshare/wiki' + QtGui.QDesktopServices.openUrl(QtCore.QUrl(help_url)) def settings_from_fields(self): """ From cae9ca4b721c55d13982cc283ffdae6ebc677f5c Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 15:12:05 -0700 Subject: [PATCH 023/142] Increase minimum window with to 460, and store it in a variable to stop repeating myself --- onionshare_gui/mode.py | 4 ++-- onionshare_gui/onionshare_gui.py | 4 +++- onionshare_gui/receive_mode/__init__.py | 2 +- onionshare_gui/share_mode/__init__.py | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/onionshare_gui/mode.py b/onionshare_gui/mode.py index 0fba029b..1a961149 100644 --- a/onionshare_gui/mode.py +++ b/onionshare_gui/mode.py @@ -50,7 +50,7 @@ class Mode(QtWidgets.QWidget): self.filenames = filenames - self.setMinimumWidth(450) + self.setMinimumWidth(self.common.min_window_width) # The web object gets created in init() self.web = None @@ -83,7 +83,7 @@ class Mode(QtWidgets.QWidget): # Hack to allow a minimum width on the main layout # Note: It's up to the downstream Mode to add this to its layout self.min_width_widget = QtWidgets.QWidget() - self.min_width_widget.setMinimumWidth(450) + self.min_width_widget.setMinimumWidth(self.common.min_window_width) def init(self): """ diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index dd15fe12..ced53ede 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -45,6 +45,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.common = common self.common.log('OnionShareGui', '__init__') + self.common.min_window_width = 460 self.onion = onion self.qtapp = qtapp @@ -169,7 +170,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.show() # Adjust window size, to start with a minimum window width - self.adjust_size(450) + self.adjust_size(self.common.min_window_width) # The server isn't active yet self.set_server_active(False) @@ -474,6 +475,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # Adjust sizes of each mode for mode in [self.share_mode, self.receive_mode]: + self.qtapp.processEvents() adjust_size_widget(mode) # Adjust window size diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index 2f61b2ca..6430382b 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -194,7 +194,7 @@ class ReceiveMode(Mode): self.resize_window() def resize_window(self): - min_width = 450 + min_width = self.common.min_window_width if self.uploads.isVisible(): min_width += 300 self.adjust_size.emit(min_width) diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index 58801c45..c44e8beb 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -317,7 +317,7 @@ class ShareMode(Mode): self.downloads.reset() def resize_window(self): - min_width = 450 + min_width = self.common.min_window_width if self.downloads.isVisible(): min_width += 300 self.adjust_size.emit(min_width) From e9d1a88aa4885ff572542a36340e4e062fee6c06 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 18:24:11 -0700 Subject: [PATCH 024/142] Fix local GUI tests so they pass --- tests_gui_local/commontests.py | 47 +++++++++------ .../onionshare_receive_mode_upload_test.py | 12 ++-- ...re_receive_mode_upload_test_public_mode.py | 22 ++++--- .../onionshare_share_mode_download_test.py | 52 ++++++++++------- ...re_share_mode_download_test_public_mode.py | 52 ++++++++++------- ...hare_share_mode_download_test_stay_open.py | 58 +++++++++++-------- .../onionshare_slug_persistent_test.py | 42 ++++++++------ tests_gui_local/onionshare_timer_test.py | 8 +-- 8 files changed, 171 insertions(+), 122 deletions(-) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/commontests.py index de1ad9ab..870c2dbe 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/commontests.py @@ -24,19 +24,13 @@ class CommonTests(object): '''Test that the status bar is visible''' self.assertTrue(self.gui.status_bar.isVisible()) - def test_info_widget_is_not_visible(self, mode): - '''Test that the info widget along top of screen is not shown''' - if mode == 'receive': - self.assertFalse(self.gui.receive_mode.info_widget.isVisible()) + def test_info_widget_shows_less(self, mode): + '''Test that minimum information (no label) is displayed in the info bar''' if mode == 'share': - self.assertFalse(self.gui.share_mode.info_widget.isVisible()) - - def test_info_widget_is_visible(self, mode): - '''Test that the info widget along top of screen is shown''' + self.assertFalse(self.gui.share_mode.info.label.text() == "") if mode == 'receive': - self.assertTrue(self.gui.receive_mode.info_widget.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.info_widget.isVisible()) + # There's no minimal display in receive mode + self.assertTrue(False) def test_click_mode(self, mode): '''Test that we can switch Mode by clicking the button''' @@ -47,14 +41,30 @@ class CommonTests(object): QtTest.QTest.mouseClick(self.gui.share_mode_button, QtCore.Qt.LeftButton) self.assertTrue(self.gui.mode, self.gui.MODE_SHARE) + def test_click_toggle_history(self, mode): + '''Test that we can toggle Download or Upload history by clicking the toggle button''' + if mode == 'receive': + currently_visible = self.gui.receive_mode.uploads.isVisible() + QtTest.QTest.mouseClick(self.gui.receive_mode.info.toggle_button, QtCore.Qt.LeftButton) + self.assertEqual(self.gui.receive_mode.uploads.isVisible(), not currently_visible) + if mode == 'share': + currently_visible = self.gui.receive_mode.uploads.isVisible() + QtTest.QTest.mouseClick(self.gui.share_mode.info.toggle_button, QtCore.Qt.LeftButton) + self.assertEqual(self.gui.share_mode.downloads.isVisible(), not currently_visible) + + def test_history_is_not_visible(self, mode): + '''Test that the History section is not visible''' + if mode == 'receive': + self.assertFalse(self.gui.receive_mode.uploads.isVisible()) + if mode == 'share': + self.assertFalse(self.gui.share_mode.downloads.isVisible()) + def test_history_is_visible(self, mode): - '''Test that the History section is visible and that the relevant widget is present''' + '''Test that the History section is visible''' if mode == 'receive': self.assertTrue(self.gui.receive_mode.uploads.isVisible()) - self.assertTrue(self.gui.receive_mode.uploads.no_uploads_label.isVisible()) if mode == 'share': self.assertTrue(self.gui.share_mode.downloads.isVisible()) - self.assertTrue(self.gui.share_mode.downloads.no_downloads_label.isVisible()) def test_server_working_on_start_button_pressed(self, mode): '''Test we can start the service''' @@ -161,11 +171,11 @@ class CommonTests(object): def test_history_widgets_present(self, mode): '''Test that the relevant widgets are present in the history view after activity has taken place''' if mode == 'receive': - self.assertFalse(self.gui.receive_mode.uploads.no_uploads_label.isVisible()) - self.assertTrue(self.gui.receive_mode.uploads.clear_history_button.isVisible()) + self.assertFalse(self.gui.receive_mode.uploads.empty.isVisible()) + self.assertTrue(self.gui.receive_mode.uploads.not_empty.isVisible()) if mode == 'share': - self.assertFalse(self.gui.share_mode.downloads.no_downloads_label.isVisible()) - self.assertTrue(self.gui.share_mode.downloads.clear_history_button.isVisible()) + self.assertFalse(self.gui.share_mode.downloads.empty.isVisible()) + self.assertTrue(self.gui.share_mode.downloads.not_empty.isVisible()) def test_counter_incremented(self, mode, count): '''Test that the counter has incremented''' @@ -304,4 +314,3 @@ class CommonTests(object): def test_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()) - diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index 2aa2ed94..b53d5c06 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -94,15 +94,19 @@ class OnionShareGuiTest(unittest.TestCase): def test_server_status_bar_is_visible(self): CommonTests.test_server_status_bar_is_visible(self) - @pytest.mark.run(order=5) - def test_info_widget_is_not_visible(self): - CommonTests.test_info_widget_is_not_visible(self, 'receive') - @pytest.mark.run(order=6) def test_click_mode(self): CommonTests.test_click_mode(self, 'receive') + @pytest.mark.run(order=6) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'receive') + @pytest.mark.run(order=7) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'receive') + + @pytest.mark.run(order=8) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'receive') diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py index 30a290e7..5e5a6b77 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py @@ -95,34 +95,38 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_server_status_bar_is_visible(self) @pytest.mark.run(order=5) - def test_info_widget_is_not_visible(self): - CommonTests.test_info_widget_is_not_visible(self, 'receive') - - @pytest.mark.run(order=6) def test_click_mode(self): CommonTests.test_click_mode(self, 'receive') + @pytest.mark.run(order=6) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'receive') + @pytest.mark.run(order=7) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'receive') + + @pytest.mark.run(order=8) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'receive') - @pytest.mark.run(order=8) + @pytest.mark.run(order=9) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'receive') - @pytest.mark.run(order=9) + @pytest.mark.run(order=10) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'receive') - @pytest.mark.run(order=10) + @pytest.mark.run(order=11) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=12) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'receive') - @pytest.mark.run(order=12) + @pytest.mark.run(order=13) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index c546fb61..40df6d98 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -97,90 +97,98 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', False) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_web_page(self): CommonTests.test_web_page(self, 'share', 'Total size', False) - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_download_share(self): CommonTests.test_download_share(self, False) - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_history_widgets_present(self): CommonTests.test_history_widgets_present(self, 'share') - @pytest.mark.run(order=24) + @pytest.mark.run(order=26) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', False) - @pytest.mark.run(order=25) + @pytest.mark.run(order=27) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=26) + @pytest.mark.run(order=28) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'share', False) - @pytest.mark.run(order=27) + @pytest.mark.run(order=29) def test_add_button_visible(self): CommonTests.test_add_button_visible(self) diff --git a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py index 764b5885..73d4c999 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py +++ b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py @@ -97,90 +97,98 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', True) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_web_page(self): CommonTests.test_web_page(self, 'share', 'Total size', True) - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_download_share(self): CommonTests.test_download_share(self, True) - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_history_widgets_present(self): CommonTests.test_history_widgets_present(self, 'share') - @pytest.mark.run(order=24) + @pytest.mark.run(order=26) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', False) - @pytest.mark.run(order=25) + @pytest.mark.run(order=27) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=26) + @pytest.mark.run(order=28) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'share', False) - @pytest.mark.run(order=27) + @pytest.mark.run(order=29) def test_add_button_visible(self): CommonTests.test_add_button_visible(self) diff --git a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py index b92ff097..e849d224 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py +++ b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py @@ -97,102 +97,110 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', True) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_web_page(self): CommonTests.test_web_page(self, 'share', 'Total size', True) - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_download_share(self): CommonTests.test_download_share(self, True) - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_history_widgets_present(self): CommonTests.test_history_widgets_present(self, 'share') - @pytest.mark.run(order=24) + @pytest.mark.run(order=26) def test_counter_incremented(self): CommonTests.test_counter_incremented(self, 'share', 1) - @pytest.mark.run(order=25) + @pytest.mark.run(order=27) def test_download_share_again(self): CommonTests.test_download_share(self, True) - @pytest.mark.run(order=26) + @pytest.mark.run(order=28) def test_counter_incremented_again(self): CommonTests.test_counter_incremented(self, 'share', 2) - @pytest.mark.run(order=27) + @pytest.mark.run(order=29) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', True) - @pytest.mark.run(order=28) + @pytest.mark.run(order=30) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=29) + @pytest.mark.run(order=31) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'share', True) - @pytest.mark.run(order=30) + @pytest.mark.run(order=32) def test_add_button_visible(self): CommonTests.test_add_button_visible(self) diff --git a/tests_gui_local/onionshare_slug_persistent_test.py b/tests_gui_local/onionshare_slug_persistent_test.py index 1e5614dc..5b53f7e0 100644 --- a/tests_gui_local/onionshare_slug_persistent_test.py +++ b/tests_gui_local/onionshare_slug_persistent_test.py @@ -94,68 +94,76 @@ class OnionShareGuiTest(unittest.TestCase): def test_server_status_bar_is_visible(self): CommonTests.test_server_status_bar_is_visible(self) - @pytest.mark.run(order=5) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') - @pytest.mark.run(order=6) + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') + + @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=7) + @pytest.mark.run(order=10) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=11) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=9) + @pytest.mark.run(order=12) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=13) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=11) + @pytest.mark.run(order=14) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=12) + @pytest.mark.run(order=15) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', False) global slug slug = self.gui.share_mode.server_status.web.slug - @pytest.mark.run(order=13) + @pytest.mark.run(order=16) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=14) + @pytest.mark.run(order=17) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', True) - @pytest.mark.run(order=15) + @pytest.mark.run(order=18) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=16) + @pytest.mark.run(order=19) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'share', True) - @pytest.mark.run(order=17) + @pytest.mark.run(order=20) def test_server_started_again(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') CommonTests.test_server_status_indicator_says_starting(self, 'share') CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=18) + @pytest.mark.run(order=21) def test_have_same_slug(self): '''Test that we have the same slug''' self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) - @pytest.mark.run(order=19) + @pytest.mark.run(order=22) def test_server_is_stopped_again(self): CommonTests.test_server_is_stopped(self, 'share', True) CommonTests.test_web_service_is_stopped(self) diff --git a/tests_gui_local/onionshare_timer_test.py b/tests_gui_local/onionshare_timer_test.py index 1a5134e2..701d9a21 100644 --- a/tests_gui_local/onionshare_timer_test.py +++ b/tests_gui_local/onionshare_timer_test.py @@ -97,12 +97,12 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') @pytest.mark.run(order=8) def test_set_timeout(self): From 9fc17037e53e0d4732495221a95ab34b331e8d71 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sat, 29 Sep 2018 18:58:27 -0700 Subject: [PATCH 025/142] Begin refactoring Tor tests to inherit from local tests --- tests_gui_local/__init__.py | 8 + tests_gui_tor/commontests.py | 311 +---------------------------------- 2 files changed, 10 insertions(+), 309 deletions(-) diff --git a/tests_gui_local/__init__.py b/tests_gui_local/__init__.py index e69de29b..76e5b1b9 100644 --- a/tests_gui_local/__init__.py +++ b/tests_gui_local/__init__.py @@ -0,0 +1,8 @@ +from .onionshare_receive_mode_upload_test_public_mode import OnionShareGuiTest as ReceiveMoveUploadTestPublicMode +from .onionshare_receive_mode_upload_test import OnionShareGuiTest as ReceiveModeUploadTest +from .onionshare_share_mode_download_test_public_mode import OnionShareGuiTest as ShareModeDownloadTestPublicMode +from .onionshare_share_mode_download_test import OnionShareGuiTest as ShareModeDownloadTest +from .onionshare_share_mode_download_test_stay_open import OnionShareGuiTest as ShareModeDownloadTestStayOpen +from .onionshare_slug_persistent_test import OnionShareGuiTest as SlugPersistentTest +from .onionshare_timer_test import OnionShareGuiTest as TimerTest +from .commontests import CommonTests diff --git a/tests_gui_tor/commontests.py b/tests_gui_tor/commontests.py index a0d9bf5f..ea37279f 100644 --- a/tests_gui_tor/commontests.py +++ b/tests_gui_tor/commontests.py @@ -7,207 +7,13 @@ import zipfile from PyQt5 import QtCore, QtTest from onionshare import strings -class CommonTests(object): - def test_gui_loaded(self): - '''Test that the GUI actually is shown''' - self.assertTrue(self.gui.show) - - def test_windowTitle_seen(self): - '''Test that the window title is OnionShare''' - self.assertEqual(self.gui.windowTitle(), 'OnionShare') - - def test_settings_button_is_visible(self): - '''Test that the settings button is visible''' - self.assertTrue(self.gui.settings_button.isVisible()) - - def test_server_status_bar_is_visible(self): - '''Test that the status bar is visible''' - self.assertTrue(self.gui.status_bar.isVisible()) - - def test_info_widget_is_not_visible(self, mode): - '''Test that the info widget along top of screen is not shown''' - if mode == 'receive': - self.assertFalse(self.gui.receive_mode.info_widget.isVisible()) - if mode == 'share': - self.assertFalse(self.gui.share_mode.info_widget.isVisible()) - - def test_info_widget_is_visible(self, mode): - '''Test that the info widget along top of screen is shown''' - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.info_widget.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.info_widget.isVisible()) - - def test_click_mode(self, mode): - '''Test that we can switch Mode by clicking the button''' - if mode == 'receive': - QtTest.QTest.mouseClick(self.gui.receive_mode_button, QtCore.Qt.LeftButton) - self.assertTrue(self.gui.mode, self.gui.MODE_RECEIVE) - if mode == 'share': - QtTest.QTest.mouseClick(self.gui.share_mode_button, QtCore.Qt.LeftButton) - self.assertTrue(self.gui.mode, self.gui.MODE_SHARE) - - def test_history_is_visible(self, mode): - '''Test that the History section is visible and that the relevant widget is present''' - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.uploads.isVisible()) - self.assertTrue(self.gui.receive_mode.uploads.no_uploads_label.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.downloads.isVisible()) - self.assertTrue(self.gui.share_mode.downloads.no_downloads_label.isVisible()) - - def test_server_working_on_start_button_pressed(self, mode): - '''Test we can start the service''' - # Should be in SERVER_WORKING state - if mode == 'receive': - QtTest.QTest.mouseClick(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.receive_mode.server_status.status, 1) - if mode == 'share': - QtTest.QTest.mouseClick(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.share_mode.server_status.status, 1) - - def test_server_status_indicator_says_starting(self, mode): - '''Test that the Server Status indicator shows we are Starting''' - if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) - if mode == 'share': - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) - - def test_settings_button_is_hidden(self): - '''Test that the settings button is hidden when the server starts''' - self.assertFalse(self.gui.settings_button.isVisible()) - - def test_a_server_is_started(self, mode): - '''Test that the server has started''' - QtTest.QTest.qWait(45000) - # Should now be in SERVER_STARTED state - if mode == 'receive': - self.assertEqual(self.gui.receive_mode.server_status.status, 2) - if mode == 'share': - self.assertEqual(self.gui.share_mode.server_status.status, 2) - - def test_a_web_server_is_running(self): - '''Test that the web server has started''' - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - self.assertEqual(sock.connect_ex(('127.0.0.1',self.gui.app.port)), 0) - - def test_have_a_slug(self, mode, public_mode): - '''Test that we have a valid slug''' - if mode == 'receive': - if not public_mode: - self.assertRegex(self.gui.receive_mode.server_status.web.slug, r'(\w+)-(\w+)') - else: - self.assertIsNone(self.gui.receive_mode.server_status.web.slug, r'(\w+)-(\w+)') - if mode == 'share': - if not public_mode: - self.assertRegex(self.gui.share_mode.server_status.web.slug, r'(\w+)-(\w+)') - else: - self.assertIsNone(self.gui.share_mode.server_status.web.slug, r'(\w+)-(\w+)') +from tests_gui_local import CommonTests as LocalCommonTests +class CommonTests(LocalCommonTests): def test_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 test_url_description_shown(self, mode): - '''Test that the URL label is showing''' - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.server_status.url_description.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.server_status.url_description.isVisible()) - - def test_have_copy_url_button(self, mode): - '''Test that the Copy URL button is shown''' - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.server_status.copy_url_button.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.server_status.copy_url_button.isVisible()) - - def test_server_status_indicator_says_started(self, mode): - '''Test that the Server Status indicator shows we are started''' - if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) - if mode == 'share': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) - - def test_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: - if mode == 'receive': - path = '/{}'.format(self.gui.receive_mode.server_status.web.slug) - if mode == 'share': - path = '/{}'.format(self.gui.share_mode.server_status.web.slug) - else: - path = '/' - - http_request = 'GET {} HTTP/1.0\r\n'.format(path) - http_request += 'Host: {}\r\n'.format(self.gui.app.onion_host) - 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 test_history_widgets_present(self, mode): - '''Test that the relevant widgets are present in the history view after activity has taken place''' - if mode == 'receive': - self.assertFalse(self.gui.receive_mode.uploads.no_uploads_label.isVisible()) - self.assertTrue(self.gui.receive_mode.uploads.clear_history_button.isVisible()) - if mode == 'share': - self.assertFalse(self.gui.share_mode.downloads.no_downloads_label.isVisible()) - self.assertTrue(self.gui.share_mode.downloads.clear_history_button.isVisible()) - - def test_counter_incremented(self, mode, count): - '''Test that the counter has incremented''' - if mode == 'receive': - self.assertEquals(self.gui.receive_mode.uploads_completed, count) - if mode == 'share': - self.assertEquals(self.gui.share_mode.downloads_completed, count) - - def test_server_is_stopped(self, mode, stay_open): - '''Test that the server stops when we click Stop''' - if mode == 'receive': - QtTest.QTest.mouseClick(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.receive_mode.server_status.status, 0) - if mode == 'share': - if stay_open: - QtTest.QTest.mouseClick(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.share_mode.server_status.status, 0) - - def test_web_service_is_stopped(self): - '''Test that the web server also stopped''' - QtTest.QTest.qWait(2000) - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - - # We should be closed by now. Fail if not! - self.assertNotEqual(sock.connect_ex(('127.0.0.1',self.gui.app.port)), 0) - - def test_server_status_indicator_says_closed(self, mode, stay_open): - '''Test that the Server Status indicator shows we closed''' - if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) - if mode == 'share': - if stay_open: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) - else: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically', True)) - def test_cancel_the_share(self, mode): '''Test that we can cancel this share before it's started up ''' if mode == 'share': @@ -222,119 +28,6 @@ class CommonTests(object): QtTest.QTest.mouseRelease(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) self.assertEqual(self.gui.receive_mode.server_status.status, 0) - - # Auto-stop timer tests - def test_set_timeout(self, mode, timeout): - '''Test that the timeout can be set''' - timer = QtCore.QDateTime.currentDateTime().addSecs(timeout) - if mode == 'receive': - self.gui.receive_mode.server_status.shutdown_timeout.setDateTime(timer) - self.assertTrue(self.gui.receive_mode.server_status.shutdown_timeout.dateTime(), timer) - if mode == 'share': - self.gui.share_mode.server_status.shutdown_timeout.setDateTime(timer) - self.assertTrue(self.gui.share_mode.server_status.shutdown_timeout.dateTime(), timer) - - def test_timeout_widget_hidden(self, mode): - '''Test that the timeout widget is hidden when share has started''' - if mode == 'receive': - self.assertFalse(self.gui.receive_mode.server_status.shutdown_timeout_container.isVisible()) - if mode == 'share': - self.assertFalse(self.gui.share_mode.server_status.shutdown_timeout_container.isVisible()) - - def test_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 - if mode == 'receive': - self.assertEqual(self.gui.receive_mode.server_status.status, 0) - if mode == 'share': - self.assertEqual(self.gui.share_mode.server_status.status, 0) - - # Receive-specific tests - def test_upload_file(self, public_mode, 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'] = 'socks5h://{}:{}'.format(socks_address, socks_port) - - files = {'file[]': open('/tmp/test.txt', 'rb')} - if not public_mode: - path = 'http://{}/{}/upload'.format(self.gui.app.onion_host, self.gui.receive_mode.web.slug) - else: - path = 'http://{}/upload'.format(self.gui.app.onion_host) - response = session.post(path, files=files) - QtTest.QTest.qWait(4000) - self.assertTrue(os.path.isfile(expected_file)) - - # Share-specific tests - def test_file_selection_widget_has_a_file(self): - '''Test that the number of files in the list is 1''' - self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 1) - - def test_deleting_only_file_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, and since there's no more files, the delete button should be hidden - QtTest.QTest.mouseClick(self.gui.share_mode.server_status.file_selection.delete_button, QtCore.Qt.LeftButton) - self.assertFalse(self.gui.share_mode.server_status.file_selection.delete_button.isVisible()) - - def test_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.assertEquals(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) - - def test_file_selection_widget_readd_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.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 2) - - def test_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 test_download_share(self, public_mode): - '''Test that we can download the share''' - (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 public_mode: - path = '/download' - else: - path = '{}/download'.format(self.gui.share_mode.web.slug) - - http_request = 'GET {} HTTP/1.0\r\n'.format(path) - http_request += 'Host: {}\r\n'.format(self.gui.app.onion_host) - http_request += '\r\n' - s.sendall(http_request.encode('utf-8')) - - with open('/tmp/download.zip', 'wb') as file_to_write: - while True: - data = s.recv(1024) - if not data: - break - file_to_write.write(data) - file_to_write.close() - - zip = zipfile.ZipFile('/tmp/download.zip') - QtTest.QTest.qWait(4000) - self.assertEquals('onionshare', zip.read('test.txt').decode('utf-8')) - - def test_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()) - - # Stealth tests def test_copy_have_hidserv_auth_button(self, mode): '''Test that the Copy HidservAuth button is shown''' From c58fb4379589017d7d6b1a7f9c712832cba5386d Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sun, 30 Sep 2018 16:52:48 +1000 Subject: [PATCH 026/142] Ignore attribute error when optimistically trying to cancel compression (we may have no ZipWriter object yet) --- onionshare_gui/share_mode/threads.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/onionshare_gui/share_mode/threads.py b/onionshare_gui/share_mode/threads.py index d6022746..24e2c242 100644 --- a/onionshare_gui/share_mode/threads.py +++ b/onionshare_gui/share_mode/threads.py @@ -56,5 +56,8 @@ class CompressThread(QtCore.QThread): # Let the Web and ZipWriter objects know that we're canceling compression early self.mode.web.cancel_compression = True - if self.mode.web.zip_writer: + try: self.mode.web.zip_writer.cancel_compression = True + except AttributeError: + # we never made it as far as creating a ZipWriter object + pass From bdaf47834cdcb7953cdc0bee22134428a26d2769 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sun, 30 Sep 2018 17:16:37 +1000 Subject: [PATCH 027/142] Add a test for #790 --- ...onshare_790_cancel_on_second_share_test.py | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 tests_gui_tor/onionshare_790_cancel_on_second_share_test.py diff --git a/tests_gui_tor/onionshare_790_cancel_on_second_share_test.py b/tests_gui_tor/onionshare_790_cancel_on_second_share_test.py new file mode 100644 index 00000000..731de4fd --- /dev/null +++ b/tests_gui_tor/onionshare_790_cancel_on_second_share_test.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python3 +import os +import sys +import unittest +import pytest +import json + +from PyQt5 import QtWidgets + +from onionshare.common import Common +from onionshare.web import Web +from onionshare import onion, strings +from onionshare_gui import * + +from .commontests import CommonTests + +class OnionShareGuiTest(unittest.TestCase): + '''Test the OnionShare GUI''' + @classmethod + def setUpClass(cls): + '''Create the GUI''' + # Create our test file + testfile = open('/tmp/test.txt', 'w') + testfile.write('onionshare') + testfile.close() + common = Common() + common.define_css() + + # Start the Onion + strings.load_strings(common) + + testonion = onion.Onion(common) + global qtapp + qtapp = Application(common) + app = OnionShare(common, testonion, False, 0) + + web = Web(common, False, True) + + test_settings = { + "auth_password": "", + "auth_type": "no_auth", + "autoupdate_timestamp": "", + "close_after_first_download": True, + "connection_type": "bundled", + "control_port_address": "127.0.0.1", + "control_port_port": 9051, + "downloads_dir": "/tmp/OnionShare", + "hidservauth_string": "", + "no_bridges": True, + "private_key": "", + "public_mode": False, + "receive_allow_receiver_shutdown": True, + "save_private_key": False, + "shutdown_timeout": False, + "slug": "", + "socks_address": "127.0.0.1", + "socks_port": 9050, + "socket_file_path": "/var/run/tor/control", + "systray_notifications": True, + "tor_bridges_use_meek_lite_azure": False, + "tor_bridges_use_meek_lite_amazon": False, + "tor_bridges_use_custom_bridges": "", + "tor_bridges_use_obfs4": False, + "use_stealth": False, + "use_legacy_v2_onions": False, + "use_autoupdate": True, + "version": "1.3.1" + } + testsettings = '/tmp/testsettings.json' + open(testsettings, 'w').write(json.dumps(test_settings)) + + cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) + + @classmethod + def tearDownClass(cls): + '''Clean up after tests''' + os.remove('/tmp/test.txt') + + @pytest.mark.run(order=1) + def test_gui_loaded(self): + CommonTests.test_gui_loaded(self) + + @pytest.mark.run(order=2) + def test_windowTitle_seen(self): + CommonTests.test_windowTitle_seen(self) + + @pytest.mark.run(order=3) + def test_settings_button_is_visible(self): + CommonTests.test_settings_button_is_visible(self) + + @pytest.mark.run(order=4) + def test_server_status_bar_is_visible(self): + CommonTests.test_server_status_bar_is_visible(self) + + @pytest.mark.run(order=5) + def test_file_selection_widget_has_a_file(self): + CommonTests.test_file_selection_widget_has_a_file(self) + + @pytest.mark.run(order=6) + def test_info_widget_is_visible(self): + CommonTests.test_info_widget_is_visible(self, 'share') + + @pytest.mark.run(order=7) + def test_history_is_visible(self): + CommonTests.test_history_is_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_deleting_only_file_hides_delete_button(self): + CommonTests.test_deleting_only_file_hides_delete_button(self) + + @pytest.mark.run(order=9) + def test_add_a_file_and_delete_using_its_delete_widget(self): + CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) + + @pytest.mark.run(order=10) + def test_file_selection_widget_readd_files(self): + CommonTests.test_file_selection_widget_readd_files(self) + + @pytest.mark.run(order=11) + def test_server_working_on_start_button_pressed(self): + CommonTests.test_server_working_on_start_button_pressed(self, 'share') + + @pytest.mark.run(order=12) + def test_server_status_indicator_says_starting(self): + CommonTests.test_server_status_indicator_says_starting(self, 'share') + + @pytest.mark.run(order=13) + def test_add_delete_buttons_hidden(self): + CommonTests.test_add_delete_buttons_hidden(self) + + @pytest.mark.run(order=14) + def test_settings_button_is_hidden(self): + CommonTests.test_settings_button_is_hidden(self) + + @pytest.mark.run(order=15) + def test_a_server_is_started(self): + CommonTests.test_a_server_is_started(self, 'share') + + @pytest.mark.run(order=16) + def test_a_web_server_is_running(self): + CommonTests.test_a_web_server_is_running(self) + + @pytest.mark.run(order=17) + def test_have_a_slug(self): + CommonTests.test_have_a_slug(self, 'share', False) + + @pytest.mark.run(order=18) + def test_have_an_onion(self): + CommonTests.test_have_an_onion_service(self) + + @pytest.mark.run(order=19) + def test_url_description_shown(self): + CommonTests.test_url_description_shown(self, 'share') + + @pytest.mark.run(order=20) + def test_have_copy_url_button(self): + CommonTests.test_have_copy_url_button(self, 'share') + + @pytest.mark.run(order=21) + def test_server_status_indicator_says_started(self): + CommonTests.test_server_status_indicator_says_started(self, 'share') + + @pytest.mark.run(order=22) + def test_server_is_stopped(self): + CommonTests.test_server_is_stopped(self, 'share', True) + + @pytest.mark.run(order=23) + def test_web_service_is_stopped(self): + CommonTests.test_web_service_is_stopped(self) + + @pytest.mark.run(order=24) + def test_server_working_on_start_button_pressed_round2(self): + CommonTests.test_server_working_on_start_button_pressed(self, 'share') + + @pytest.mark.run(order=25) + def test_server_status_indicator_says_starting_round2(self): + CommonTests.test_server_status_indicator_says_starting(self, 'share') + + @pytest.mark.run(order=26) + def test_cancel_the_share(self): + CommonTests.test_cancel_the_share(self, 'share') + + @pytest.mark.run(order=27) + def test_server_is_stopped_round2(self): + CommonTests.test_server_is_stopped(self, 'share', False) + + @pytest.mark.run(order=28) + def test_web_service_is_stopped_round2(self): + CommonTests.test_web_service_is_stopped(self) + + @pytest.mark.run(order=29) + def test_add_button_visible(self): + CommonTests.test_add_button_visible(self) + + +if __name__ == "__main__": + unittest.main() From c6b8c0aa9510b3705c65e56003139c903a337b05 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sun, 30 Sep 2018 17:43:45 +1000 Subject: [PATCH 028/142] Replace deprecated assertEquals with assertEqual in tests --- tests_gui_local/commontests.py | 26 +++++++++++++------------- tests_gui_tor/commontests.py | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/commontests.py index de1ad9ab..e67a91f2 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/commontests.py @@ -69,9 +69,9 @@ class CommonTests(object): def test_server_status_indicator_says_starting(self, mode): '''Test that the Server Status indicator shows we are Starting''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) if mode == 'share': - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) def test_settings_button_is_hidden(self): '''Test that the settings button is hidden when the server starts''' @@ -123,9 +123,9 @@ class CommonTests(object): def test_server_status_indicator_says_started(self, mode): '''Test that the Server Status indicator shows we are started''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) if mode == 'share': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) def test_web_page(self, mode, string, public_mode): '''Test that the web page contains a string''' @@ -170,19 +170,19 @@ class CommonTests(object): def test_counter_incremented(self, mode, count): '''Test that the counter has incremented''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.uploads_completed, count) + self.assertEqual(self.gui.receive_mode.uploads_completed, count) if mode == 'share': - self.assertEquals(self.gui.share_mode.downloads_completed, count) + self.assertEqual(self.gui.share_mode.downloads_completed, count) def test_server_is_stopped(self, mode, stay_open): '''Test that the server stops when we click Stop''' if mode == 'receive': QtTest.QTest.mouseClick(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.receive_mode.server_status.status, 0) + self.assertEqual(self.gui.receive_mode.server_status.status, 0) if mode == 'share': if stay_open: QtTest.QTest.mouseClick(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.share_mode.server_status.status, 0) + self.assertEqual(self.gui.share_mode.server_status.status, 0) def test_web_service_is_stopped(self): '''Test that the web server also stopped''' @@ -195,12 +195,12 @@ class CommonTests(object): def test_server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) if mode == 'share': if stay_open: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) else: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically', True)) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically', True)) # Auto-stop timer tests def test_set_timeout(self, mode, timeout): @@ -260,7 +260,7 @@ class CommonTests(object): '''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.assertEquals(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) + self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) def test_file_selection_widget_readd_files(self): '''Re-add some files to the list so we can share''' @@ -299,7 +299,7 @@ class CommonTests(object): zip = zipfile.ZipFile('/tmp/download.zip') QtTest.QTest.qWait(2000) - self.assertEquals('onionshare', zip.read('test.txt').decode('utf-8')) + self.assertEqual('onionshare', zip.read('test.txt').decode('utf-8')) def test_add_button_visible(self): '''Test that the add button should be visible''' diff --git a/tests_gui_tor/commontests.py b/tests_gui_tor/commontests.py index a0d9bf5f..f58f0504 100644 --- a/tests_gui_tor/commontests.py +++ b/tests_gui_tor/commontests.py @@ -69,9 +69,9 @@ class CommonTests(object): def test_server_status_indicator_says_starting(self, mode): '''Test that the Server Status indicator shows we are Starting''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) if mode == 'share': - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) def test_settings_button_is_hidden(self): '''Test that the settings button is hidden when the server starts''' @@ -126,9 +126,9 @@ class CommonTests(object): def test_server_status_indicator_says_started(self, mode): '''Test that the Server Status indicator shows we are started''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) if mode == 'share': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) def test_web_page(self, mode, string, public_mode): '''Test that the web page contains a string''' @@ -176,19 +176,19 @@ class CommonTests(object): def test_counter_incremented(self, mode, count): '''Test that the counter has incremented''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.uploads_completed, count) + self.assertEqual(self.gui.receive_mode.uploads_completed, count) if mode == 'share': - self.assertEquals(self.gui.share_mode.downloads_completed, count) + self.assertEqual(self.gui.share_mode.downloads_completed, count) def test_server_is_stopped(self, mode, stay_open): '''Test that the server stops when we click Stop''' if mode == 'receive': QtTest.QTest.mouseClick(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.receive_mode.server_status.status, 0) + self.assertEqual(self.gui.receive_mode.server_status.status, 0) if mode == 'share': if stay_open: QtTest.QTest.mouseClick(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.share_mode.server_status.status, 0) + self.assertEqual(self.gui.share_mode.server_status.status, 0) def test_web_service_is_stopped(self): '''Test that the web server also stopped''' @@ -201,12 +201,12 @@ class CommonTests(object): def test_server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) if mode == 'share': if stay_open: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) else: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically', True)) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically', True)) def test_cancel_the_share(self, mode): '''Test that we can cancel this share before it's started up ''' @@ -286,7 +286,7 @@ class CommonTests(object): '''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.assertEquals(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) + self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) def test_file_selection_widget_readd_files(self): '''Re-add some files to the list so we can share''' @@ -328,7 +328,7 @@ class CommonTests(object): zip = zipfile.ZipFile('/tmp/download.zip') QtTest.QTest.qWait(4000) - self.assertEquals('onionshare', zip.read('test.txt').decode('utf-8')) + self.assertEqual('onionshare', zip.read('test.txt').decode('utf-8')) def test_add_button_visible(self): '''Test that the add button should be visible''' From da970a4c1b306eb4065964be2f9df1574acca4ac Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 10:57:13 -0700 Subject: [PATCH 029/142] Fix Tor tests so they pass, too --- tests_gui_local/__init__.py | 7 --- tests_gui_tor/commontests.py | 9 +++ .../onionshare_receive_mode_upload_test.py | 36 ++++++----- ...re_receive_mode_upload_test_public_mode.py | 46 +++++++------- ...onionshare_share_mode_cancel_share_test.py | 8 --- .../onionshare_share_mode_download_test.py | 16 ++--- ...re_share_mode_download_test_public_mode.py | 54 ++++++++++------- ...hare_share_mode_download_test_stay_open.py | 60 +++++++++++-------- .../onionshare_share_mode_persistent_test.py | 46 ++++++++------ .../onionshare_share_mode_stealth_test.py | 44 ++++++++------ ...e_share_mode_tor_connection_killed_test.py | 46 ++++++++------ tests_gui_tor/onionshare_timer_test.py | 28 +++++---- .../onionshare_tor_connection_killed_test.py | 46 ++++++++------ 13 files changed, 252 insertions(+), 194 deletions(-) diff --git a/tests_gui_local/__init__.py b/tests_gui_local/__init__.py index 76e5b1b9..bb2b2182 100644 --- a/tests_gui_local/__init__.py +++ b/tests_gui_local/__init__.py @@ -1,8 +1 @@ -from .onionshare_receive_mode_upload_test_public_mode import OnionShareGuiTest as ReceiveMoveUploadTestPublicMode -from .onionshare_receive_mode_upload_test import OnionShareGuiTest as ReceiveModeUploadTest -from .onionshare_share_mode_download_test_public_mode import OnionShareGuiTest as ShareModeDownloadTestPublicMode -from .onionshare_share_mode_download_test import OnionShareGuiTest as ShareModeDownloadTest -from .onionshare_share_mode_download_test_stay_open import OnionShareGuiTest as ShareModeDownloadTestStayOpen -from .onionshare_slug_persistent_test import OnionShareGuiTest as SlugPersistentTest -from .onionshare_timer_test import OnionShareGuiTest as TimerTest from .commontests import CommonTests diff --git a/tests_gui_tor/commontests.py b/tests_gui_tor/commontests.py index ea37279f..a1e420fd 100644 --- a/tests_gui_tor/commontests.py +++ b/tests_gui_tor/commontests.py @@ -10,6 +10,15 @@ from onionshare import strings from tests_gui_local import CommonTests as LocalCommonTests class CommonTests(LocalCommonTests): + def test_a_server_is_started(self, mode): + '''Test that the server has started (overriding from local tests to wait for longer)''' + QtTest.QTest.qWait(45000) + # Should now be in SERVER_STARTED state + if mode == 'receive': + self.assertEqual(self.gui.receive_mode.server_status.status, 2) + if mode == 'share': + self.assertEqual(self.gui.share_mode.server_status.status, 2) + def test_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') diff --git a/tests_gui_tor/onionshare_receive_mode_upload_test.py b/tests_gui_tor/onionshare_receive_mode_upload_test.py index 5be400e2..7c340037 100644 --- a/tests_gui_tor/onionshare_receive_mode_upload_test.py +++ b/tests_gui_tor/onionshare_receive_mode_upload_test.py @@ -94,15 +94,19 @@ class OnionShareGuiTest(unittest.TestCase): def test_server_status_bar_is_visible(self): CommonTests.test_server_status_bar_is_visible(self) - @pytest.mark.run(order=5) - def test_info_widget_is_not_visible(self): - CommonTests.test_info_widget_is_not_visible(self, 'receive') - @pytest.mark.run(order=6) def test_click_mode(self): CommonTests.test_click_mode(self, 'receive') + @pytest.mark.run(order=6) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'receive') + @pytest.mark.run(order=7) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'receive') + + @pytest.mark.run(order=8) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'receive') @@ -134,51 +138,51 @@ class OnionShareGuiTest(unittest.TestCase): def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) - @pytest.mark.run(order=16) + @pytest.mark.run(order=20) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'receive') - @pytest.mark.run(order=17) + @pytest.mark.run(order=21) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'receive') - @pytest.mark.run(order=18) + @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'receive') - @pytest.mark.run(order=19) + @pytest.mark.run(order=23) def test_web_page(self): CommonTests.test_web_page(self, 'receive', 'Select the files you want to send, then click', False) - @pytest.mark.run(order=20) + @pytest.mark.run(order=24) def test_upload_file(self): CommonTests.test_upload_file(self, False, '/tmp/OnionShare/test.txt') - @pytest.mark.run(order=21) + @pytest.mark.run(order=25) def test_history_widgets_present(self): CommonTests.test_history_widgets_present(self, 'receive') - @pytest.mark.run(order=22) + @pytest.mark.run(order=26) def test_counter_incremented(self): CommonTests.test_counter_incremented(self, 'receive', 1) - @pytest.mark.run(order=23) + @pytest.mark.run(order=27) def test_upload_same_file_is_renamed(self): CommonTests.test_upload_file(self, False, '/tmp/OnionShare/test-2.txt') - @pytest.mark.run(order=24) + @pytest.mark.run(order=28) def test_upload_count_incremented_again(self): CommonTests.test_counter_incremented(self, 'receive', 2) - @pytest.mark.run(order=25) + @pytest.mark.run(order=29) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'receive', False) - @pytest.mark.run(order=26) + @pytest.mark.run(order=30) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=27) + @pytest.mark.run(order=31) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) diff --git a/tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py index 9c9553a4..65bf5c89 100644 --- a/tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py @@ -95,34 +95,38 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_server_status_bar_is_visible(self) @pytest.mark.run(order=5) - def test_info_widget_is_not_visible(self): - CommonTests.test_info_widget_is_not_visible(self, 'receive') - - @pytest.mark.run(order=6) def test_click_mode(self): CommonTests.test_click_mode(self, 'receive') + @pytest.mark.run(order=6) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'receive') + @pytest.mark.run(order=7) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'receive') + + @pytest.mark.run(order=8) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'receive') - @pytest.mark.run(order=8) + @pytest.mark.run(order=9) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'receive') - @pytest.mark.run(order=9) + @pytest.mark.run(order=10) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'receive') - @pytest.mark.run(order=10) + @pytest.mark.run(order=11) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=12) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'receive') - @pytest.mark.run(order=12) + @pytest.mark.run(order=13) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) @@ -134,51 +138,51 @@ class OnionShareGuiTest(unittest.TestCase): def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) - @pytest.mark.run(order=16) + @pytest.mark.run(order=20) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'receive') - @pytest.mark.run(order=17) + @pytest.mark.run(order=21) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'receive') - @pytest.mark.run(order=18) + @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'receive') - @pytest.mark.run(order=19) + @pytest.mark.run(order=23) def test_web_page(self): CommonTests.test_web_page(self, 'receive', 'Select the files you want to send, then click', True) - @pytest.mark.run(order=20) + @pytest.mark.run(order=24) def test_upload_file(self): CommonTests.test_upload_file(self, True, '/tmp/OnionShare/test.txt') - @pytest.mark.run(order=21) + @pytest.mark.run(order=25) def test_history_widgets_present(self): CommonTests.test_history_widgets_present(self, 'receive') - @pytest.mark.run(order=22) + @pytest.mark.run(order=26) def test_counter_incremented(self): CommonTests.test_counter_incremented(self, 'receive', 1) - @pytest.mark.run(order=23) + @pytest.mark.run(order=27) def test_upload_same_file_is_renamed(self): CommonTests.test_upload_file(self, True, '/tmp/OnionShare/test-2.txt') - @pytest.mark.run(order=24) + @pytest.mark.run(order=28) def test_upload_count_incremented_again(self): CommonTests.test_counter_incremented(self, 'receive', 2) - @pytest.mark.run(order=25) + @pytest.mark.run(order=29) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'receive', False) - @pytest.mark.run(order=26) + @pytest.mark.run(order=30) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=27) + @pytest.mark.run(order=31) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) diff --git a/tests_gui_tor/onionshare_share_mode_cancel_share_test.py b/tests_gui_tor/onionshare_share_mode_cancel_share_test.py index 466109d7..cdab8f85 100644 --- a/tests_gui_tor/onionshare_share_mode_cancel_share_test.py +++ b/tests_gui_tor/onionshare_share_mode_cancel_share_test.py @@ -96,14 +96,6 @@ class OnionShareGuiTest(unittest.TestCase): def test_file_selection_widget_has_a_file(self): CommonTests.test_file_selection_widget_has_a_file(self) - @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) diff --git a/tests_gui_tor/onionshare_share_mode_download_test.py b/tests_gui_tor/onionshare_share_mode_download_test.py index 1c8e1b6c..2bf26690 100644 --- a/tests_gui_tor/onionshare_share_mode_download_test.py +++ b/tests_gui_tor/onionshare_share_mode_download_test.py @@ -97,20 +97,20 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') @pytest.mark.run(order=8) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') @pytest.mark.run(order=9) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) + def test_history_is_visible(self): + CommonTests.test_history_is_visible(self, 'share') @pytest.mark.run(order=10) def test_file_selection_widget_readd_files(self): diff --git a/tests_gui_tor/onionshare_share_mode_download_test_public_mode.py b/tests_gui_tor/onionshare_share_mode_download_test_public_mode.py index c292e729..4792994d 100644 --- a/tests_gui_tor/onionshare_share_mode_download_test_public_mode.py +++ b/tests_gui_tor/onionshare_share_mode_download_test_public_mode.py @@ -97,94 +97,102 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', True) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_web_page(self): CommonTests.test_web_page(self, 'share', 'Total size', True) - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_download_share(self): CommonTests.test_download_share(self, True) - @pytest.mark.run(order=24) + @pytest.mark.run(order=26) def test_history_widgets_present(self): CommonTests.test_history_widgets_present(self, 'share') - @pytest.mark.run(order=25) + @pytest.mark.run(order=27) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', False) - @pytest.mark.run(order=26) + @pytest.mark.run(order=28) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=27) + @pytest.mark.run(order=29) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'share', False) - @pytest.mark.run(order=28) + @pytest.mark.run(order=30) def test_add_button_visible(self): CommonTests.test_add_button_visible(self) diff --git a/tests_gui_tor/onionshare_share_mode_download_test_stay_open.py b/tests_gui_tor/onionshare_share_mode_download_test_stay_open.py index 7838316f..92d52169 100644 --- a/tests_gui_tor/onionshare_share_mode_download_test_stay_open.py +++ b/tests_gui_tor/onionshare_share_mode_download_test_stay_open.py @@ -97,106 +97,114 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', True) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_web_page(self): CommonTests.test_web_page(self, 'share', 'Total size', True) - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_download_share(self): CommonTests.test_download_share(self, True) - @pytest.mark.run(order=24) + @pytest.mark.run(order=26) def test_history_widgets_present(self): CommonTests.test_history_widgets_present(self, 'share') - @pytest.mark.run(order=25) + @pytest.mark.run(order=27) def test_counter_incremented(self): CommonTests.test_counter_incremented(self, 'share', 1) - @pytest.mark.run(order=26) + @pytest.mark.run(order=28) def test_download_share_again(self): CommonTests.test_download_share(self, True) - @pytest.mark.run(order=27) + @pytest.mark.run(order=29) def test_counter_incremented_again(self): CommonTests.test_counter_incremented(self, 'share', 2) - @pytest.mark.run(order=28) + @pytest.mark.run(order=30) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', True) - @pytest.mark.run(order=29) + @pytest.mark.run(order=31) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=30) + @pytest.mark.run(order=32) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'share', True) - @pytest.mark.run(order=31) + @pytest.mark.run(order=33) def test_add_button_visible(self): CommonTests.test_add_button_visible(self) diff --git a/tests_gui_tor/onionshare_share_mode_persistent_test.py b/tests_gui_tor/onionshare_share_mode_persistent_test.py index 3cffaab6..6b9fbe16 100644 --- a/tests_gui_tor/onionshare_share_mode_persistent_test.py +++ b/tests_gui_tor/onionshare_share_mode_persistent_test.py @@ -95,79 +95,87 @@ class OnionShareGuiTest(unittest.TestCase): def test_server_status_bar_is_visible(self): CommonTests.test_server_status_bar_is_visible(self) - @pytest.mark.run(order=5) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') - @pytest.mark.run(order=6) + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') + + @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=7) + @pytest.mark.run(order=10) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=11) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=9) + @pytest.mark.run(order=12) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=13) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=11) + @pytest.mark.run(order=14) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=12) + @pytest.mark.run(order=15) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', False) global slug slug = self.gui.share_mode.server_status.web.slug - @pytest.mark.run(order=13) + @pytest.mark.run(order=16) def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) global onion_host onion_host = self.gui.app.onion_host - @pytest.mark.run(order=14) + @pytest.mark.run(order=17) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=15) + @pytest.mark.run(order=18) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', True) - @pytest.mark.run(order=16) + @pytest.mark.run(order=19) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=20) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'share', True) - @pytest.mark.run(order=18) + @pytest.mark.run(order=21) def test_server_started_again(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') CommonTests.test_server_status_indicator_says_starting(self, 'share') CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=19) + @pytest.mark.run(order=22) def test_have_same_slug(self): '''Test that we have the same slug''' self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) - @pytest.mark.run(order=20) + @pytest.mark.run(order=23) def test_have_same_onion(self): '''Test that we have the same onion''' self.assertEqual(self.gui.app.onion_host, onion_host) - @pytest.mark.run(order=21) + @pytest.mark.run(order=24) def test_server_is_stopped_again(self): CommonTests.test_server_is_stopped(self, 'share', True) CommonTests.test_web_service_is_stopped(self) diff --git a/tests_gui_tor/onionshare_share_mode_stealth_test.py b/tests_gui_tor/onionshare_share_mode_stealth_test.py index aaf6fbc6..876efde2 100644 --- a/tests_gui_tor/onionshare_share_mode_stealth_test.py +++ b/tests_gui_tor/onionshare_share_mode_stealth_test.py @@ -97,74 +97,82 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', False) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_copy_have_hidserv_auth_button(self): CommonTests.test_copy_have_hidserv_auth_button(self, 'share') - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_hidserv_auth_string(self): CommonTests.test_hidserv_auth_string(self) diff --git a/tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py b/tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py index 861b7ccc..37abc825 100644 --- a/tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py +++ b/tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py @@ -97,78 +97,86 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', False) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_tor_killed_statusbar_message_shown(self): CommonTests.test_tor_killed_statusbar_message_shown(self, 'share') - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', False) - @pytest.mark.run(order=24) + @pytest.mark.run(order=26) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) diff --git a/tests_gui_tor/onionshare_timer_test.py b/tests_gui_tor/onionshare_timer_test.py index b76106d9..2b64b998 100644 --- a/tests_gui_tor/onionshare_timer_test.py +++ b/tests_gui_tor/onionshare_timer_test.py @@ -97,42 +97,50 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_set_timeout(self): CommonTests.test_set_timeout(self, 'share', 120) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_timeout_widget_hidden(self): CommonTests.test_timeout_widget_hidden(self, 'share') - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_timeout(self): CommonTests.test_server_timed_out(self, 'share', 125000) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) diff --git a/tests_gui_tor/onionshare_tor_connection_killed_test.py b/tests_gui_tor/onionshare_tor_connection_killed_test.py index 861b7ccc..37abc825 100644 --- a/tests_gui_tor/onionshare_tor_connection_killed_test.py +++ b/tests_gui_tor/onionshare_tor_connection_killed_test.py @@ -97,78 +97,86 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_file_selection_widget_has_a_file(self) @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') + def test_info_widget_shows_less(self): + CommonTests.test_info_widget_shows_less(self, 'share') @pytest.mark.run(order=7) + def test_history_is_not_visible(self): + CommonTests.test_history_is_not_visible(self, 'share') + + @pytest.mark.run(order=8) + def test_click_toggle_history(self): + CommonTests.test_click_toggle_history(self, 'share') + + @pytest.mark.run(order=9) def test_history_is_visible(self): CommonTests.test_history_is_visible(self, 'share') - @pytest.mark.run(order=8) + @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): CommonTests.test_deleting_only_file_hides_delete_button(self) - @pytest.mark.run(order=9) + @pytest.mark.run(order=11) def test_add_a_file_and_delete_using_its_delete_widget(self): CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - @pytest.mark.run(order=10) + @pytest.mark.run(order=12) def test_file_selection_widget_readd_files(self): CommonTests.test_file_selection_widget_readd_files(self) - @pytest.mark.run(order=11) + @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): CommonTests.test_server_working_on_start_button_pressed(self, 'share') - @pytest.mark.run(order=12) + @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): CommonTests.test_server_status_indicator_says_starting(self, 'share') - @pytest.mark.run(order=13) + @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): CommonTests.test_add_delete_buttons_hidden(self) - @pytest.mark.run(order=14) + @pytest.mark.run(order=16) def test_settings_button_is_hidden(self): CommonTests.test_settings_button_is_hidden(self) - @pytest.mark.run(order=15) + @pytest.mark.run(order=17) def test_a_server_is_started(self): CommonTests.test_a_server_is_started(self, 'share') - @pytest.mark.run(order=16) + @pytest.mark.run(order=18) def test_a_web_server_is_running(self): CommonTests.test_a_web_server_is_running(self) - @pytest.mark.run(order=17) + @pytest.mark.run(order=19) def test_have_a_slug(self): CommonTests.test_have_a_slug(self, 'share', False) - @pytest.mark.run(order=18) + @pytest.mark.run(order=20) def test_have_an_onion(self): CommonTests.test_have_an_onion_service(self) - @pytest.mark.run(order=19) + @pytest.mark.run(order=21) def test_url_description_shown(self): CommonTests.test_url_description_shown(self, 'share') - @pytest.mark.run(order=20) + @pytest.mark.run(order=22) def test_have_copy_url_button(self): CommonTests.test_have_copy_url_button(self, 'share') - @pytest.mark.run(order=21) + @pytest.mark.run(order=23) def test_server_status_indicator_says_started(self): CommonTests.test_server_status_indicator_says_started(self, 'share') - @pytest.mark.run(order=22) + @pytest.mark.run(order=24) def test_tor_killed_statusbar_message_shown(self): CommonTests.test_tor_killed_statusbar_message_shown(self, 'share') - @pytest.mark.run(order=23) + @pytest.mark.run(order=25) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'share', False) - @pytest.mark.run(order=24) + @pytest.mark.run(order=26) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) From 7afee90cd25766d05c694817d2e5e6ead628d4ab Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 11:41:07 -0700 Subject: [PATCH 030/142] Test the history indicator widget, in local GUI tests --- tests_gui_local/commontests.py | 53 +++++++++++++++++++ .../onionshare_receive_mode_upload_test.py | 8 ++- ...re_receive_mode_upload_test_public_mode.py | 8 ++- .../onionshare_share_mode_download_test.py | 6 +++ ...re_share_mode_download_test_public_mode.py | 6 +++ ...hare_share_mode_download_test_stay_open.py | 6 +++ .../onionshare_slug_persistent_test.py | 6 +++ 7 files changed, 89 insertions(+), 4 deletions(-) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/commontests.py index 870c2dbe..21e8cfad 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/commontests.py @@ -52,6 +52,59 @@ class CommonTests(object): QtTest.QTest.mouseClick(self.gui.share_mode.info.toggle_button, QtCore.Qt.LeftButton) self.assertEqual(self.gui.share_mode.downloads.isVisible(), not currently_visible) + def test_history_indicator(self, mode, public_mode): + '''Test that we can make sure the history is toggled off, do an action, and the indiciator works''' + if mode == 'receive': + # Make sure history is toggled off + if self.gui.receive_mode.uploads.isVisible(): + QtTest.QTest.mouseClick(self.gui.receive_mode.info.toggle_button, QtCore.Qt.LeftButton) + self.assertFalse(self.gui.receive_mode.uploads.isVisible()) + + # Indicator should not be visible yet + self.assertFalse(self.gui.receive_mode.info.indicator_label.isVisible()) + + # Upload a file + files = {'file[]': open('/tmp/test.txt', 'rb')} + if not public_mode: + path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, self.gui.receive_mode.web.slug) + else: + path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) + response = requests.post(path, files=files) + QtTest.QTest.qWait(2000) + + # Indicator should be visible, have a value of "1" + self.assertTrue(self.gui.receive_mode.info.indicator_label.isVisible()) + self.assertEqual(self.gui.receive_mode.info.indicator_label.text(), "1") + + # Toggle history back on, indicator should be hidden again + QtTest.QTest.mouseClick(self.gui.receive_mode.info.toggle_button, QtCore.Qt.LeftButton) + self.assertFalse(self.gui.receive_mode.info.indicator_label.isVisible()) + + if mode == 'share': + # Make sure history is toggled off + if self.gui.share_mode.downloads.isVisible(): + QtTest.QTest.mouseClick(self.gui.share_mode.info.toggle_button, QtCore.Qt.LeftButton) + self.assertFalse(self.gui.share_mode.downloads.isVisible()) + + # Indicator should not be visible yet + self.assertFalse(self.gui.share_mode.info.indicator_label.isVisible()) + + # Download files + if public_mode: + url = "http://127.0.0.1:{}/download".format(self.gui.app.port) + else: + url = "http://127.0.0.1:{}/{}/download".format(self.gui.app.port, self.gui.share_mode.web.slug) + r = requests.get(url) + QtTest.QTest.qWait(2000) + + # Indicator should be visible, have a value of "1" + self.assertTrue(self.gui.share_mode.info.indicator_label.isVisible()) + self.assertEqual(self.gui.share_mode.info.indicator_label.text(), "1") + + # Toggle history back on, indicator should be hidden again + QtTest.QTest.mouseClick(self.gui.share_mode.info.toggle_button, QtCore.Qt.LeftButton) + self.assertFalse(self.gui.share_mode.info.indicator_label.isVisible()) + def test_history_is_not_visible(self, mode): '''Test that the History section is not visible''' if mode == 'receive': diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index b53d5c06..19674aa3 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -171,14 +171,18 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_counter_incremented(self, 'receive', 2) @pytest.mark.run(order=24) + def test_history_indicator(self): + CommonTests.test_history_indicator(self, 'receive', False) + + @pytest.mark.run(order=25) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'receive', False) - @pytest.mark.run(order=25) + @pytest.mark.run(order=26) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=26) + @pytest.mark.run(order=27) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py index 5e5a6b77..e3f85731 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py @@ -171,14 +171,18 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_counter_incremented(self, 'receive', 2) @pytest.mark.run(order=24) + def test_history_indicator(self): + CommonTests.test_history_indicator(self, 'receive', True) + + @pytest.mark.run(order=25) def test_server_is_stopped(self): CommonTests.test_server_is_stopped(self, 'receive', False) - @pytest.mark.run(order=25) + @pytest.mark.run(order=26) def test_web_service_is_stopped(self): CommonTests.test_web_service_is_stopped(self) - @pytest.mark.run(order=26) + @pytest.mark.run(order=27) def test_server_status_indicator_says_closed(self): CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index 40df6d98..c4a60101 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -192,6 +192,12 @@ class OnionShareGuiTest(unittest.TestCase): def test_add_button_visible(self): CommonTests.test_add_button_visible(self) + @pytest.mark.run(order=30) + def test_history_indicator(self): + CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_history_indicator(self, 'share', False) + if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py index 73d4c999..a10ee4c2 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py +++ b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py @@ -192,6 +192,12 @@ class OnionShareGuiTest(unittest.TestCase): def test_add_button_visible(self): CommonTests.test_add_button_visible(self) + @pytest.mark.run(order=30) + def test_history_indicator(self): + CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_history_indicator(self, 'share', True) + if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py index e849d224..8426c264 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py +++ b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py @@ -204,6 +204,12 @@ class OnionShareGuiTest(unittest.TestCase): def test_add_button_visible(self): CommonTests.test_add_button_visible(self) + @pytest.mark.run(order=33) + def test_history_indicator(self): + CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_history_indicator(self, 'share', True) + if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_slug_persistent_test.py b/tests_gui_local/onionshare_slug_persistent_test.py index 5b53f7e0..9fb623dd 100644 --- a/tests_gui_local/onionshare_slug_persistent_test.py +++ b/tests_gui_local/onionshare_slug_persistent_test.py @@ -168,6 +168,12 @@ class OnionShareGuiTest(unittest.TestCase): CommonTests.test_server_is_stopped(self, 'share', True) CommonTests.test_web_service_is_stopped(self) + @pytest.mark.run(order=23) + def test_history_indicator(self): + CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_history_indicator(self, 'share', False) + if __name__ == "__main__": unittest.main() From dc464aae23103a33ca7fa95a3a5f7eeba598aa3e Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 14:45:21 -0700 Subject: [PATCH 031/142] Add locale to Settings, and make it default to the system locale, or English --- onionshare/settings.py | 17 ++++++++++++++++- tests/test_onionshare_settings.py | 7 ++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/onionshare/settings.py b/onionshare/settings.py index adcfc7a3..d231a976 100644 --- a/onionshare/settings.py +++ b/onionshare/settings.py @@ -21,6 +21,7 @@ along with this program. If not, see . import json import os import platform +import locale from . import strings @@ -47,6 +48,12 @@ class Settings(object): else: self.common.log('Settings', '__init__', 'Supplied config does not exist or is unreadable. Falling back to default location') + # Available languages in this version of OnionShare + self.available_locales = [ + 'cs', 'da', 'de', 'en', 'eo', 'es', 'fi', + 'fr', 'it', 'nl', 'no', 'pt', 'ru', 'tr' + ] + # These are the default settings. They will get overwritten when loading from disk self.default_settings = { 'version': self.common.version, @@ -74,7 +81,8 @@ class Settings(object): 'slug': '', 'hidservauth_string': '', 'downloads_dir': self.build_default_downloads_dir(), - 'receive_allow_receiver_shutdown': True + 'receive_allow_receiver_shutdown': True, + 'locale': None # this gets defined in fill_in_defaults() } self._settings = {} self.fill_in_defaults() @@ -88,6 +96,13 @@ class Settings(object): if key not in self._settings: self._settings[key] = self.default_settings[key] + # Choose the default locale based on the OS preference, and fall-back to English + if self._settings['locale'] is None: + default_locale = locale.getdefaultlocale()[0][:2] + if default_locale not in self.available_locales: + default_locale = 'en' + self._settings['locale'] = default_locale + def build_filename(self): """ Returns the path of the settings file. diff --git a/tests/test_onionshare_settings.py b/tests/test_onionshare_settings.py index 1f1ef528..371b2d27 100644 --- a/tests/test_onionshare_settings.py +++ b/tests/test_onionshare_settings.py @@ -40,7 +40,7 @@ def settings_obj(sys_onionshare_dev_mode, platform_linux): class TestSettings: def test_init(self, settings_obj): - assert settings_obj._settings == settings_obj.default_settings == { + expected_settings = { 'version': 'DUMMY_VERSION_1.2.3', 'connection_type': 'bundled', 'control_port_address': '127.0.0.1', @@ -68,6 +68,11 @@ class TestSettings: 'receive_allow_receiver_shutdown': True, 'public_mode': False } + 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'] From e61c43fde1afc0b9e91a7dcd43e2033a4f86e1e7 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 15:01:02 -0700 Subject: [PATCH 032/142] Make Settings.available_locales be a dictionary mapping locale codes to language names in that language --- onionshare/settings.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/onionshare/settings.py b/onionshare/settings.py index d231a976..d3788739 100644 --- a/onionshare/settings.py +++ b/onionshare/settings.py @@ -48,11 +48,25 @@ class Settings(object): else: self.common.log('Settings', '__init__', 'Supplied config does not exist or is unreadable. Falling back to default location') - # Available languages in this version of OnionShare - self.available_locales = [ - 'cs', 'da', 'de', 'en', 'eo', 'es', 'fi', - 'fr', 'it', 'nl', 'no', 'pt', 'ru', 'tr' - ] + # Dictionary of available languages in this version of OnionShare, + # mapped to the language name, in that language. + # TODO: Update language names to not be in English + self.available_locales = { + 'cs': 'Croatian', + 'da': 'Danish', + 'de': 'German', + 'en': 'English', + 'eo': 'Esperanto', + 'es': 'Spanish', + 'fi': 'Finnish', + 'fr': 'French', + 'it': 'Italian', + 'nl': 'Dutch', + 'no': 'Norweigan', + 'pt': 'Portuguese', + 'ru': 'Russian', + 'tr': 'Turkish' + } # These are the default settings. They will get overwritten when loading from disk self.default_settings = { From 17df699aad378934ce7b897caf80528b0e3076a9 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 16:14:14 -0700 Subject: [PATCH 033/142] Allow switching locales from the settings dialog --- onionshare_gui/settings_dialog.py | 27 +++++++++++++++++++++++++++ share/locale/en.json | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 3cd25d31..5966b954 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -227,6 +227,22 @@ class SettingsDialog(QtWidgets.QDialog): if self.system != 'Windows' and self.system != 'Darwin': autoupdate_group.hide() + # Language settings + + # Populate the dropdown with all of OnionShare's available languages + self.language_combobox = QtWidgets.QComboBox() + language_names_to_locales = {v: k for k, v in self.common.settings.available_locales.items()} + language_names = list(language_names_to_locales) + language_names.sort() + for language_name in language_names: + locale = language_names_to_locales[language_name] + self.language_combobox.addItem(language_name, QtCore.QVariant(locale)) + + language_layout = QtWidgets.QVBoxLayout() + language_layout.addWidget(self.language_combobox) + language_group = QtWidgets.QGroupBox(strings._("gui_settings_language_label", True)) + language_group.setLayout(language_layout) + # Connection type: either automatic, control port, or socket file # Bundled Tor @@ -431,6 +447,7 @@ class SettingsDialog(QtWidgets.QDialog): left_col_layout.addWidget(sharing_group) left_col_layout.addWidget(receiving_group) left_col_layout.addWidget(autoupdate_group) + left_col_layout.addWidget(language_group) left_col_layout.addStretch() right_col_layout = QtWidgets.QVBoxLayout() @@ -524,6 +541,10 @@ class SettingsDialog(QtWidgets.QDialog): autoupdate_timestamp = self.old_settings.get('autoupdate_timestamp') self._update_autoupdate_timestamp(autoupdate_timestamp) + locale = self.old_settings.get('locale') + locale_index = self.language_combobox.findData(QtCore.QVariant(locale)) + self.language_combobox.setCurrentIndex(locale_index) + connection_type = self.old_settings.get('connection_type') if connection_type == 'bundled': if self.connection_type_bundled_radio.isEnabled(): @@ -936,6 +957,12 @@ class SettingsDialog(QtWidgets.QDialog): if not self.stealth_checkbox.isChecked(): settings.set('hidservauth_string', '') + # Language + locale_index = self.language_combobox.currentIndex() + locale = self.language_combobox.itemData(locale_index) + settings.set('locale', locale) + + # Tor connection if self.connection_type_bundled_radio.isChecked(): settings.set('connection_type', 'bundled') if self.connection_type_automatic_radio.isChecked(): diff --git a/share/locale/en.json b/share/locale/en.json index 0f0f0cf4..903f8945 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -180,5 +180,6 @@ "gui_upload_in_progress": "Upload Started {}", "gui_upload_finished_range": "Uploaded {} to {}", "gui_upload_finished": "Uploaded {}", - "gui_open_folder_error_nautilus": "Cannot open folder because nautilus is not available. The file is here: {}" + "gui_open_folder_error_nautilus": "Cannot open folder because nautilus is not available. The file is here: {}", + "gui_settings_language_label": "Select language" } From 786a8146d481349a14f7bd16cbb70cf711d14c74 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 16:18:40 -0700 Subject: [PATCH 034/142] Translate language names to their own language --- onionshare/settings.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/onionshare/settings.py b/onionshare/settings.py index d3788739..1fbda807 100644 --- a/onionshare/settings.py +++ b/onionshare/settings.py @@ -49,23 +49,22 @@ class Settings(object): self.common.log('Settings', '__init__', 'Supplied config does not exist or is unreadable. Falling back to default location') # Dictionary of available languages in this version of OnionShare, - # mapped to the language name, in that language. - # TODO: Update language names to not be in English + # mapped to the language name, in that language self.available_locales = { - 'cs': 'Croatian', - 'da': 'Danish', - 'de': 'German', - 'en': 'English', - 'eo': 'Esperanto', - 'es': 'Spanish', - 'fi': 'Finnish', - 'fr': 'French', - 'it': 'Italian', - 'nl': 'Dutch', - 'no': 'Norweigan', - 'pt': 'Portuguese', - 'ru': 'Russian', - 'tr': 'Turkish' + 'cs': 'Hrvatski', # Croatian + 'da': 'Dansk', # Danish + 'de': 'Deutsch', # German + 'en': 'English', # English + 'eo': 'Esperanto', # Esperanto + 'es': 'Español', # Spanish + 'fi': 'Suomi', # Finnish + 'fr': 'Français', # French + 'it': 'Italiano', # Italian + 'nl': 'Nederlands', # Dutch + 'no': 'Norsk', # Norweigan + 'pt': 'Português', # Portuguese + 'ru': 'Русский', # Russian + 'tr': 'Türkçe' # Turkish } # These are the default settings. They will get overwritten when loading from disk From 08c01db69d9e7433f230ecbfe15f498a80954d70 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 16:23:46 -0700 Subject: [PATCH 035/142] Change how language selection setting looks --- onionshare_gui/settings_dialog.py | 13 ++++++------- share/locale/en.json | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 5966b954..709ab059 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -228,20 +228,19 @@ class SettingsDialog(QtWidgets.QDialog): autoupdate_group.hide() # Language settings - - # Populate the dropdown with all of OnionShare's available languages + language_label = QtWidgets.QLabel(strings._("gui_settings_language_label", True)) self.language_combobox = QtWidgets.QComboBox() + # Populate the dropdown with all of OnionShare's available languages language_names_to_locales = {v: k for k, v in self.common.settings.available_locales.items()} language_names = list(language_names_to_locales) language_names.sort() for language_name in language_names: locale = language_names_to_locales[language_name] self.language_combobox.addItem(language_name, QtCore.QVariant(locale)) - - language_layout = QtWidgets.QVBoxLayout() + language_layout = QtWidgets.QHBoxLayout() + language_layout.addWidget(language_label) language_layout.addWidget(self.language_combobox) - language_group = QtWidgets.QGroupBox(strings._("gui_settings_language_label", True)) - language_group.setLayout(language_layout) + language_layout.addStretch() # Connection type: either automatic, control port, or socket file @@ -447,7 +446,7 @@ class SettingsDialog(QtWidgets.QDialog): left_col_layout.addWidget(sharing_group) left_col_layout.addWidget(receiving_group) left_col_layout.addWidget(autoupdate_group) - left_col_layout.addWidget(language_group) + left_col_layout.addLayout(language_layout) left_col_layout.addStretch() right_col_layout = QtWidgets.QVBoxLayout() diff --git a/share/locale/en.json b/share/locale/en.json index 903f8945..05830e62 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -181,5 +181,5 @@ "gui_upload_finished_range": "Uploaded {} to {}", "gui_upload_finished": "Uploaded {}", "gui_open_folder_error_nautilus": "Cannot open folder because nautilus is not available. The file is here: {}", - "gui_settings_language_label": "Select language" + "gui_settings_language_label": "Preferred language" } From 8d44c0f729310b53819d103d1140094442e3ad1d Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 17:06:29 -0700 Subject: [PATCH 036/142] Set OnionShare language based on the locale stored in settings, and prompt user to restart OnionShare after changing their language --- onionshare/__init__.py | 9 +++++-- onionshare/strings.py | 39 ++++++++++++++----------------- onionshare_gui/__init__.py | 4 ++++ onionshare_gui/onionshare_gui.py | 5 ++-- onionshare_gui/settings_dialog.py | 30 +++++++++++++++++------- share/locale/en.json | 3 ++- 6 files changed, 55 insertions(+), 35 deletions(-) diff --git a/onionshare/__init__.py b/onionshare/__init__.py index 715c5571..2f0ef14c 100644 --- a/onionshare/__init__.py +++ b/onionshare/__init__.py @@ -33,7 +33,11 @@ def main(cwd=None): """ common = Common() + # Load settings right away, in order to get locale setting for strings + common.load_settings(config) strings.load_strings(common) + + # Display OnionShare banner print(strings._('version_string').format(common.version)) # OnionShare CLI in OSX needs to change current working directory (#132) @@ -88,8 +92,9 @@ def main(cwd=None): if not valid: sys.exit() - # Load settings - common.load_settings(config) + # Re-load settings, if a custom config was passed in + if config: + common.load_settings(config) # Debug mode? common.debug = debug diff --git a/onionshare/strings.py b/onionshare/strings.py index 3e9df56d..edae7849 100644 --- a/onionshare/strings.py +++ b/onionshare/strings.py @@ -22,36 +22,33 @@ import locale import os strings = {} +translations = {} -def load_strings(common, default="en"): +def load_strings(common): """ Loads translated strings and fallback to English if the translation does not exist. """ - global strings + global strings, translations - # find locale dir - locale_dir = common.get_resource_path('locale') - - # load all translations + # Load all translations translations = {} - for filename in os.listdir(locale_dir): - abs_filename = os.path.join(locale_dir, filename) - lang, ext = os.path.splitext(filename) - if ext == '.json': - with open(abs_filename, encoding='utf-8') as f: - translations[lang] = json.load(f) + for locale in common.settings.available_locales: + locale_dir = common.get_resource_path('locale') + filename = os.path.join(locale_dir, "{}.json".format(locale)) + with open(filename, encoding='utf-8') as f: + translations[locale] = json.load(f) - strings = translations[default] - lc, enc = locale.getdefaultlocale() - if lc: - lang = lc[:2] - if lang in translations: - # if a string doesn't exist, fallback to English - for key in translations[default]: - if key in translations[lang]: - strings[key] = translations[lang][key] + # Build strings + default_locale = 'en' + current_locale = common.settings.get('locale') + strings = {} + for s in translations[default_locale]: + if s in translations[current_locale]: + strings[s] = translations[current_locale][s] + else: + strings[s] = translations[default_locale][s] def translated(k, gui=False): diff --git a/onionshare_gui/__init__.py b/onionshare_gui/__init__.py index 99db635a..51565cb6 100644 --- a/onionshare_gui/__init__.py +++ b/onionshare_gui/__init__.py @@ -59,7 +59,11 @@ def main(): common = Common() common.define_css() + # Load settings right away, in order to get locale setting for strings + common.load_settings() strings.load_strings(common) + + # Display OnionShare banner print(strings._('version_string').format(common.version)) # Allow Ctrl-C to smoothly quit the program instead of throwing an exception diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 83f3a7e0..b3d6afef 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -57,9 +57,10 @@ class OnionShareGui(QtWidgets.QMainWindow): self.setWindowIcon(QtGui.QIcon(self.common.get_resource_path('images/logo.png'))) self.setMinimumWidth(850) - # Load settings + # Load settings, if a custom config was passed in self.config = config - self.common.load_settings(self.config) + if self.config: + self.common.load_settings(self.config) # System tray menu = QtWidgets.QMenu() diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 709ab059..7aff85a5 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -830,8 +830,29 @@ class SettingsDialog(QtWidgets.QDialog): """ self.common.log('SettingsDialog', 'save_clicked') + def changed(s1, s2, keys): + """ + Compare the Settings objects s1 and s2 and return true if any values + have changed for the given keys. + """ + for key in keys: + if s1.get(key) != s2.get(key): + return True + return False + settings = self.settings_from_fields() if settings: + # If language changed, inform user they need to restart OnionShare + if changed(settings, self.old_settings, ['locale']): + # Look up error message in different locale + new_locale = settings.get('locale') + if new_locale in strings.translations and 'gui_settings_language_changed_notice' in strings.translations[new_locale]: + notice = strings.translations[new_locale]['gui_settings_language_changed_notice'] + else: + notice = strings._('gui_settings_language_changed_notice') + Alert(self.common, notice, QtWidgets.QMessageBox.Information) + + # Save the new settings settings.save() # If Tor isn't connected, or if Tor settings have changed, Reinitialize @@ -840,15 +861,6 @@ class SettingsDialog(QtWidgets.QDialog): if not self.local_only: if self.onion.is_authenticated(): self.common.log('SettingsDialog', 'save_clicked', 'Connected to Tor') - def changed(s1, s2, keys): - """ - Compare the Settings objects s1 and s2 and return true if any values - have changed for the given keys. - """ - for key in keys: - if s1.get(key) != s2.get(key): - return True - return False if changed(settings, self.old_settings, [ 'connection_type', 'control_port_address', diff --git a/share/locale/en.json b/share/locale/en.json index 05830e62..02577f0d 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -181,5 +181,6 @@ "gui_upload_finished_range": "Uploaded {} to {}", "gui_upload_finished": "Uploaded {}", "gui_open_folder_error_nautilus": "Cannot open folder because nautilus is not available. The file is here: {}", - "gui_settings_language_label": "Preferred language" + "gui_settings_language_label": "Preferred language", + "gui_settings_language_changed_notice": "Restart OnionShare for your change in language to take effect." } From 30b14712e9ea8b63c71763564af2d81d1a146287 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 17:18:56 -0700 Subject: [PATCH 037/142] Make printing the settings filename as debug statement instead of print --- onionshare/settings.py | 2 +- share/locale/en.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/onionshare/settings.py b/onionshare/settings.py index 1fbda807..811ad032 100644 --- a/onionshare/settings.py +++ b/onionshare/settings.py @@ -164,7 +164,7 @@ class Settings(object): except: pass open(self.filename, 'w').write(json.dumps(self._settings)) - print(strings._('settings_saved').format(self.filename)) + self.common.log('Settings', 'save', 'Settings saved in {}'.format(self.filename)) def get(self, key): return self._settings[key] diff --git a/share/locale/en.json b/share/locale/en.json index 02577f0d..f5d887b5 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -106,7 +106,6 @@ "gui_settings_button_help": "Help", "gui_settings_shutdown_timeout_checkbox": "Use auto-stop timer", "gui_settings_shutdown_timeout": "Stop the share at:", - "settings_saved": "Settings saved in {}", "settings_error_unknown": "Can't connect to Tor controller because your settings don't make sense.", "settings_error_automatic": "Could not connect to the Tor controller. Is Tor Browser (available from torproject.org) running in the background?", "settings_error_socket_port": "Can't connect to the Tor controller at {}:{}.", From fc1360a0ba0d6959f89ade771026c0ef6cefe755 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 17:35:58 -0700 Subject: [PATCH 038/142] Fix tests --- onionshare/settings.py | 9 +++++++-- tests/conftest.py | 7 +++++-- tests/test_onionshare_strings.py | 12 ++++-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/onionshare/settings.py b/onionshare/settings.py index 811ad032..ed827cbd 100644 --- a/onionshare/settings.py +++ b/onionshare/settings.py @@ -122,8 +122,13 @@ class Settings(object): """ p = platform.system() if p == 'Windows': - appdata = os.environ['APPDATA'] - return '{}\\OnionShare\\onionshare.json'.format(appdata) + try: + appdata = os.environ['APPDATA'] + return '{}\\OnionShare\\onionshare.json'.format(appdata) + except: + # If for some reason we don't have the 'APPDATA' environment variable + # (like running tests in Linux while pretending to be in Windows) + return os.path.expanduser('~/.config/onionshare/onionshare.json') elif p == 'Darwin': return os.path.expanduser('~/Library/Application Support/OnionShare/onionshare.json') else: diff --git a/tests/conftest.py b/tests/conftest.py index 8ac7efb8..3ae6fd52 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,7 +8,7 @@ import tempfile import pytest -from onionshare import common, web, settings +from onionshare import common, web, settings, strings @pytest.fixture def temp_dir_1024(): @@ -151,7 +151,10 @@ def time_strftime(monkeypatch): @pytest.fixture def common_obj(): - return common.Common() + _common = common.Common() + _common.settings = settings.Settings(_common) + strings.load_strings(_common) + return _common @pytest.fixture def settings_obj(sys_onionshare_dev_mode, platform_linux): diff --git a/tests/test_onionshare_strings.py b/tests/test_onionshare_strings.py index d3d40c8f..6d39598c 100644 --- a/tests/test_onionshare_strings.py +++ b/tests/test_onionshare_strings.py @@ -32,12 +32,6 @@ from onionshare import strings # return path # common.get_resource_path = get_resource_path - -def test_starts_with_empty_strings(): - """ Creates an empty strings dict by default """ - assert strings.strings == {} - - def test_underscore_is_function(): assert callable(strings._) and isinstance(strings._, types.FunctionType) @@ -53,11 +47,13 @@ class TestLoadStrings: def test_load_strings_loads_other_languages( self, common_obj, locale_fr, sys_onionshare_dev_mode): """ load_strings() loads other languages in different locales """ - strings.load_strings(common_obj, "fr") + common_obj.settings.set('locale', 'fr') + strings.load_strings(common_obj) assert strings._('preparing_files') == "Préparation des fichiers à partager." 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): - strings.load_strings(common_obj, 'XX') + common_obj.settings.set('locale', 'XX') + strings.load_strings(common_obj) From e6302f3ba44091bbf358e33a868b43f466c325fd Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 17:47:10 -0700 Subject: [PATCH 039/142] Remove the useless gui=True arg getting passed intro strings._ all over the place --- onionshare/onion.py | 2 +- onionshare/strings.py | 2 +- onionshare_gui/__init__.py | 4 +- onionshare_gui/onionshare_gui.py | 50 ++++---- onionshare_gui/receive_mode/__init__.py | 14 +- onionshare_gui/receive_mode/uploads.py | 16 +-- onionshare_gui/server_status.py | 30 ++--- onionshare_gui/settings_dialog.py | 134 ++++++++++---------- onionshare_gui/share_mode/__init__.py | 26 ++-- onionshare_gui/share_mode/downloads.py | 8 +- onionshare_gui/share_mode/file_selection.py | 12 +- onionshare_gui/tor_connection_dialog.py | 6 +- 12 files changed, 152 insertions(+), 152 deletions(-) diff --git a/onionshare/onion.py b/onionshare/onion.py index c45ae72e..cb73e976 100644 --- a/onionshare/onion.py +++ b/onionshare/onion.py @@ -247,7 +247,7 @@ class Onion(object): self.c = Controller.from_socket_file(path=self.tor_control_socket) self.c.authenticate() except Exception as e: - raise BundledTorBroken(strings._('settings_error_bundled_tor_broken', True).format(e.args[0])) + raise BundledTorBroken(strings._('settings_error_bundled_tor_broken').format(e.args[0])) while True: try: diff --git a/onionshare/strings.py b/onionshare/strings.py index edae7849..b730933d 100644 --- a/onionshare/strings.py +++ b/onionshare/strings.py @@ -51,7 +51,7 @@ def load_strings(common): strings[s] = translations[default_locale][s] -def translated(k, gui=False): +def translated(k): """ Returns a translated string. """ diff --git a/onionshare_gui/__init__.py b/onionshare_gui/__init__.py index 51565cb6..b5520071 100644 --- a/onionshare_gui/__init__.py +++ b/onionshare_gui/__init__.py @@ -100,10 +100,10 @@ def main(): valid = True for filename in filenames: if not os.path.isfile(filename) and not os.path.isdir(filename): - Alert(common, strings._("not_a_file", True).format(filename)) + Alert(common, strings._("not_a_file").format(filename)) valid = False if not os.access(filename, os.R_OK): - Alert(common, strings._("not_a_readable_file", True).format(filename)) + Alert(common, strings._("not_a_readable_file").format(filename)) valid = False if not valid: sys.exit() diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index b3d6afef..1b3a62a2 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -64,11 +64,11 @@ class OnionShareGui(QtWidgets.QMainWindow): # System tray menu = QtWidgets.QMenu() - self.settings_action = menu.addAction(strings._('gui_settings_window_title', True)) + self.settings_action = menu.addAction(strings._('gui_settings_window_title')) self.settings_action.triggered.connect(self.open_settings) - help_action = menu.addAction(strings._('gui_settings_button_help', True)) + help_action = menu.addAction(strings._('gui_settings_button_help')) help_action.triggered.connect(SettingsDialog.help_clicked) - exit_action = menu.addAction(strings._('systray_menu_exit', True)) + exit_action = menu.addAction(strings._('systray_menu_exit')) exit_action.triggered.connect(self.close) self.system_tray = QtWidgets.QSystemTrayIcon(self) @@ -81,10 +81,10 @@ class OnionShareGui(QtWidgets.QMainWindow): self.system_tray.show() # Mode switcher, to switch between share files and receive files - self.share_mode_button = QtWidgets.QPushButton(strings._('gui_mode_share_button', True)); + self.share_mode_button = QtWidgets.QPushButton(strings._('gui_mode_share_button')); self.share_mode_button.setFixedHeight(50) self.share_mode_button.clicked.connect(self.share_mode_clicked) - self.receive_mode_button = QtWidgets.QPushButton(strings._('gui_mode_receive_button', True)); + self.receive_mode_button = QtWidgets.QPushButton(strings._('gui_mode_receive_button')); self.receive_mode_button.setFixedHeight(50) self.receive_mode_button.clicked.connect(self.receive_mode_clicked) self.settings_button = QtWidgets.QPushButton() @@ -224,24 +224,24 @@ class OnionShareGui(QtWidgets.QMainWindow): # Share mode if self.share_mode.server_status.status == ServerStatus.STATUS_STOPPED: self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_stopped)) - self.server_status_label.setText(strings._('gui_status_indicator_share_stopped', True)) + self.server_status_label.setText(strings._('gui_status_indicator_share_stopped')) elif self.share_mode.server_status.status == ServerStatus.STATUS_WORKING: self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_working)) - self.server_status_label.setText(strings._('gui_status_indicator_share_working', True)) + self.server_status_label.setText(strings._('gui_status_indicator_share_working')) elif self.share_mode.server_status.status == ServerStatus.STATUS_STARTED: self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_started)) - self.server_status_label.setText(strings._('gui_status_indicator_share_started', True)) + self.server_status_label.setText(strings._('gui_status_indicator_share_started')) else: # Receive mode if self.receive_mode.server_status.status == ServerStatus.STATUS_STOPPED: self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_stopped)) - self.server_status_label.setText(strings._('gui_status_indicator_receive_stopped', True)) + self.server_status_label.setText(strings._('gui_status_indicator_receive_stopped')) elif self.receive_mode.server_status.status == ServerStatus.STATUS_WORKING: self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_working)) - self.server_status_label.setText(strings._('gui_status_indicator_receive_working', True)) + self.server_status_label.setText(strings._('gui_status_indicator_receive_working')) elif self.receive_mode.server_status.status == ServerStatus.STATUS_STARTED: self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_started)) - self.server_status_label.setText(strings._('gui_status_indicator_receive_started', True)) + self.server_status_label.setText(strings._('gui_status_indicator_receive_started')) def stop_server_finished(self): # When the server stopped, cleanup the ephemeral onion service @@ -255,9 +255,9 @@ class OnionShareGui(QtWidgets.QMainWindow): self.common.log('OnionShareGui', '_tor_connection_canceled') def ask(): - a = Alert(self.common, strings._('gui_tor_connection_ask', True), QtWidgets.QMessageBox.Question, buttons=QtWidgets.QMessageBox.NoButton, autostart=False) - settings_button = QtWidgets.QPushButton(strings._('gui_tor_connection_ask_open_settings', True)) - quit_button = QtWidgets.QPushButton(strings._('gui_tor_connection_ask_quit', True)) + a = Alert(self.common, strings._('gui_tor_connection_ask'), QtWidgets.QMessageBox.Question, buttons=QtWidgets.QMessageBox.NoButton, autostart=False) + settings_button = QtWidgets.QPushButton(strings._('gui_tor_connection_ask_open_settings')) + quit_button = QtWidgets.QPushButton(strings._('gui_tor_connection_ask_quit')) a.addButton(settings_button, QtWidgets.QMessageBox.AcceptRole) a.addButton(quit_button, QtWidgets.QMessageBox.RejectRole) a.setDefaultButton(settings_button) @@ -328,7 +328,7 @@ class OnionShareGui(QtWidgets.QMainWindow): if self.common.platform == 'Windows' or self.common.platform == 'Darwin': if self.common.settings.get('use_autoupdate'): def update_available(update_url, installed_version, latest_version): - Alert(self.common, strings._("update_available", True).format(update_url, installed_version, latest_version)) + Alert(self.common, strings._("update_available").format(update_url, installed_version, latest_version)) self.update_thread = UpdateThread(self.common, self.onion, self.config) self.update_thread.update_available.connect(update_available) @@ -345,8 +345,8 @@ class OnionShareGui(QtWidgets.QMainWindow): # Have we lost connection to Tor somehow? if not self.onion.is_authenticated(): self.timer.stop() - self.status_bar.showMessage(strings._('gui_tor_connection_lost', True)) - self.system_tray.showMessage(strings._('gui_tor_connection_lost', True), strings._('gui_tor_connection_error_settings', True)) + self.status_bar.showMessage(strings._('gui_tor_connection_lost')) + self.system_tray.showMessage(strings._('gui_tor_connection_lost'), strings._('gui_tor_connection_error_settings')) self.share_mode.handle_tor_broke() self.receive_mode.handle_tor_broke() @@ -400,7 +400,7 @@ class OnionShareGui(QtWidgets.QMainWindow): if event["type"] == Web.REQUEST_OTHER: if event["path"] != '/favicon.ico' and event["path"] != "/{}/shutdown".format(mode.web.shutdown_slug): - self.status_bar.showMessage('[#{0:d}] {1:s}: {2:s}'.format(mode.web.error404_count, strings._('other_page_loaded', True), event["path"])) + self.status_bar.showMessage('[#{0:d}] {1:s}: {2:s}'.format(mode.web.error404_count, strings._('other_page_loaded'), event["path"])) mode.timer_callback() @@ -409,14 +409,14 @@ class OnionShareGui(QtWidgets.QMainWindow): When the URL gets copied to the clipboard, display this in the status bar. """ self.common.log('OnionShareGui', 'copy_url') - self.system_tray.showMessage(strings._('gui_copied_url_title', True), strings._('gui_copied_url', True)) + self.system_tray.showMessage(strings._('gui_copied_url_title'), strings._('gui_copied_url')) def copy_hidservauth(self): """ When the stealth onion service HidServAuth gets copied to the clipboard, display this in the status bar. """ self.common.log('OnionShareGui', 'copy_hidservauth') - self.system_tray.showMessage(strings._('gui_copied_hidservauth_title', True), strings._('gui_copied_hidservauth', True)) + self.system_tray.showMessage(strings._('gui_copied_hidservauth_title'), strings._('gui_copied_hidservauth')) def clear_message(self): """ @@ -454,14 +454,14 @@ class OnionShareGui(QtWidgets.QMainWindow): if server_status.status != server_status.STATUS_STOPPED: self.common.log('OnionShareGui', 'closeEvent, opening warning dialog') dialog = QtWidgets.QMessageBox() - dialog.setWindowTitle(strings._('gui_quit_title', True)) + dialog.setWindowTitle(strings._('gui_quit_title')) if self.mode == OnionShareGui.MODE_SHARE: - dialog.setText(strings._('gui_share_quit_warning', True)) + dialog.setText(strings._('gui_share_quit_warning')) else: - dialog.setText(strings._('gui_receive_quit_warning', True)) + dialog.setText(strings._('gui_receive_quit_warning')) dialog.setIcon(QtWidgets.QMessageBox.Critical) - quit_button = dialog.addButton(strings._('gui_quit_warning_quit', True), QtWidgets.QMessageBox.YesRole) - dont_quit_button = dialog.addButton(strings._('gui_quit_warning_dont_quit', True), QtWidgets.QMessageBox.NoRole) + quit_button = dialog.addButton(strings._('gui_quit_warning_quit'), QtWidgets.QMessageBox.YesRole) + dont_quit_button = dialog.addButton(strings._('gui_quit_warning_dont_quit'), QtWidgets.QMessageBox.NoRole) dialog.setDefaultButton(dont_quit_button) reply = dialog.exec_() diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/receive_mode/__init__.py index 590dec65..1207a0f3 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/receive_mode/__init__.py @@ -72,7 +72,7 @@ class ReceiveMode(Mode): self.info_widget.hide() # Receive mode info - self.receive_info = QtWidgets.QLabel(strings._('gui_receive_mode_warning', True)) + self.receive_info = QtWidgets.QLabel(strings._('gui_receive_mode_warning')) self.receive_info.setMinimumHeight(80) self.receive_info.setWordWrap(True) @@ -86,7 +86,7 @@ class ReceiveMode(Mode): """ Return the string to put on the stop server button, if there's a shutdown timeout """ - return strings._('gui_receive_stop_server_shutdown_timeout', True) + return strings._('gui_receive_stop_server_shutdown_timeout') def timeout_finished_should_stop_server(self): """ @@ -125,7 +125,7 @@ class ReceiveMode(Mode): """ Handle REQUEST_LOAD event. """ - self.system_tray.showMessage(strings._('systray_page_loaded_title', True), strings._('systray_upload_page_loaded_message', True)) + self.system_tray.showMessage(strings._('systray_page_loaded_title'), strings._('systray_upload_page_loaded_message')) def handle_request_started(self, event): """ @@ -135,7 +135,7 @@ class ReceiveMode(Mode): self.uploads_in_progress += 1 self.update_uploads_in_progress() - self.system_tray.showMessage(strings._('systray_upload_started_title', True), strings._('systray_upload_started_message', True)) + self.system_tray.showMessage(strings._('systray_upload_started_title'), strings._('systray_upload_started_message')) def handle_request_progress(self, event): """ @@ -148,7 +148,7 @@ class ReceiveMode(Mode): Handle REQUEST_CLOSE_SERVER event. """ self.stop_server() - self.system_tray.showMessage(strings._('systray_close_server_title', True), strings._('systray_close_server_message', True)) + self.system_tray.showMessage(strings._('systray_close_server_title'), strings._('systray_close_server_message')) def handle_request_upload_file_renamed(self, event): """ @@ -194,7 +194,7 @@ class ReceiveMode(Mode): else: image = self.common.get_resource_path('images/share_completed.png') self.info_completed_uploads_count.setText(' {1:d}'.format(image, self.uploads_completed)) - self.info_completed_uploads_count.setToolTip(strings._('info_completed_uploads_tooltip', True).format(self.uploads_completed)) + self.info_completed_uploads_count.setToolTip(strings._('info_completed_uploads_tooltip').format(self.uploads_completed)) def update_uploads_in_progress(self): """ @@ -205,7 +205,7 @@ class ReceiveMode(Mode): else: image = self.common.get_resource_path('images/share_in_progress.png') self.info_in_progress_uploads_count.setText(' {1:d}'.format(image, self.uploads_in_progress)) - self.info_in_progress_uploads_count.setToolTip(strings._('info_in_progress_uploads_tooltip', True).format(self.uploads_in_progress)) + self.info_in_progress_uploads_count.setToolTip(strings._('info_in_progress_uploads_tooltip').format(self.uploads_in_progress)) def update_primary_action(self): self.common.log('ReceiveMode', 'update_primary_action') diff --git a/onionshare_gui/receive_mode/uploads.py b/onionshare_gui/receive_mode/uploads.py index 48574cc7..33d993b3 100644 --- a/onionshare_gui/receive_mode/uploads.py +++ b/onionshare_gui/receive_mode/uploads.py @@ -113,7 +113,7 @@ class Upload(QtWidgets.QWidget): self.started = datetime.now() # Label - self.label = QtWidgets.QLabel(strings._('gui_upload_in_progress', True).format(self.started.strftime("%b %d, %I:%M%p"))) + self.label = QtWidgets.QLabel(strings._('gui_upload_in_progress').format(self.started.strftime("%b %d, %I:%M%p"))) # Progress bar self.progress_bar = QtWidgets.QProgressBar() @@ -190,16 +190,16 @@ class Upload(QtWidgets.QWidget): self.ended = self.started = datetime.now() if self.started.year == self.ended.year and self.started.month == self.ended.month and self.started.day == self.ended.day: if self.started.hour == self.ended.hour and self.started.minute == self.ended.minute: - text = strings._('gui_upload_finished', True).format( + text = strings._('gui_upload_finished').format( self.started.strftime("%b %d, %I:%M%p") ) else: - text = strings._('gui_upload_finished_range', True).format( + text = strings._('gui_upload_finished_range').format( self.started.strftime("%b %d, %I:%M%p"), self.ended.strftime("%I:%M%p") ) else: - text = strings._('gui_upload_finished_range', True).format( + text = strings._('gui_upload_finished_range').format( self.started.strftime("%b %d, %I:%M%p"), self.ended.strftime("%b %d, %I:%M%p") ) @@ -220,7 +220,7 @@ class Uploads(QtWidgets.QScrollArea): self.uploads = {} - self.setWindowTitle(strings._('gui_uploads', True)) + self.setWindowTitle(strings._('gui_uploads')) self.setWidgetResizable(True) self.setMinimumHeight(150) self.setMinimumWidth(350) @@ -229,10 +229,10 @@ class Uploads(QtWidgets.QScrollArea): self.vbar = self.verticalScrollBar() self.vbar.rangeChanged.connect(self.resizeScroll) - uploads_label = QtWidgets.QLabel(strings._('gui_uploads', True)) + uploads_label = QtWidgets.QLabel(strings._('gui_uploads')) uploads_label.setStyleSheet(self.common.css['downloads_uploads_label']) - self.no_uploads_label = QtWidgets.QLabel(strings._('gui_no_uploads', True)) - self.clear_history_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) + self.no_uploads_label = QtWidgets.QLabel(strings._('gui_no_uploads')) + self.clear_history_button = QtWidgets.QPushButton(strings._('gui_clear_history')) self.clear_history_button.clicked.connect(self.reset) self.clear_history_button.hide() diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 32135ca4..f1ffe995 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -61,7 +61,7 @@ class ServerStatus(QtWidgets.QWidget): self.resizeEvent(None) # Shutdown timeout layout - self.shutdown_timeout_label = QtWidgets.QLabel(strings._('gui_settings_shutdown_timeout', True)) + self.shutdown_timeout_label = QtWidgets.QLabel(strings._('gui_settings_shutdown_timeout')) self.shutdown_timeout = QtWidgets.QDateTimeEdit() self.shutdown_timeout.setDisplayFormat("hh:mm A MMM d, yy") if self.local_only: @@ -101,11 +101,11 @@ class ServerStatus(QtWidgets.QWidget): self.url.setMinimumSize(self.url.sizeHint()) self.url.setStyleSheet(self.common.css['server_status_url']) - self.copy_url_button = QtWidgets.QPushButton(strings._('gui_copy_url', True)) + self.copy_url_button = QtWidgets.QPushButton(strings._('gui_copy_url')) self.copy_url_button.setFlat(True) self.copy_url_button.setStyleSheet(self.common.css['server_status_url_buttons']) self.copy_url_button.clicked.connect(self.copy_url) - self.copy_hidservauth_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth', True)) + self.copy_hidservauth_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth')) self.copy_hidservauth_button.setFlat(True) self.copy_hidservauth_button.setStyleSheet(self.common.css['server_status_url_buttons']) self.copy_hidservauth_button.clicked.connect(self.copy_hidservauth) @@ -174,21 +174,21 @@ class ServerStatus(QtWidgets.QWidget): info_image = self.common.get_resource_path('images/info.png') if self.mode == ServerStatus.MODE_SHARE: - self.url_description.setText(strings._('gui_share_url_description', True).format(info_image)) + self.url_description.setText(strings._('gui_share_url_description').format(info_image)) else: - self.url_description.setText(strings._('gui_receive_url_description', True).format(info_image)) + self.url_description.setText(strings._('gui_receive_url_description').format(info_image)) # Show a Tool Tip explaining the lifecycle of this URL if self.common.settings.get('save_private_key'): if self.mode == ServerStatus.MODE_SHARE and self.common.settings.get('close_after_first_download'): - self.url_description.setToolTip(strings._('gui_url_label_onetime_and_persistent', True)) + self.url_description.setToolTip(strings._('gui_url_label_onetime_and_persistent')) else: - self.url_description.setToolTip(strings._('gui_url_label_persistent', True)) + self.url_description.setToolTip(strings._('gui_url_label_persistent')) else: if self.mode == ServerStatus.MODE_SHARE and self.common.settings.get('close_after_first_download'): - self.url_description.setToolTip(strings._('gui_url_label_onetime', True)) + self.url_description.setToolTip(strings._('gui_url_label_onetime')) else: - self.url_description.setToolTip(strings._('gui_url_label_stay_open', True)) + self.url_description.setToolTip(strings._('gui_url_label_stay_open')) self.url.setText(self.get_url()) self.url.show() @@ -223,9 +223,9 @@ class ServerStatus(QtWidgets.QWidget): self.server_button.setStyleSheet(self.common.css['server_status_button_stopped']) self.server_button.setEnabled(True) if self.mode == ServerStatus.MODE_SHARE: - self.server_button.setText(strings._('gui_share_start_server', True)) + self.server_button.setText(strings._('gui_share_start_server')) else: - self.server_button.setText(strings._('gui_receive_start_server', True)) + self.server_button.setText(strings._('gui_receive_start_server')) self.server_button.setToolTip('') if self.common.settings.get('shutdown_timeout'): self.shutdown_timeout_container.show() @@ -233,15 +233,15 @@ class ServerStatus(QtWidgets.QWidget): self.server_button.setStyleSheet(self.common.css['server_status_button_started']) self.server_button.setEnabled(True) if self.mode == ServerStatus.MODE_SHARE: - self.server_button.setText(strings._('gui_share_stop_server', True)) + self.server_button.setText(strings._('gui_share_stop_server')) else: - self.server_button.setText(strings._('gui_receive_stop_server', True)) + self.server_button.setText(strings._('gui_receive_stop_server')) if self.common.settings.get('shutdown_timeout'): self.shutdown_timeout_container.hide() if self.mode == ServerStatus.MODE_SHARE: - self.server_button.setToolTip(strings._('gui_share_stop_server_shutdown_timeout_tooltip', True).format(self.timeout)) + self.server_button.setToolTip(strings._('gui_share_stop_server_shutdown_timeout_tooltip').format(self.timeout)) else: - self.server_button.setToolTip(strings._('gui_receive_stop_server_shutdown_timeout_tooltip', True).format(self.timeout)) + self.server_button.setToolTip(strings._('gui_receive_stop_server_shutdown_timeout_tooltip').format(self.timeout)) elif self.status == self.STATUS_WORKING: self.server_button.setStyleSheet(self.common.css['server_status_button_working']) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 7aff85a5..b9e0453a 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -47,7 +47,7 @@ class SettingsDialog(QtWidgets.QDialog): self.local_only = local_only self.setModal(True) - self.setWindowTitle(strings._('gui_settings_window_title', True)) + self.setWindowTitle(strings._('gui_settings_window_title')) self.setWindowIcon(QtGui.QIcon(self.common.get_resource_path('images/logo.png'))) self.system = platform.system() @@ -57,8 +57,8 @@ class SettingsDialog(QtWidgets.QDialog): # Use a slug or not ('public mode') self.public_mode_checkbox = QtWidgets.QCheckBox() self.public_mode_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.public_mode_checkbox.setText(strings._("gui_settings_public_mode_checkbox", True)) - public_mode_label = QtWidgets.QLabel(strings._("gui_settings_whats_this", True).format("https://github.com/micahflee/onionshare/wiki/Public-Mode")) + self.public_mode_checkbox.setText(strings._("gui_settings_public_mode_checkbox")) + public_mode_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Public-Mode")) public_mode_label.setStyleSheet(self.common.css['settings_whats_this']) public_mode_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) public_mode_label.setOpenExternalLinks(True) @@ -74,8 +74,8 @@ class SettingsDialog(QtWidgets.QDialog): # Whether or not to use a shutdown ('auto-stop') timer self.shutdown_timeout_checkbox = QtWidgets.QCheckBox() self.shutdown_timeout_checkbox.setCheckState(QtCore.Qt.Checked) - self.shutdown_timeout_checkbox.setText(strings._("gui_settings_shutdown_timeout_checkbox", True)) - shutdown_timeout_label = QtWidgets.QLabel(strings._("gui_settings_whats_this", True).format("https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Stop-Timer")) + self.shutdown_timeout_checkbox.setText(strings._("gui_settings_shutdown_timeout_checkbox")) + shutdown_timeout_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Stop-Timer")) shutdown_timeout_label.setStyleSheet(self.common.css['settings_whats_this']) shutdown_timeout_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) shutdown_timeout_label.setOpenExternalLinks(True) @@ -91,9 +91,9 @@ class SettingsDialog(QtWidgets.QDialog): # Whether or not to use legacy v2 onions self.use_legacy_v2_onions_checkbox = QtWidgets.QCheckBox() self.use_legacy_v2_onions_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.use_legacy_v2_onions_checkbox.setText(strings._("gui_use_legacy_v2_onions_checkbox", True)) + self.use_legacy_v2_onions_checkbox.setText(strings._("gui_use_legacy_v2_onions_checkbox")) self.use_legacy_v2_onions_checkbox.clicked.connect(self.use_legacy_v2_onions_checkbox_clicked) - use_legacy_v2_onions_label = QtWidgets.QLabel(strings._("gui_settings_whats_this", True).format("https://github.com/micahflee/onionshare/wiki/Legacy-Addresses")) + use_legacy_v2_onions_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Legacy-Addresses")) use_legacy_v2_onions_label.setStyleSheet(self.common.css['settings_whats_this']) use_legacy_v2_onions_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) use_legacy_v2_onions_label.setOpenExternalLinks(True) @@ -108,9 +108,9 @@ class SettingsDialog(QtWidgets.QDialog): # Whether or not to save the Onion private key for reuse (persistent URL mode) self.save_private_key_checkbox = QtWidgets.QCheckBox() self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.save_private_key_checkbox.setText(strings._("gui_save_private_key_checkbox", True)) + self.save_private_key_checkbox.setText(strings._("gui_save_private_key_checkbox")) self.save_private_key_checkbox.clicked.connect(self.save_private_key_checkbox_clicked) - save_private_key_label = QtWidgets.QLabel(strings._("gui_settings_whats_this", True).format("https://github.com/micahflee/onionshare/wiki/Using-a-Persistent-URL")) + save_private_key_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Using-a-Persistent-URL")) save_private_key_label.setStyleSheet(self.common.css['settings_whats_this']) save_private_key_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) save_private_key_label.setOpenExternalLinks(True) @@ -125,9 +125,9 @@ class SettingsDialog(QtWidgets.QDialog): # Stealth self.stealth_checkbox = QtWidgets.QCheckBox() self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.stealth_checkbox.setText(strings._("gui_settings_stealth_option", True)) + self.stealth_checkbox.setText(strings._("gui_settings_stealth_option")) self.stealth_checkbox.clicked.connect(self.stealth_checkbox_clicked_connect) - use_stealth_label = QtWidgets.QLabel(strings._("gui_settings_whats_this", True).format("https://github.com/micahflee/onionshare/wiki/Stealth-Onion-Services")) + use_stealth_label = QtWidgets.QLabel(strings._("gui_settings_whats_this").format("https://github.com/micahflee/onionshare/wiki/Stealth-Onion-Services")) use_stealth_label.setStyleSheet(self.common.css['settings_whats_this']) use_stealth_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) use_stealth_label.setOpenExternalLinks(True) @@ -140,12 +140,12 @@ class SettingsDialog(QtWidgets.QDialog): self.use_stealth_widget = QtWidgets.QWidget() self.use_stealth_widget.setLayout(use_stealth_layout) - hidservauth_details = QtWidgets.QLabel(strings._('gui_settings_stealth_hidservauth_string', True)) + hidservauth_details = QtWidgets.QLabel(strings._('gui_settings_stealth_hidservauth_string')) hidservauth_details.setWordWrap(True) hidservauth_details.setMinimumSize(hidservauth_details.sizeHint()) hidservauth_details.hide() - self.hidservauth_copy_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth', True)) + self.hidservauth_copy_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth')) self.hidservauth_copy_button.clicked.connect(self.hidservauth_copy_button_clicked) self.hidservauth_copy_button.hide() @@ -159,7 +159,7 @@ class SettingsDialog(QtWidgets.QDialog): general_group_layout.addWidget(hidservauth_details) general_group_layout.addWidget(self.hidservauth_copy_button) - general_group = QtWidgets.QGroupBox(strings._("gui_settings_general_label", True)) + general_group = QtWidgets.QGroupBox(strings._("gui_settings_general_label")) general_group.setLayout(general_group_layout) # Sharing options @@ -167,19 +167,19 @@ class SettingsDialog(QtWidgets.QDialog): # Close after first download self.close_after_first_download_checkbox = QtWidgets.QCheckBox() self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) - self.close_after_first_download_checkbox.setText(strings._("gui_settings_close_after_first_download_option", True)) + self.close_after_first_download_checkbox.setText(strings._("gui_settings_close_after_first_download_option")) # Sharing options layout sharing_group_layout = QtWidgets.QVBoxLayout() sharing_group_layout.addWidget(self.close_after_first_download_checkbox) - sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label", True)) + sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label")) sharing_group.setLayout(sharing_group_layout) # Downloads dir - downloads_label = QtWidgets.QLabel(strings._('gui_settings_downloads_label', True)); + downloads_label = QtWidgets.QLabel(strings._('gui_settings_downloads_label')); self.downloads_dir_lineedit = QtWidgets.QLineEdit() self.downloads_dir_lineedit.setReadOnly(True) - downloads_button = QtWidgets.QPushButton(strings._('gui_settings_downloads_button', True)) + downloads_button = QtWidgets.QPushButton(strings._('gui_settings_downloads_button')) downloads_button.clicked.connect(self.downloads_button_clicked) downloads_layout = QtWidgets.QHBoxLayout() downloads_layout.addWidget(downloads_label) @@ -189,13 +189,13 @@ class SettingsDialog(QtWidgets.QDialog): # Allow the receiver to shutdown the server self.receive_allow_receiver_shutdown_checkbox = QtWidgets.QCheckBox() self.receive_allow_receiver_shutdown_checkbox.setCheckState(QtCore.Qt.Checked) - self.receive_allow_receiver_shutdown_checkbox.setText(strings._("gui_settings_receive_allow_receiver_shutdown_checkbox", True)) + self.receive_allow_receiver_shutdown_checkbox.setText(strings._("gui_settings_receive_allow_receiver_shutdown_checkbox")) # Receiving options layout receiving_group_layout = QtWidgets.QVBoxLayout() receiving_group_layout.addLayout(downloads_layout) receiving_group_layout.addWidget(self.receive_allow_receiver_shutdown_checkbox) - receiving_group = QtWidgets.QGroupBox(strings._("gui_settings_receiving_label", True)) + receiving_group = QtWidgets.QGroupBox(strings._("gui_settings_receiving_label")) receiving_group.setLayout(receiving_group_layout) # Automatic updates options @@ -203,13 +203,13 @@ class SettingsDialog(QtWidgets.QDialog): # Autoupdate self.autoupdate_checkbox = QtWidgets.QCheckBox() self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) - self.autoupdate_checkbox.setText(strings._("gui_settings_autoupdate_option", True)) + self.autoupdate_checkbox.setText(strings._("gui_settings_autoupdate_option")) # Last update time self.autoupdate_timestamp = QtWidgets.QLabel() # Check for updates button - self.check_for_updates_button = QtWidgets.QPushButton(strings._('gui_settings_autoupdate_check_button', True)) + self.check_for_updates_button = QtWidgets.QPushButton(strings._('gui_settings_autoupdate_check_button')) self.check_for_updates_button.clicked.connect(self.check_for_updates) # We can't check for updates if not connected to Tor if not self.onion.connected_to_tor: @@ -220,7 +220,7 @@ class SettingsDialog(QtWidgets.QDialog): autoupdate_group_layout.addWidget(self.autoupdate_checkbox) autoupdate_group_layout.addWidget(self.autoupdate_timestamp) autoupdate_group_layout.addWidget(self.check_for_updates_button) - autoupdate_group = QtWidgets.QGroupBox(strings._("gui_settings_autoupdate_label", True)) + autoupdate_group = QtWidgets.QGroupBox(strings._("gui_settings_autoupdate_label")) autoupdate_group.setLayout(autoupdate_group_layout) # Autoupdate is only available for Windows and Mac (Linux updates using package manager) @@ -228,7 +228,7 @@ class SettingsDialog(QtWidgets.QDialog): autoupdate_group.hide() # Language settings - language_label = QtWidgets.QLabel(strings._("gui_settings_language_label", True)) + language_label = QtWidgets.QLabel(strings._("gui_settings_language_label")) self.language_combobox = QtWidgets.QComboBox() # Populate the dropdown with all of OnionShare's available languages language_names_to_locales = {v: k for k, v in self.common.settings.available_locales.items()} @@ -245,7 +245,7 @@ class SettingsDialog(QtWidgets.QDialog): # Connection type: either automatic, control port, or socket file # Bundled Tor - self.connection_type_bundled_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_bundled_option', True)) + self.connection_type_bundled_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_bundled_option')) self.connection_type_bundled_radio.toggled.connect(self.connection_type_bundled_toggled) # Bundled Tor doesn't work on dev mode in Windows or Mac @@ -255,27 +255,27 @@ class SettingsDialog(QtWidgets.QDialog): # Bridge options for bundled tor # No bridges option radio - self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_no_bridges_radio_option', True)) + self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_no_bridges_radio_option')) self.tor_bridges_no_bridges_radio.toggled.connect(self.tor_bridges_no_bridges_radio_toggled) # obfs4 option radio # if the obfs4proxy binary is missing, we can't use obfs4 transports (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = self.common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): - self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy', True)) + self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy')) self.tor_bridges_use_obfs4_radio.setEnabled(False) else: - self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option', True)) + self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_obfs4_radio_option')) self.tor_bridges_use_obfs4_radio.toggled.connect(self.tor_bridges_use_obfs4_radio_toggled) # meek_lite-azure option radio # if the obfs4proxy binary is missing, we can't use meek_lite-azure transports (self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path) = self.common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): - self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy', True)) + self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy')) self.tor_bridges_use_meek_lite_azure_radio.setEnabled(False) else: - self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option', True)) + self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_meek_lite_azure_radio_option')) self.tor_bridges_use_meek_lite_azure_radio.toggled.connect(self.tor_bridges_use_meek_lite_azure_radio_toggled) # meek_lite currently not supported on the version of obfs4proxy bundled with TorBrowser @@ -283,10 +283,10 @@ class SettingsDialog(QtWidgets.QDialog): self.tor_bridges_use_meek_lite_azure_radio.hide() # Custom bridges radio and textbox - self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_custom_radio_option', True)) + self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton(strings._('gui_settings_tor_bridges_custom_radio_option')) self.tor_bridges_use_custom_radio.toggled.connect(self.tor_bridges_use_custom_radio_toggled) - self.tor_bridges_use_custom_label = QtWidgets.QLabel(strings._('gui_settings_tor_bridges_custom_label', True)) + self.tor_bridges_use_custom_label = QtWidgets.QLabel(strings._('gui_settings_tor_bridges_custom_label')) self.tor_bridges_use_custom_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) self.tor_bridges_use_custom_label.setOpenExternalLinks(True) self.tor_bridges_use_custom_textbox = QtWidgets.QPlainTextEdit() @@ -313,14 +313,14 @@ class SettingsDialog(QtWidgets.QDialog): self.bridges.setLayout(bridges_layout) # Automatic - self.connection_type_automatic_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_automatic_option', True)) + self.connection_type_automatic_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_automatic_option')) self.connection_type_automatic_radio.toggled.connect(self.connection_type_automatic_toggled) # Control port - self.connection_type_control_port_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_control_port_option', True)) + self.connection_type_control_port_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_control_port_option')) self.connection_type_control_port_radio.toggled.connect(self.connection_type_control_port_toggled) - connection_type_control_port_extras_label = QtWidgets.QLabel(strings._('gui_settings_control_port_label', True)) + connection_type_control_port_extras_label = QtWidgets.QLabel(strings._('gui_settings_control_port_label')) self.connection_type_control_port_extras_address = QtWidgets.QLineEdit() self.connection_type_control_port_extras_port = QtWidgets.QLineEdit() connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout() @@ -333,10 +333,10 @@ class SettingsDialog(QtWidgets.QDialog): self.connection_type_control_port_extras.hide() # Socket file - self.connection_type_socket_file_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_socket_file_option', True)) + self.connection_type_socket_file_radio = QtWidgets.QRadioButton(strings._('gui_settings_connection_type_socket_file_option')) self.connection_type_socket_file_radio.toggled.connect(self.connection_type_socket_file_toggled) - connection_type_socket_file_extras_label = QtWidgets.QLabel(strings._('gui_settings_socket_file_label', True)) + connection_type_socket_file_extras_label = QtWidgets.QLabel(strings._('gui_settings_socket_file_label')) self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit() connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout() connection_type_socket_file_extras_layout.addWidget(connection_type_socket_file_extras_label) @@ -347,7 +347,7 @@ class SettingsDialog(QtWidgets.QDialog): self.connection_type_socket_file_extras.hide() # Tor SOCKS address and port - gui_settings_socks_label = QtWidgets.QLabel(strings._('gui_settings_socks_label', True)) + gui_settings_socks_label = QtWidgets.QLabel(strings._('gui_settings_socks_label')) self.connection_type_socks_address = QtWidgets.QLineEdit() self.connection_type_socks_port = QtWidgets.QLineEdit() connection_type_socks_layout = QtWidgets.QHBoxLayout() @@ -362,14 +362,14 @@ class SettingsDialog(QtWidgets.QDialog): # Authentication options # No authentication - self.authenticate_no_auth_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_no_auth_option', True)) + self.authenticate_no_auth_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_no_auth_option')) self.authenticate_no_auth_radio.toggled.connect(self.authenticate_no_auth_toggled) # Password - self.authenticate_password_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_password_option', True)) + self.authenticate_password_radio = QtWidgets.QRadioButton(strings._('gui_settings_authenticate_password_option')) self.authenticate_password_radio.toggled.connect(self.authenticate_password_toggled) - authenticate_password_extras_label = QtWidgets.QLabel(strings._('gui_settings_password_label', True)) + authenticate_password_extras_label = QtWidgets.QLabel(strings._('gui_settings_password_label')) self.authenticate_password_extras_password = QtWidgets.QLineEdit('') authenticate_password_extras_layout = QtWidgets.QHBoxLayout() authenticate_password_extras_layout.addWidget(authenticate_password_extras_label) @@ -384,7 +384,7 @@ class SettingsDialog(QtWidgets.QDialog): authenticate_group_layout.addWidget(self.authenticate_no_auth_radio) authenticate_group_layout.addWidget(self.authenticate_password_radio) authenticate_group_layout.addWidget(self.authenticate_password_extras) - self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label", True)) + self.authenticate_group = QtWidgets.QGroupBox(strings._("gui_settings_authenticate_label")) self.authenticate_group.setLayout(authenticate_group_layout) # Put the radios into their own group so they are exclusive @@ -393,18 +393,18 @@ class SettingsDialog(QtWidgets.QDialog): connection_type_radio_group_layout.addWidget(self.connection_type_automatic_radio) connection_type_radio_group_layout.addWidget(self.connection_type_control_port_radio) connection_type_radio_group_layout.addWidget(self.connection_type_socket_file_radio) - connection_type_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_connection_type_label", True)) + connection_type_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_connection_type_label")) connection_type_radio_group.setLayout(connection_type_radio_group_layout) # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges) connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_bridges_radio_group_layout.addWidget(self.bridges) - self.connection_type_bridges_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_tor_bridges", True)) + self.connection_type_bridges_radio_group = QtWidgets.QGroupBox(strings._("gui_settings_tor_bridges")) self.connection_type_bridges_radio_group.setLayout(connection_type_bridges_radio_group_layout) self.connection_type_bridges_radio_group.hide() # Test tor settings button - self.connection_type_test_button = QtWidgets.QPushButton(strings._('gui_settings_connection_type_test_button', True)) + self.connection_type_test_button = QtWidgets.QPushButton(strings._('gui_settings_connection_type_test_button')) self.connection_type_test_button.clicked.connect(self.test_tor_clicked) connection_type_test_button_layout = QtWidgets.QHBoxLayout() connection_type_test_button_layout.addWidget(self.connection_type_test_button) @@ -420,13 +420,13 @@ class SettingsDialog(QtWidgets.QDialog): connection_type_layout.addLayout(connection_type_test_button_layout) # Buttons - self.save_button = QtWidgets.QPushButton(strings._('gui_settings_button_save', True)) + self.save_button = QtWidgets.QPushButton(strings._('gui_settings_button_save')) self.save_button.clicked.connect(self.save_clicked) - self.cancel_button = QtWidgets.QPushButton(strings._('gui_settings_button_cancel', True)) + self.cancel_button = QtWidgets.QPushButton(strings._('gui_settings_button_cancel')) self.cancel_button.clicked.connect(self.cancel_clicked) version_label = QtWidgets.QLabel('OnionShare {0:s}'.format(self.common.version)) version_label.setStyleSheet(self.common.css['settings_version']) - self.help_button = QtWidgets.QPushButton(strings._('gui_settings_button_help', True)) + self.help_button = QtWidgets.QPushButton(strings._('gui_settings_button_help')) self.help_button.clicked.connect(self.help_clicked) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(version_label) @@ -623,7 +623,7 @@ class SettingsDialog(QtWidgets.QDialog): self.tor_bridges_use_custom_textbox_options.hide() # Alert the user about meek's costliness if it looks like they're turning it on if not self.old_settings.get('tor_bridges_use_meek_lite_azure'): - Alert(self.common, strings._('gui_settings_meek_lite_expensive_warning', True), QtWidgets.QMessageBox.Warning) + Alert(self.common, strings._('gui_settings_meek_lite_expensive_warning'), QtWidgets.QMessageBox.Warning) def tor_bridges_use_custom_radio_toggled(self, checked): """ @@ -736,7 +736,7 @@ class SettingsDialog(QtWidgets.QDialog): """ downloads_dir = self.downloads_dir_lineedit.text() selected_dir = QtWidgets.QFileDialog.getExistingDirectory(self, - strings._('gui_settings_downloads_label', True), downloads_dir) + strings._('gui_settings_downloads_label'), downloads_dir) if selected_dir: self.common.log('SettingsDialog', 'downloads_button_clicked', 'selected dir: {}'.format(selected_dir)) @@ -766,7 +766,7 @@ class SettingsDialog(QtWidgets.QDialog): onion.connect(custom_settings=settings, config=self.config, tor_status_update_func=tor_status_update_func) # If an exception hasn't been raised yet, the Tor settings work - Alert(self.common, strings._('settings_test_success', True).format(onion.tor_version, onion.supports_ephemeral, onion.supports_stealth, onion.supports_next_gen_onions)) + Alert(self.common, strings._('settings_test_success').format(onion.tor_version, onion.supports_ephemeral, onion.supports_stealth, onion.supports_next_gen_onions)) # Clean up onion.cleanup() @@ -802,19 +802,19 @@ class SettingsDialog(QtWidgets.QDialog): # Check for updates def update_available(update_url, installed_version, latest_version): - Alert(self.common, strings._("update_available", True).format(update_url, installed_version, latest_version)) + Alert(self.common, strings._("update_available").format(update_url, installed_version, latest_version)) close_forced_update_thread() def update_not_available(): - Alert(self.common, strings._('update_not_available', True)) + Alert(self.common, strings._('update_not_available')) close_forced_update_thread() def update_error(): - Alert(self.common, strings._('update_error_check_error', True), QtWidgets.QMessageBox.Warning) + Alert(self.common, strings._('update_error_check_error'), QtWidgets.QMessageBox.Warning) close_forced_update_thread() def update_invalid_version(latest_version): - Alert(self.common, strings._('update_error_invalid_latest_version', True).format(latest_version), QtWidgets.QMessageBox.Warning) + Alert(self.common, strings._('update_error_invalid_latest_version').format(latest_version), QtWidgets.QMessageBox.Warning) close_forced_update_thread() forced_update_thread = UpdateThread(self.common, self.onion, self.config, force=True) @@ -905,7 +905,7 @@ class SettingsDialog(QtWidgets.QDialog): """ self.common.log('SettingsDialog', 'cancel_clicked') if not self.local_only and not self.onion.is_authenticated(): - Alert(self.common, strings._('gui_tor_connection_canceled', True), QtWidgets.QMessageBox.Warning) + Alert(self.common, strings._('gui_tor_connection_canceled'), QtWidgets.QMessageBox.Warning) sys.exit() else: self.close() @@ -938,7 +938,7 @@ class SettingsDialog(QtWidgets.QDialog): if self.save_private_key_checkbox.isChecked(): # force the legacy mode on use_legacy_v2_onions = True - settings.set('save_private_key', True) + settings.set('save_private_key') settings.set('private_key', self.old_settings.get('private_key')) settings.set('slug', self.old_settings.get('slug')) settings.set('hidservauth_string', self.old_settings.get('hidservauth_string')) @@ -950,7 +950,7 @@ class SettingsDialog(QtWidgets.QDialog): settings.set('hidservauth_string', '') if use_legacy_v2_onions: - settings.set('use_legacy_v2_onions', True) + settings.set('use_legacy_v2_onions') else: settings.set('use_legacy_v2_onions', False) # If we are not using legacy mode, but we previously had persistence turned on, force it off! @@ -984,7 +984,7 @@ class SettingsDialog(QtWidgets.QDialog): settings.set('connection_type', 'socket_file') if self.autoupdate_checkbox.isChecked(): - settings.set('use_autoupdate', True) + settings.set('use_autoupdate') else: settings.set('use_autoupdate', False) @@ -1004,19 +1004,19 @@ class SettingsDialog(QtWidgets.QDialog): # Whether we use bridges if self.tor_bridges_no_bridges_radio.isChecked(): - settings.set('no_bridges', True) + settings.set('no_bridges') settings.set('tor_bridges_use_obfs4', False) settings.set('tor_bridges_use_meek_lite_azure', False) settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_obfs4_radio.isChecked(): settings.set('no_bridges', False) - settings.set('tor_bridges_use_obfs4', True) + settings.set('tor_bridges_use_obfs4') settings.set('tor_bridges_use_meek_lite_azure', False) settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_meek_lite_azure_radio.isChecked(): settings.set('no_bridges', False) settings.set('tor_bridges_use_obfs4', False) - settings.set('tor_bridges_use_meek_lite_azure', True) + settings.set('tor_bridges_use_meek_lite_azure') settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_custom_radio.isChecked(): settings.set('no_bridges', False) @@ -1047,8 +1047,8 @@ class SettingsDialog(QtWidgets.QDialog): new_bridges = ''.join(new_bridges) settings.set('tor_bridges_use_custom_bridges', new_bridges) else: - Alert(self.common, strings._('gui_settings_tor_bridges_invalid', True)) - settings.set('no_bridges', True) + Alert(self.common, strings._('gui_settings_tor_bridges_invalid')) + settings.set('no_bridges') return False return settings @@ -1071,11 +1071,11 @@ class SettingsDialog(QtWidgets.QDialog): dt = datetime.datetime.fromtimestamp(autoupdate_timestamp) last_checked = dt.strftime('%B %d, %Y %H:%M') else: - last_checked = strings._('gui_settings_autoupdate_timestamp_never', True) - self.autoupdate_timestamp.setText(strings._('gui_settings_autoupdate_timestamp', True).format(last_checked)) + last_checked = strings._('gui_settings_autoupdate_timestamp_never') + self.autoupdate_timestamp.setText(strings._('gui_settings_autoupdate_timestamp').format(last_checked)) def _tor_status_update(self, progress, summary): - self.tor_status.setText('{}
{}% {}'.format(strings._('connecting_to_tor', True), progress, summary)) + self.tor_status.setText('{}
{}% {}'.format(strings._('connecting_to_tor'), progress, summary)) self.qtapp.processEvents() if 'Done' in summary: self.tor_status.hide() diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/share_mode/__init__.py index 90fce49a..feb3b86b 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/share_mode/__init__.py @@ -118,7 +118,7 @@ class ShareMode(Mode): """ Return the string to put on the stop server button, if there's a shutdown timeout """ - return strings._('gui_share_stop_server_shutdown_timeout', True) + return strings._('gui_share_stop_server_shutdown_timeout') def timeout_finished_should_stop_server(self): """ @@ -127,11 +127,11 @@ class ShareMode(Mode): # If there were no attempts to download the share, or all downloads are done, we can stop if self.web.share_mode.download_count == 0 or self.web.done: self.server_status.stop_server() - self.server_status_label.setText(strings._('close_on_timeout', True)) + self.server_status_label.setText(strings._('close_on_timeout')) return True # A download is probably still running - hold off on stopping the share else: - self.server_status_label.setText(strings._('timeout_download_still_running', True)) + self.server_status_label.setText(strings._('timeout_download_still_running')) return False def start_server_custom(self): @@ -178,7 +178,7 @@ class ShareMode(Mode): # Warn about sending large files over Tor if self.web.share_mode.download_filesize >= 157286400: # 150mb - self.filesize_warning.setText(strings._("large_filesize", True)) + self.filesize_warning.setText(strings._("large_filesize")) self.filesize_warning.show() def start_server_error_custom(self): @@ -223,7 +223,7 @@ class ShareMode(Mode): """ Handle REQUEST_LOAD event. """ - self.system_tray.showMessage(strings._('systray_page_loaded_title', True), strings._('systray_download_page_loaded_message', True)) + self.system_tray.showMessage(strings._('systray_page_loaded_title'), strings._('systray_download_page_loaded_message')) def handle_request_started(self, event): """ @@ -237,7 +237,7 @@ class ShareMode(Mode): self.downloads_in_progress += 1 self.update_downloads_in_progress() - self.system_tray.showMessage(strings._('systray_download_started_title', True), strings._('systray_download_started_message', True)) + self.system_tray.showMessage(strings._('systray_download_started_title'), strings._('systray_download_started_message')) def handle_request_progress(self, event): """ @@ -247,7 +247,7 @@ class ShareMode(Mode): # Is the download complete? if event["data"]["bytes"] == self.web.share_mode.filesize: - self.system_tray.showMessage(strings._('systray_download_completed_title', True), strings._('systray_download_completed_message', True)) + self.system_tray.showMessage(strings._('systray_download_completed_title'), strings._('systray_download_completed_message')) # Update the total 'completed downloads' info self.downloads_completed += 1 @@ -260,7 +260,7 @@ class ShareMode(Mode): if self.common.settings.get('close_after_first_download'): self.server_status.stop_server() self.status_bar.clearMessage() - self.server_status_label.setText(strings._('closing_automatically', True)) + self.server_status_label.setText(strings._('closing_automatically')) else: if self.server_status.status == self.server_status.STATUS_STOPPED: self.downloads.cancel(event["data"]["id"]) @@ -276,7 +276,7 @@ class ShareMode(Mode): # Update the 'in progress downloads' info self.downloads_in_progress -= 1 self.update_downloads_in_progress() - self.system_tray.showMessage(strings._('systray_download_canceled_title', True), strings._('systray_download_canceled_message', True)) + self.system_tray.showMessage(strings._('systray_download_canceled_title'), strings._('systray_download_canceled_message')) def on_reload_settings(self): """ @@ -302,9 +302,9 @@ class ShareMode(Mode): total_size_readable = self.common.human_readable_filesize(total_size_bytes) if file_count > 1: - self.info_label.setText(strings._('gui_file_info', True).format(file_count, total_size_readable)) + self.info_label.setText(strings._('gui_file_info').format(file_count, total_size_readable)) else: - self.info_label.setText(strings._('gui_file_info_single', True).format(file_count, total_size_readable)) + self.info_label.setText(strings._('gui_file_info_single').format(file_count, total_size_readable)) else: self.primary_action.hide() @@ -332,7 +332,7 @@ class ShareMode(Mode): else: image = self.common.get_resource_path('images/share_completed.png') self.info_completed_downloads_count.setText(' {1:d}'.format(image, self.downloads_completed)) - self.info_completed_downloads_count.setToolTip(strings._('info_completed_downloads_tooltip', True).format(self.downloads_completed)) + self.info_completed_downloads_count.setToolTip(strings._('info_completed_downloads_tooltip').format(self.downloads_completed)) def update_downloads_in_progress(self): """ @@ -343,7 +343,7 @@ class ShareMode(Mode): else: image = self.common.get_resource_path('images/share_in_progress.png') self.info_in_progress_downloads_count.setText(' {1:d}'.format(image, self.downloads_in_progress)) - self.info_in_progress_downloads_count.setToolTip(strings._('info_in_progress_downloads_tooltip', True).format(self.downloads_in_progress)) + self.info_in_progress_downloads_count.setToolTip(strings._('info_in_progress_downloads_tooltip').format(self.downloads_in_progress)) @staticmethod def _compute_total_size(filenames): diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/share_mode/downloads.py index a34796f1..fe1e91b8 100644 --- a/onionshare_gui/share_mode/downloads.py +++ b/onionshare_gui/share_mode/downloads.py @@ -89,7 +89,7 @@ class Downloads(QtWidgets.QScrollArea): self.downloads = {} - self.setWindowTitle(strings._('gui_downloads', True)) + self.setWindowTitle(strings._('gui_downloads')) self.setWidgetResizable(True) self.setMinimumHeight(150) self.setMinimumWidth(350) @@ -98,10 +98,10 @@ class Downloads(QtWidgets.QScrollArea): self.vbar = self.verticalScrollBar() self.vbar.rangeChanged.connect(self.resizeScroll) - downloads_label = QtWidgets.QLabel(strings._('gui_downloads', True)) + downloads_label = QtWidgets.QLabel(strings._('gui_downloads')) downloads_label.setStyleSheet(self.common.css['downloads_uploads_label']) - self.no_downloads_label = QtWidgets.QLabel(strings._('gui_no_downloads', True)) - self.clear_history_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) + self.no_downloads_label = QtWidgets.QLabel(strings._('gui_no_downloads')) + self.clear_history_button = QtWidgets.QPushButton(strings._('gui_clear_history')) self.clear_history_button.clicked.connect(self.reset) self.clear_history_button.hide() diff --git a/onionshare_gui/share_mode/file_selection.py b/onionshare_gui/share_mode/file_selection.py index 628ad5ef..f6f54469 100644 --- a/onionshare_gui/share_mode/file_selection.py +++ b/onionshare_gui/share_mode/file_selection.py @@ -41,7 +41,7 @@ class DropHereLabel(QtWidgets.QLabel): if image: self.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/logo_transparent.png')))) else: - self.setText(strings._('gui_drag_and_drop', True)) + self.setText(strings._('gui_drag_and_drop')) self.setStyleSheet(self.common.css['share_file_selection_drop_here_label']) self.hide() @@ -65,7 +65,7 @@ class DropCountLabel(QtWidgets.QLabel): self.setAcceptDrops(True) self.setAlignment(QtCore.Qt.AlignCenter) - self.setText(strings._('gui_drag_and_drop', True)) + self.setText(strings._('gui_drag_and_drop')) self.setStyleSheet(self.common.css['share_file_selection_drop_count_label']) self.hide() @@ -216,7 +216,7 @@ class FileList(QtWidgets.QListWidget): if filename not in filenames: if not os.access(filename, os.R_OK): - Alert(self.common, strings._("not_a_readable_file", True).format(filename)) + Alert(self.common, strings._("not_a_readable_file").format(filename)) return fileinfo = QtCore.QFileInfo(filename) @@ -301,9 +301,9 @@ class FileSelection(QtWidgets.QVBoxLayout): self.file_list.files_updated.connect(self.update) # Buttons - self.add_button = QtWidgets.QPushButton(strings._('gui_add', True)) + self.add_button = QtWidgets.QPushButton(strings._('gui_add')) self.add_button.clicked.connect(self.add) - self.delete_button = QtWidgets.QPushButton(strings._('gui_delete', True)) + self.delete_button = QtWidgets.QPushButton(strings._('gui_delete')) self.delete_button.clicked.connect(self.delete) button_layout = QtWidgets.QHBoxLayout() button_layout.addStretch() @@ -340,7 +340,7 @@ class FileSelection(QtWidgets.QVBoxLayout): """ Add button clicked. """ - file_dialog = AddFileDialog(self.common, caption=strings._('gui_choose_items', True)) + file_dialog = AddFileDialog(self.common, caption=strings._('gui_choose_items')) if file_dialog.exec_() == QtWidgets.QDialog.Accepted: for filename in file_dialog.selectedFiles(): self.file_list.add_file(filename) diff --git a/onionshare_gui/tor_connection_dialog.py b/onionshare_gui/tor_connection_dialog.py index b3bd1fe5..2bcbf1a6 100644 --- a/onionshare_gui/tor_connection_dialog.py +++ b/onionshare_gui/tor_connection_dialog.py @@ -51,7 +51,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog): self.setFixedSize(400, 150) # Label - self.setLabelText(strings._('connecting_to_tor', True)) + self.setLabelText(strings._('connecting_to_tor')) # Progress bar ticks from 0 to 100 self.setRange(0, 100) @@ -81,7 +81,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog): def _tor_status_update(self, progress, summary): self.setValue(int(progress)) - self.setLabelText("{}
{}".format(strings._('connecting_to_tor', True), summary)) + self.setLabelText("{}
{}".format(strings._('connecting_to_tor'), summary)) def _connected_to_tor(self): self.common.log('TorConnectionDialog', '_connected_to_tor') @@ -104,7 +104,7 @@ class TorConnectionDialog(QtWidgets.QProgressDialog): def alert_and_open_settings(): # Display the exception in an alert box - Alert(self.common, "{}\n\n{}".format(msg, strings._('gui_tor_connection_error_settings', True)), QtWidgets.QMessageBox.Warning) + Alert(self.common, "{}\n\n{}".format(msg, strings._('gui_tor_connection_error_settings')), QtWidgets.QMessageBox.Warning) # Open settings self.open_settings.emit() From c7c3120a0ce2effcbeda78888b468842e784cb9b Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 18:19:25 -0700 Subject: [PATCH 040/142] Fix tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py tests --- tests_gui_local/commontests.py | 66 ++++++++++++++++--- ...re_receive_mode_upload_test_public_mode.py | 57 ++-------------- tests_gui_tor/commontests.py | 20 +++--- tests_gui_tor/conftest.py | 5 +- 4 files changed, 75 insertions(+), 73 deletions(-) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/commontests.py index de1ad9ab..d3f8a100 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/commontests.py @@ -3,11 +3,60 @@ import requests import socket import socks import zipfile +import json +import shutil 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 + class CommonTests(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() + + common = Common() + common.settings = Settings(common) + common.define_css() + strings.load_strings(common) + + # Get all of the settings in test_settings + test_settings['downloads_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) + settings_filename = '/tmp/testsettings.json' + open(settings_filename, 'w').write(json.dumps(test_settings)) + + gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], settings_filename, True) + return gui + + @staticmethod + def tear_down(): + try: + os.remove('/tmp/test.txt') + shutil.rmtree('/tmp/OnionShare') + except: + pass + def test_gui_loaded(self): '''Test that the GUI actually is shown''' self.assertTrue(self.gui.show) @@ -32,7 +81,7 @@ class CommonTests(object): self.assertFalse(self.gui.share_mode.info_widget.isVisible()) def test_info_widget_is_visible(self, mode): - '''Test that the info widget along top of screen is shown''' + '''Test that the info widget along top of screen is shown''' if mode == 'receive': self.assertTrue(self.gui.receive_mode.info_widget.isVisible()) if mode == 'share': @@ -69,9 +118,9 @@ class CommonTests(object): def test_server_status_indicator_says_starting(self, mode): '''Test that the Server Status indicator shows we are Starting''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working')) if mode == 'share': - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working')) def test_settings_button_is_hidden(self): '''Test that the settings button is hidden when the server starts''' @@ -123,9 +172,9 @@ class CommonTests(object): def test_server_status_indicator_says_started(self, mode): '''Test that the Server Status indicator shows we are started''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started')) if mode == 'share': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started')) def test_web_page(self, mode, string, public_mode): '''Test that the web page contains a string''' @@ -195,12 +244,12 @@ class CommonTests(object): def test_server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped')) if mode == 'share': if stay_open: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) + self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped')) else: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically', True)) + self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically')) # Auto-stop timer tests def test_set_timeout(self, mode, timeout): @@ -304,4 +353,3 @@ class CommonTests(object): def test_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()) - diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py index 30a290e7..7b1cfe79 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py @@ -8,6 +8,7 @@ import json from PyQt5 import QtWidgets from onionshare.common import Common +from onionshare.settings import Settings from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * @@ -18,65 +19,15 @@ class OnionShareGuiTest(unittest.TestCase): '''Test the OnionShare GUI''' @classmethod def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, True, 0) - - web = Web(common, False, True) - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", "public_mode": True, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" + "receive_allow_receiver_shutdown": True } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, True) + cls.gui = CommonTests.set_up(test_settings) @classmethod def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - os.remove('/tmp/OnionShare/test.txt') - os.remove('/tmp/OnionShare/test-2.txt') + CommonTests.tear_down() @pytest.mark.run(order=1) def test_gui_loaded(self): diff --git a/tests_gui_tor/commontests.py b/tests_gui_tor/commontests.py index a0d9bf5f..cb23cca9 100644 --- a/tests_gui_tor/commontests.py +++ b/tests_gui_tor/commontests.py @@ -32,7 +32,7 @@ class CommonTests(object): self.assertFalse(self.gui.share_mode.info_widget.isVisible()) def test_info_widget_is_visible(self, mode): - '''Test that the info widget along top of screen is shown''' + '''Test that the info widget along top of screen is shown''' if mode == 'receive': self.assertTrue(self.gui.receive_mode.info_widget.isVisible()) if mode == 'share': @@ -69,9 +69,9 @@ class CommonTests(object): def test_server_status_indicator_says_starting(self, mode): '''Test that the Server Status indicator shows we are Starting''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working')) if mode == 'share': - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working')) def test_settings_button_is_hidden(self): '''Test that the settings button is hidden when the server starts''' @@ -126,9 +126,9 @@ class CommonTests(object): def test_server_status_indicator_says_started(self, mode): '''Test that the Server Status indicator shows we are started''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started')) if mode == 'share': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started')) def test_web_page(self, mode, string, public_mode): '''Test that the web page contains a string''' @@ -201,12 +201,12 @@ class CommonTests(object): def test_server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped')) if mode == 'share': if stay_open: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) + self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped')) else: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically', True)) + self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically')) def test_cancel_the_share(self, mode): '''Test that we can cancel this share before it's started up ''' @@ -354,6 +354,6 @@ class CommonTests(object): self.gui.app.onion.cleanup(stop_tor=True) QtTest.QTest.qWait(2500) if mode == 'share': - self.assertTrue(self.gui.share_mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost', True)) + self.assertTrue(self.gui.share_mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost')) if mode == 'receive': - self.assertTrue(self.gui.receive_mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost', True)) + self.assertTrue(self.gui.receive_mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost')) diff --git a/tests_gui_tor/conftest.py b/tests_gui_tor/conftest.py index 8ac7efb8..23079e8d 100644 --- a/tests_gui_tor/conftest.py +++ b/tests_gui_tor/conftest.py @@ -151,7 +151,10 @@ def time_strftime(monkeypatch): @pytest.fixture def common_obj(): - return common.Common() + _common = common.Common() + _common.settings = settings.Settings(_common) + strings.load_strings(_common) + return _common @pytest.fixture def settings_obj(sys_onionshare_dev_mode, platform_linux): From acd2fcdf61e08c1410e572b9aa8efffb9b9ce71a Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 18:32:18 -0700 Subject: [PATCH 041/142] Fix the rest of the local GUI tests --- .../onionshare_receive_mode_upload_test.py | 57 +------------------ ...re_receive_mode_upload_test_public_mode.py | 1 - .../onionshare_share_mode_download_test.py | 55 +----------------- ...re_share_mode_download_test_public_mode.py | 56 +----------------- ...hare_share_mode_download_test_stay_open.py | 55 +----------------- .../onionshare_slug_persistent_test.py | 56 +----------------- tests_gui_local/onionshare_timer_test.py | 55 +----------------- 7 files changed, 18 insertions(+), 317 deletions(-) diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index 2aa2ed94..cf439950 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -15,68 +15,17 @@ from onionshare_gui import * from .commontests import CommonTests class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' @classmethod def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, True, 0) - - web = Web(common, False, True) - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" + "receive_allow_receiver_shutdown": True } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, True) + cls.gui = CommonTests.set_up(test_settings) @classmethod def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - os.remove('/tmp/OnionShare/test.txt') - os.remove('/tmp/OnionShare/test-2.txt') + CommonTests.tear_down() @pytest.mark.run(order=1) def test_gui_loaded(self): diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py index 7b1cfe79..f89da51a 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py @@ -16,7 +16,6 @@ from onionshare_gui import * from .commontests import CommonTests class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' @classmethod def setUpClass(cls): test_settings = { diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index c546fb61..1800150f 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -15,66 +15,17 @@ from onionshare_gui import * from .commontests import CommonTests class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' @classmethod def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, True, 0) - - web = Web(common, False, True) - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" + "close_after_first_download": True } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, True) + cls.gui = CommonTests.set_up(test_settings) @classmethod def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') + CommonTests.tear_down() @pytest.mark.run(order=1) def test_gui_loaded(self): diff --git a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py index 764b5885..37c593f9 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py +++ b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py @@ -15,66 +15,16 @@ from onionshare_gui import * from .commontests import CommonTests class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' @classmethod def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, True, 0) - - web = Web(common, False, True) - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": True, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" + "public_mode": True } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, True) + cls.gui = CommonTests.set_up(test_settings) @classmethod def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') + CommonTests.tear_down() @pytest.mark.run(order=1) def test_gui_loaded(self): diff --git a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py index b92ff097..57ea8424 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py +++ b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py @@ -15,66 +15,17 @@ from onionshare_gui import * from .commontests import CommonTests class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' @classmethod def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, True, 0) - - web = Web(common, False, True) - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": False, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", "public_mode": True, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" + "close_after_first_download": False } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, True) + cls.gui = CommonTests.set_up(test_settings) @classmethod def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') + CommonTests.tear_down() @pytest.mark.run(order=1) def test_gui_loaded(self): diff --git a/tests_gui_local/onionshare_slug_persistent_test.py b/tests_gui_local/onionshare_slug_persistent_test.py index 1e5614dc..54652eeb 100644 --- a/tests_gui_local/onionshare_slug_persistent_test.py +++ b/tests_gui_local/onionshare_slug_persistent_test.py @@ -15,68 +15,18 @@ from onionshare_gui import * from .commontests import CommonTests class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - slug = '' - @classmethod def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, True, 0) - - web = Web(common, False, True) - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": True, - "shutdown_timeout": False, "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" + "save_private_key": True } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, True) + cls.gui = CommonTests.set_up(test_settings) @classmethod def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') + CommonTests.tear_down() @pytest.mark.run(order=1) def test_gui_loaded(self): diff --git a/tests_gui_local/onionshare_timer_test.py b/tests_gui_local/onionshare_timer_test.py index 1a5134e2..26eb4560 100644 --- a/tests_gui_local/onionshare_timer_test.py +++ b/tests_gui_local/onionshare_timer_test.py @@ -15,66 +15,17 @@ from onionshare_gui import * from .commontests import CommonTests class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' @classmethod def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, True, 0) - - web = Web(common, False, True) - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": True, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" + "shutdown_timeout": True } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, True) + cls.gui = CommonTests.set_up(test_settings) @classmethod def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') + CommonTests.tear_down() @pytest.mark.run(order=1) def test_gui_loaded(self): From 898276e6b5ebbc766d3f79507173c417f7645619 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 30 Sep 2018 18:40:47 -0700 Subject: [PATCH 042/142] Oops, import strings into tor GUI tests --- tests_gui_tor/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests_gui_tor/conftest.py b/tests_gui_tor/conftest.py index 23079e8d..3ae6fd52 100644 --- a/tests_gui_tor/conftest.py +++ b/tests_gui_tor/conftest.py @@ -8,7 +8,7 @@ import tempfile import pytest -from onionshare import common, web, settings +from onionshare import common, web, settings, strings @pytest.fixture def temp_dir_1024(): From a503da526486a5a4956152ac814306636a6fadbd Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 1 Oct 2018 12:53:10 +1000 Subject: [PATCH 043/142] Explicitly set true/false values for settings that need it --- onionshare_gui/settings_dialog.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index b9e0453a..794bd79c 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -938,7 +938,7 @@ class SettingsDialog(QtWidgets.QDialog): if self.save_private_key_checkbox.isChecked(): # force the legacy mode on use_legacy_v2_onions = True - settings.set('save_private_key') + settings.set('save_private_key', True) settings.set('private_key', self.old_settings.get('private_key')) settings.set('slug', self.old_settings.get('slug')) settings.set('hidservauth_string', self.old_settings.get('hidservauth_string')) @@ -950,7 +950,7 @@ class SettingsDialog(QtWidgets.QDialog): settings.set('hidservauth_string', '') if use_legacy_v2_onions: - settings.set('use_legacy_v2_onions') + settings.set('use_legacy_v2_onions', True) else: settings.set('use_legacy_v2_onions', False) # If we are not using legacy mode, but we previously had persistence turned on, force it off! @@ -984,7 +984,7 @@ class SettingsDialog(QtWidgets.QDialog): settings.set('connection_type', 'socket_file') if self.autoupdate_checkbox.isChecked(): - settings.set('use_autoupdate') + settings.set('use_autoupdate', True) else: settings.set('use_autoupdate', False) @@ -1004,19 +1004,19 @@ class SettingsDialog(QtWidgets.QDialog): # Whether we use bridges if self.tor_bridges_no_bridges_radio.isChecked(): - settings.set('no_bridges') + settings.set('no_bridges', True) settings.set('tor_bridges_use_obfs4', False) settings.set('tor_bridges_use_meek_lite_azure', False) settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_obfs4_radio.isChecked(): settings.set('no_bridges', False) - settings.set('tor_bridges_use_obfs4') + settings.set('tor_bridges_use_obfs4', True) settings.set('tor_bridges_use_meek_lite_azure', False) settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_meek_lite_azure_radio.isChecked(): settings.set('no_bridges', False) settings.set('tor_bridges_use_obfs4', False) - settings.set('tor_bridges_use_meek_lite_azure') + settings.set('tor_bridges_use_meek_lite_azure', True) settings.set('tor_bridges_use_custom_bridges', '') if self.tor_bridges_use_custom_radio.isChecked(): settings.set('no_bridges', False) @@ -1048,7 +1048,7 @@ class SettingsDialog(QtWidgets.QDialog): settings.set('tor_bridges_use_custom_bridges', new_bridges) else: Alert(self.common, strings._('gui_settings_tor_bridges_invalid')) - settings.set('no_bridges') + settings.set('no_bridges', True) return False return settings From e6b823f4bec2cebbd99169f3707cfaa6dbde7f6b Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 1 Oct 2018 12:53:23 +1000 Subject: [PATCH 044/142] Add French translation for restarting OnionShare to see change in language take effect --- share/locale/fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/locale/fr.json b/share/locale/fr.json index 967e456e..ee206662 100644 --- a/share/locale/fr.json +++ b/share/locale/fr.json @@ -29,5 +29,6 @@ "gui_please_wait": "Attendez-vous...", "gui_quit_warning_quit": "Quitter", "gui_quit_warning_dont_quit": "Ne quitter pas", - "gui_settings_autoupdate_timestamp_never": "Jamais" + "gui_settings_autoupdate_timestamp_never": "Jamais", + "gui_settings_language_changed_notice": "Redémarrez OnionShare pour que votre changement de langue prenne effet" } From a700f8627d5d13f3eb03a1fc1cd780710d9cf9b1 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 1 Oct 2018 13:32:09 +1000 Subject: [PATCH 045/142] Move Alert dialog about restart into the conditional that fires only if locale was changed --- onionshare_gui/settings_dialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 794bd79c..5a81282a 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -850,7 +850,7 @@ class SettingsDialog(QtWidgets.QDialog): notice = strings.translations[new_locale]['gui_settings_language_changed_notice'] else: notice = strings._('gui_settings_language_changed_notice') - Alert(self.common, notice, QtWidgets.QMessageBox.Information) + Alert(self.common, notice, QtWidgets.QMessageBox.Information) # Save the new settings settings.save() From 1e3b32ebbb7d21ae32bfa59f7422fcad1beca46e Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 1 Oct 2018 15:32:53 +1000 Subject: [PATCH 046/142] Load default settings before parsing for any alternate config. Reload strings if an alternate config was passed in after --- onionshare/__init__.py | 10 ++++++++-- onionshare_gui/__init__.py | 10 +++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/onionshare/__init__.py b/onionshare/__init__.py index 2f0ef14c..069559c5 100644 --- a/onionshare/__init__.py +++ b/onionshare/__init__.py @@ -33,8 +33,12 @@ def main(cwd=None): """ common = Common() - # Load settings right away, in order to get locale setting for strings - common.load_settings(config) + # Load the default settings and strings early, for the sake of being able to parse options. + # These won't be in the user's chosen locale necessarily, but we need to parse them + # early in order to even display the option to pass alternate settings (which might + # contain a preferred locale). + # If an alternate --config is passed, we'll reload strings later. + common.load_settings() strings.load_strings(common) # Display OnionShare banner @@ -95,6 +99,8 @@ def main(cwd=None): # Re-load settings, if a custom config was passed in if config: common.load_settings(config) + # Re-load the strings, in case the provided config has changed locale + strings.load_strings(common) # Debug mode? common.debug = debug diff --git a/onionshare_gui/__init__.py b/onionshare_gui/__init__.py index b5520071..675bb52d 100644 --- a/onionshare_gui/__init__.py +++ b/onionshare_gui/__init__.py @@ -59,7 +59,11 @@ def main(): common = Common() common.define_css() - # Load settings right away, in order to get locale setting for strings + # Load the default settings and strings early, for the sake of being able to parse options. + # These won't be in the user's chosen locale necessarily, but we need to parse them + # early in order to even display the option to pass alternate settings (which might + # contain a preferred locale). + # If an alternate --config is passed, we'll reload strings later. common.load_settings() strings.load_strings(common) @@ -88,6 +92,10 @@ def main(): filenames[i] = os.path.abspath(filenames[i]) config = args.config + if config: + # Re-load the strings, in case the provided config has changed locale + common.load_settings(config) + strings.load_strings(common) local_only = bool(args.local_only) debug = bool(args.debug) From 62718d1c8b25aab49d20076e2546de26463a7ced Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 14:48:15 -0700 Subject: [PATCH 047/142] Move Mode module into its own folder --- onionshare_gui/{mode.py => mode/__init__.py} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename onionshare_gui/{mode.py => mode/__init__.py} (99%) diff --git a/onionshare_gui/mode.py b/onionshare_gui/mode/__init__.py similarity index 99% rename from onionshare_gui/mode.py rename to onionshare_gui/mode/__init__.py index 1a961149..cfbb235b 100644 --- a/onionshare_gui/mode.py +++ b/onionshare_gui/mode/__init__.py @@ -22,9 +22,9 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.common import ShutdownTimer -from .server_status import ServerStatus -from .threads import OnionThread -from .widgets import Alert +from ..server_status import ServerStatus +from ..threads import OnionThread +from ..widgets import Alert class Mode(QtWidgets.QWidget): """ From b0b5b6c79e524c4183fe50a2c919325a8d0b410f Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 14:54:51 -0700 Subject: [PATCH 048/142] Move ShareMode and ReceiveMode into Mode module --- onionshare_gui/{ => mode}/receive_mode/__init__.py | 2 +- onionshare_gui/{ => mode}/receive_mode/info.py | 0 onionshare_gui/{ => mode}/receive_mode/uploads.py | 2 +- onionshare_gui/{ => mode}/share_mode/__init__.py | 4 ++-- onionshare_gui/{ => mode}/share_mode/downloads.py | 0 onionshare_gui/{ => mode}/share_mode/file_selection.py | 2 +- onionshare_gui/{ => mode}/share_mode/info.py | 0 onionshare_gui/{ => mode}/share_mode/threads.py | 0 onionshare_gui/onionshare_gui.py | 4 ++-- setup.py | 5 +++-- 10 files changed, 10 insertions(+), 9 deletions(-) rename onionshare_gui/{ => mode}/receive_mode/__init__.py (99%) rename onionshare_gui/{ => mode}/receive_mode/info.py (100%) rename onionshare_gui/{ => mode}/receive_mode/uploads.py (99%) rename onionshare_gui/{ => mode}/share_mode/__init__.py (99%) rename onionshare_gui/{ => mode}/share_mode/downloads.py (100%) rename onionshare_gui/{ => mode}/share_mode/file_selection.py (99%) rename onionshare_gui/{ => mode}/share_mode/info.py (100%) rename onionshare_gui/{ => mode}/share_mode/threads.py (100%) diff --git a/onionshare_gui/receive_mode/__init__.py b/onionshare_gui/mode/receive_mode/__init__.py similarity index 99% rename from onionshare_gui/receive_mode/__init__.py rename to onionshare_gui/mode/receive_mode/__init__.py index 6430382b..96c76dbf 100644 --- a/onionshare_gui/receive_mode/__init__.py +++ b/onionshare_gui/mode/receive_mode/__init__.py @@ -24,7 +24,7 @@ from onionshare.web import Web from .uploads import Uploads from .info import ReceiveModeInfo -from ..mode import Mode +from .. import Mode class ReceiveMode(Mode): """ diff --git a/onionshare_gui/receive_mode/info.py b/onionshare_gui/mode/receive_mode/info.py similarity index 100% rename from onionshare_gui/receive_mode/info.py rename to onionshare_gui/mode/receive_mode/info.py diff --git a/onionshare_gui/receive_mode/uploads.py b/onionshare_gui/mode/receive_mode/uploads.py similarity index 99% rename from onionshare_gui/receive_mode/uploads.py rename to onionshare_gui/mode/receive_mode/uploads.py index f08b35cc..c445be47 100644 --- a/onionshare_gui/receive_mode/uploads.py +++ b/onionshare_gui/mode/receive_mode/uploads.py @@ -24,7 +24,7 @@ from datetime import datetime from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings -from ..widgets import Alert +from ...widgets import Alert class File(QtWidgets.QWidget): diff --git a/onionshare_gui/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py similarity index 99% rename from onionshare_gui/share_mode/__init__.py rename to onionshare_gui/mode/share_mode/__init__.py index c44e8beb..c301037b 100644 --- a/onionshare_gui/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -29,8 +29,8 @@ from .file_selection import FileSelection from .downloads import Downloads from .threads import CompressThread from .info import ShareModeInfo -from ..mode import Mode -from ..widgets import Alert +from .. import Mode +from ...widgets import Alert class ShareMode(Mode): """ diff --git a/onionshare_gui/share_mode/downloads.py b/onionshare_gui/mode/share_mode/downloads.py similarity index 100% rename from onionshare_gui/share_mode/downloads.py rename to onionshare_gui/mode/share_mode/downloads.py diff --git a/onionshare_gui/share_mode/file_selection.py b/onionshare_gui/mode/share_mode/file_selection.py similarity index 99% rename from onionshare_gui/share_mode/file_selection.py rename to onionshare_gui/mode/share_mode/file_selection.py index 628ad5ef..d59df234 100644 --- a/onionshare_gui/share_mode/file_selection.py +++ b/onionshare_gui/mode/share_mode/file_selection.py @@ -22,7 +22,7 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings -from ..widgets import Alert, AddFileDialog +from ...widgets import Alert, AddFileDialog class DropHereLabel(QtWidgets.QLabel): """ diff --git a/onionshare_gui/share_mode/info.py b/onionshare_gui/mode/share_mode/info.py similarity index 100% rename from onionshare_gui/share_mode/info.py rename to onionshare_gui/mode/share_mode/info.py diff --git a/onionshare_gui/share_mode/threads.py b/onionshare_gui/mode/share_mode/threads.py similarity index 100% rename from onionshare_gui/share_mode/threads.py rename to onionshare_gui/mode/share_mode/threads.py diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index ced53ede..6a7eb63a 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -23,8 +23,8 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.web import Web -from .share_mode import ShareMode -from .receive_mode import ReceiveMode +from .mode.share_mode import ShareMode +from .mode.receive_mode import ReceiveMode from .tor_connection_dialog import TorConnectionDialog from .settings_dialog import SettingsDialog diff --git a/setup.py b/setup.py index 94213f7c..86b71f82 100644 --- a/setup.py +++ b/setup.py @@ -69,8 +69,9 @@ setup( 'onionshare', 'onionshare.web', 'onionshare_gui', - 'onionshare_gui.share_mode', - 'onionshare_gui.receive_mode' + 'onionshare_gui.mode', + 'onionshare_gui.mode.share_mode', + 'onionshare_gui.mode.receive_mode' ], include_package_data=True, scripts=['install/scripts/onionshare', 'install/scripts/onionshare-gui'], From cedb8f53c0e1617a80647f3f3d0bf585cb12b2f1 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 15:20:22 -0700 Subject: [PATCH 049/142] In ShareMode, remove the ShareModeInfo widget and replace with a customized ToggleHistory widget --- onionshare_gui/mode/share_mode/__init__.py | 54 ++++++++----- onionshare_gui/mode/toggle_history.py | 88 ++++++++++++++++++++++ 2 files changed, 124 insertions(+), 18 deletions(-) create mode 100644 onionshare_gui/mode/toggle_history.py diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py index c301037b..f7ba2760 100644 --- a/onionshare_gui/mode/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -28,8 +28,9 @@ from onionshare.web import Web from .file_selection import FileSelection from .downloads import Downloads from .threads import CompressThread -from .info import ShareModeInfo +#from .info import ShareModeInfo from .. import Mode +from ..toggle_history import ToggleHistory from ...widgets import Alert class ShareMode(Mode): @@ -78,7 +79,24 @@ class ShareMode(Mode): self.downloads_completed = 0 # Information about share, and show downloads button - self.info = ShareModeInfo(self.common, self) + #self.info = ShareModeInfo(self.common, self) + + # Info label + self.info_label = QtWidgets.QLabel() + self.info_label.hide() + + # Toggle history + self.toggle_history = ToggleHistory( + self.common, self, self.downloads, + QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')), + QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) + ) + + # Top bar + top_bar_layout = QtWidgets.QHBoxLayout() + top_bar_layout.addWidget(self.info_label) + top_bar_layout.addStretch() + top_bar_layout.addWidget(self.toggle_history) # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) @@ -90,7 +108,7 @@ class ShareMode(Mode): # Main layout self.main_layout = QtWidgets.QVBoxLayout() - self.main_layout.addWidget(self.info) + self.main_layout.addLayout(top_bar_layout) self.main_layout.addLayout(self.file_selection) self.main_layout.addWidget(self.primary_action) self.main_layout.addWidget(self.min_width_widget) @@ -191,7 +209,7 @@ class ShareMode(Mode): self.filesize_warning.hide() self.downloads_in_progress = 0 self.downloads_completed = 0 - self.info.update_downloads_in_progress() + #self.info.update_downloads_in_progress() self.file_selection.file_list.adjustSize() def cancel_server_custom(self): @@ -207,7 +225,7 @@ class ShareMode(Mode): Connection to Tor broke. """ self.primary_action.hide() - self.info.show_less() + self.info_label.hide() def handle_request_load(self, event): """ @@ -224,9 +242,9 @@ class ShareMode(Mode): else: filesize = self.web.share_mode.download_filesize self.downloads.add(event["data"]["id"], filesize) - self.info.update_indicator(True) + self.toggle_history.update_indicator(True) self.downloads_in_progress += 1 - self.info.update_downloads_in_progress() + #self.info.update_downloads_in_progress() self.system_tray.showMessage(strings._('systray_download_started_title', True), strings._('systray_download_started_message', True)) @@ -242,10 +260,10 @@ class ShareMode(Mode): # Update the total 'completed downloads' info self.downloads_completed += 1 - self.info.update_downloads_completed() + #self.info.update_downloads_completed() # Update the 'in progress downloads' info self.downloads_in_progress -= 1 - self.info.update_downloads_in_progress() + #self.info.update_downloads_in_progress() # Close on finish? if self.common.settings.get('close_after_first_download'): @@ -256,7 +274,7 @@ class ShareMode(Mode): if self.server_status.status == self.server_status.STATUS_STOPPED: self.downloads.cancel(event["data"]["id"]) self.downloads_in_progress = 0 - self.info.update_downloads_in_progress() + #self.info.update_downloads_in_progress() def handle_request_canceled(self, event): """ @@ -266,7 +284,7 @@ class ShareMode(Mode): # Update the 'in progress downloads' info self.downloads_in_progress -= 1 - self.info.update_downloads_in_progress() + #self.info.update_downloads_in_progress() self.system_tray.showMessage(strings._('systray_download_canceled_title', True), strings._('systray_download_canceled_message', True)) def on_reload_settings(self): @@ -276,7 +294,7 @@ class ShareMode(Mode): """ if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() - self.info.show_more() + self.info_label.show() def update_primary_action(self): self.common.log('ShareMode', 'update_primary_action') @@ -285,7 +303,7 @@ class ShareMode(Mode): file_count = self.file_selection.file_list.count() if file_count > 0: self.primary_action.show() - self.info.show_more() + self.info_label.show() # Update the file count in the info label total_size_bytes = 0 @@ -295,13 +313,13 @@ class ShareMode(Mode): total_size_readable = self.common.human_readable_filesize(total_size_bytes) if file_count > 1: - self.info.update_label(strings._('gui_file_info', True).format(file_count, total_size_readable)) + self.info_label.setText(strings._('gui_file_info', True).format(file_count, total_size_readable)) else: - self.info.update_label(strings._('gui_file_info_single', True).format(file_count, total_size_readable)) + self.info_label.setText(strings._('gui_file_info_single', True).format(file_count, total_size_readable)) else: self.primary_action.hide() - self.info.show_less() + self.info_label.hide() # Resize window self.resize_window() @@ -312,8 +330,8 @@ class ShareMode(Mode): """ self.downloads_completed = 0 self.downloads_in_progress = 0 - self.info.update_downloads_completed() - self.info.update_downloads_in_progress() + #self.info.update_downloads_completed() + #self.info.update_downloads_in_progress() self.downloads.reset() def resize_window(self): diff --git a/onionshare_gui/mode/toggle_history.py b/onionshare_gui/mode/toggle_history.py new file mode 100644 index 00000000..81ecde86 --- /dev/null +++ b/onionshare_gui/mode/toggle_history.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2018 Micah Lee + +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 . +""" +from PyQt5 import QtCore, QtWidgets, QtGui + +from onionshare import strings + + +class ToggleHistory(QtWidgets.QPushButton): + """ + Widget for toggling download/upload history on or off, as well as keeping track + of the indicator counter + """ + def __init__(self, common, current_mode, history_widget, icon, selected_icon): + super(ToggleHistory, self).__init__() + self.common = common + self.current_mode = current_mode + self.history_widget = history_widget + self.icon = icon + self.selected_icon = selected_icon + + # Toggle button + self.setDefault(False) + self.setFixedWidth(35) + self.setFixedHeight(30) + self.setFlat(True) + self.setIcon(icon) + self.clicked.connect(self.toggle_clicked) + + # Keep track of indicator + self.indicator_count = 0 + self.indicator_label = QtWidgets.QLabel(parent=self) + self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) + self.update_indicator() + + def update_indicator(self, increment=False): + """ + Update the display of the indicator count. If increment is True, then + only increment the counter if Downloads is hidden. + """ + if increment and not self.history_widget.isVisible(): + self.indicator_count += 1 + + self.indicator_label.setText("{}".format(self.indicator_count)) + + if self.indicator_count == 0: + self.indicator_label.hide() + else: + size = self.indicator_label.sizeHint() + self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) + self.indicator_label.show() + + def toggle_clicked(self): + """ + Toggle showing and hiding the history widget + """ + self.common.log('ToggleHistory', 'toggle_clicked') + + if self.history_widget.isVisible(): + self.history_widget.hide() + self.setIcon(self.icon) + self.setFlat(True) + else: + self.history_widget.show() + self.setIcon(self.selected_icon) + self.setFlat(False) + + # Reset the indicator count + self.indicator_count = 0 + self.update_indicator() + + self.current_mode.resize_window() From 63b095086b20749a57d2c62e918c245c1c5b1b92 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 17:35:15 -0700 Subject: [PATCH 050/142] Make ShareMode just use a History object directly, instead of defining its own Downloads class --- onionshare_gui/mode/history.py | 328 ++++++++++++++++++++ onionshare_gui/mode/share_mode/__init__.py | 34 +- onionshare_gui/mode/share_mode/downloads.py | 248 --------------- onionshare_gui/mode/toggle_history.py | 88 ------ 4 files changed, 348 insertions(+), 350 deletions(-) create mode 100644 onionshare_gui/mode/history.py delete mode 100644 onionshare_gui/mode/share_mode/downloads.py delete mode 100644 onionshare_gui/mode/toggle_history.py diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py new file mode 100644 index 00000000..31b4a646 --- /dev/null +++ b/onionshare_gui/mode/history.py @@ -0,0 +1,328 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2018 Micah Lee + +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 . +""" +import time +from PyQt5 import QtCore, QtWidgets, QtGui + +from onionshare import strings + + +class HistoryItem(QtWidgets.QWidget): + """ + The base history item + """ + def __init__(self): + super(HistoryItem, self).__init__() + + def update(self): + pass + + def cancel(self): + pass + + +class DownloadHistoryItem(HistoryItem): + """ + Download history item, for share mode + """ + def __init__(self, common, id, total_bytes): + super(DownloadHistoryItem, self).__init__() + self.common = common + + self.id = id + self.started = time.time() + self.total_bytes = total_bytes + self.downloaded_bytes = 0 + + self.setStyleSheet('QWidget { border: 1px solid red; }') + + # Progress bar + self.progress_bar = QtWidgets.QProgressBar() + self.progress_bar.setTextVisible(True) + self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) + self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) + self.progress_bar.setMinimum(0) + self.progress_bar.setMaximum(total_bytes) + self.progress_bar.setValue(0) + self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar']) + self.progress_bar.total_bytes = total_bytes + + # Layout + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.progress_bar) + self.setLayout(layout) + + # Start at 0 + self.update(0) + + def update(self, downloaded_bytes): + self.downloaded_bytes = downloaded_bytes + + self.progress_bar.setValue(downloaded_bytes) + if downloaded_bytes == self.progress_bar.total_bytes: + pb_fmt = strings._('gui_download_upload_progress_complete').format( + self.common.format_seconds(time.time() - self.started)) + else: + elapsed = time.time() - self.started + if elapsed < 10: + # Wait a couple of seconds for the download rate to stabilize. + # This prevents a "Windows copy dialog"-esque experience at + # the beginning of the download. + pb_fmt = strings._('gui_download_upload_progress_starting').format( + self.common.human_readable_filesize(downloaded_bytes)) + else: + pb_fmt = strings._('gui_download_upload_progress_eta').format( + self.common.human_readable_filesize(downloaded_bytes), + self.estimated_time_remaining) + + self.progress_bar.setFormat(pb_fmt) + + def cancel(self): + self.progress_bar.setFormat(strings._('gui_canceled')) + + @property + def estimated_time_remaining(self): + return self.common.estimated_time_remaining(self.downloaded_bytes, + self.total_bytes, + self.started) + + +class HistoryItemList(QtWidgets.QScrollArea): + """ + List of items + """ + def __init__(self, common): + super(HistoryItemList, self).__init__() + self.common = common + + self.items = {} + + # The layout that holds all of the items + self.items_layout = QtWidgets.QVBoxLayout() + self.items_layout.setContentsMargins(0, 0, 0, 0) + self.items_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) + + # Wrapper layout that also contains a stretch + wrapper_layout = QtWidgets.QVBoxLayout() + wrapper_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) + wrapper_layout.addLayout(self.items_layout) + wrapper_layout.addStretch() + + # The internal widget of the scroll area + widget = QtWidgets.QWidget() + widget.setLayout(wrapper_layout) + self.setWidget(widget) + self.setWidgetResizable(True) + + # Other scroll area settings + self.setBackgroundRole(QtGui.QPalette.Light) + self.verticalScrollBar().rangeChanged.connect(self.resizeScroll) + + def resizeScroll(self, minimum, maximum): + """ + Scroll to the bottom of the window when the range changes. + """ + self.verticalScrollBar().setValue(maximum) + + def add(self, id, item): + """ + Add a new item. Override this method. + """ + self.items[id] = item + self.items_layout.addWidget(item) + + def update(self, id, data): + """ + Update an item. Override this method. + """ + self.items[id].update(data) + + def cancel(self, id): + """ + Cancel an item. Override this method. + """ + self.items[id].cancel() + + def reset(self): + """ + Reset all items, emptying the list. Override this method. + """ + for item in self.items.values(): + self.items_layout.removeWidget(item) + self.items = {} + + +class History(QtWidgets.QWidget): + """ + A history of what's happened so far in this mode. This contains an internal + object full of a scrollable list of items. + """ + def __init__(self, common, empty_image, empty_text, header_text): + super(History, self).__init__() + self.common = common + + self.setMinimumWidth(350) + + # When there are no items + self.empty_image = QtWidgets.QLabel() + self.empty_image.setAlignment(QtCore.Qt.AlignCenter) + self.empty_image.setPixmap(empty_image) + self.empty_text = QtWidgets.QLabel(empty_text) + self.empty_text.setAlignment(QtCore.Qt.AlignCenter) + self.empty_text.setStyleSheet(self.common.css['downloads_uploads_empty_text']) + empty_layout = QtWidgets.QVBoxLayout() + empty_layout.addStretch() + empty_layout.addWidget(self.empty_image) + empty_layout.addWidget(self.empty_text) + empty_layout.addStretch() + self.empty = QtWidgets.QWidget() + self.empty.setStyleSheet(self.common.css['downloads_uploads_empty']) + self.empty.setLayout(empty_layout) + + # Header + self.header_label = QtWidgets.QLabel(header_text) + self.header_label.setStyleSheet(self.common.css['downloads_uploads_label']) + clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) + clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) + clear_button.setFlat(True) + clear_button.clicked.connect(self.reset) + header_layout = QtWidgets.QHBoxLayout() + header_layout.addWidget(self.header_label) + header_layout.addStretch() + header_layout.addWidget(clear_button) + + # When there are items + self.item_list = HistoryItemList(self.common) + self.not_empty_layout = QtWidgets.QVBoxLayout() + self.not_empty_layout.addLayout(header_layout) + self.not_empty_layout.addWidget(self.item_list) + self.not_empty = QtWidgets.QWidget() + self.not_empty.setLayout(self.not_empty_layout) + + # Layout + layout = QtWidgets.QVBoxLayout() + layout.setContentsMargins(0, 0, 0, 0) + layout.addWidget(self.empty) + layout.addWidget(self.not_empty) + self.setLayout(layout) + + # Reset once at the beginning + self.reset() + + def add(self, id, item): + """ + Add a new item. + """ + self.common.log('History', 'add', 'id: {}, item: {}'.format(id, item)) + + # Hide empty, show not empty + self.empty.hide() + self.not_empty.show() + + # Add it to the list + self.item_list.add(id, item) + + + def update(self, id, data): + """ + Update an item. + """ + self.item_list.update(id, data) + + def cancel(self, id): + """ + Cancel an item. + """ + self.item_list.cancel(id) + + def reset(self): + """ + Reset all items. + """ + self.item_list.reset() + + # Hide not empty, show empty + self.not_empty.hide() + self.empty.show() + + +class ToggleHistory(QtWidgets.QPushButton): + """ + Widget for toggling showing or hiding the history, as well as keeping track + of the indicator counter if it's hidden + """ + def __init__(self, common, current_mode, history_widget, icon, selected_icon): + super(ToggleHistory, self).__init__() + self.common = common + self.current_mode = current_mode + self.history_widget = history_widget + self.icon = icon + self.selected_icon = selected_icon + + # Toggle button + self.setDefault(False) + self.setFixedWidth(35) + self.setFixedHeight(30) + self.setFlat(True) + self.setIcon(icon) + self.clicked.connect(self.toggle_clicked) + + # Keep track of indicator + self.indicator_count = 0 + self.indicator_label = QtWidgets.QLabel(parent=self) + self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) + self.update_indicator() + + def update_indicator(self, increment=False): + """ + Update the display of the indicator count. If increment is True, then + only increment the counter if Downloads is hidden. + """ + if increment and not self.history_widget.isVisible(): + self.indicator_count += 1 + + self.indicator_label.setText("{}".format(self.indicator_count)) + + if self.indicator_count == 0: + self.indicator_label.hide() + else: + size = self.indicator_label.sizeHint() + self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) + self.indicator_label.show() + + def toggle_clicked(self): + """ + Toggle showing and hiding the history widget + """ + self.common.log('ToggleHistory', 'toggle_clicked') + + if self.history_widget.isVisible(): + self.history_widget.hide() + self.setIcon(self.icon) + self.setFlat(True) + else: + self.history_widget.show() + self.setIcon(self.selected_icon) + self.setFlat(False) + + # Reset the indicator count + self.indicator_count = 0 + self.update_indicator() + + self.current_mode.resize_window() diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py index f7ba2760..bae4bec8 100644 --- a/onionshare_gui/mode/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -26,13 +26,12 @@ from onionshare.common import Common from onionshare.web import Web from .file_selection import FileSelection -from .downloads import Downloads from .threads import CompressThread -#from .info import ShareModeInfo from .. import Mode -from ..toggle_history import ToggleHistory +from ..history import History, ToggleHistory, DownloadHistoryItem from ...widgets import Alert + class ShareMode(Mode): """ Parts of the main window UI for sharing files. @@ -72,9 +71,14 @@ class ShareMode(Mode): self.filesize_warning.setStyleSheet(self.common.css['share_filesize_warning']) self.filesize_warning.hide() - # Downloads - self.downloads = Downloads(self.common) - self.downloads.hide() + # Download history + self.history = History( + self.common, + QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/downloads_transparent.png'))), + strings._('gui_no_downloads'), + strings._('gui_downloads') + ) + self.history.hide() self.downloads_in_progress = 0 self.downloads_completed = 0 @@ -87,7 +91,7 @@ class ShareMode(Mode): # Toggle history self.toggle_history = ToggleHistory( - self.common, self, self.downloads, + self.common, self, self.history, QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')), QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) ) @@ -116,7 +120,7 @@ class ShareMode(Mode): # Wrapper layout self.wrapper_layout = QtWidgets.QHBoxLayout() self.wrapper_layout.addLayout(self.main_layout) - self.wrapper_layout.addWidget(self.downloads) + self.wrapper_layout.addWidget(self.history) self.setLayout(self.wrapper_layout) # Always start with focus on file selection @@ -241,7 +245,9 @@ class ShareMode(Mode): filesize = self.web.share_mode.gzip_filesize else: filesize = self.web.share_mode.download_filesize - self.downloads.add(event["data"]["id"], filesize) + + item = DownloadHistoryItem(self.common, event["data"]["id"], filesize) + self.history.add(event["data"]["id"], item) self.toggle_history.update_indicator(True) self.downloads_in_progress += 1 #self.info.update_downloads_in_progress() @@ -252,7 +258,7 @@ class ShareMode(Mode): """ Handle REQUEST_PROGRESS event. """ - self.downloads.update(event["data"]["id"], event["data"]["bytes"]) + self.history.update(event["data"]["id"], event["data"]["bytes"]) # Is the download complete? if event["data"]["bytes"] == self.web.share_mode.filesize: @@ -272,7 +278,7 @@ class ShareMode(Mode): self.server_status_label.setText(strings._('closing_automatically', True)) else: if self.server_status.status == self.server_status.STATUS_STOPPED: - self.downloads.cancel(event["data"]["id"]) + self.history.cancel(event["data"]["id"]) self.downloads_in_progress = 0 #self.info.update_downloads_in_progress() @@ -280,7 +286,7 @@ class ShareMode(Mode): """ Handle REQUEST_CANCELED event. """ - self.downloads.cancel(event["data"]["id"]) + self.history.cancel(event["data"]["id"]) # Update the 'in progress downloads' info self.downloads_in_progress -= 1 @@ -332,11 +338,11 @@ class ShareMode(Mode): self.downloads_in_progress = 0 #self.info.update_downloads_completed() #self.info.update_downloads_in_progress() - self.downloads.reset() + self.history.reset() def resize_window(self): min_width = self.common.min_window_width - if self.downloads.isVisible(): + if self.history.isVisible(): min_width += 300 self.adjust_size.emit(min_width) diff --git a/onionshare_gui/mode/share_mode/downloads.py b/onionshare_gui/mode/share_mode/downloads.py deleted file mode 100644 index e78231ad..00000000 --- a/onionshare_gui/mode/share_mode/downloads.py +++ /dev/null @@ -1,248 +0,0 @@ -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2014-2018 Micah Lee - -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 . -""" -import time -from PyQt5 import QtCore, QtWidgets, QtGui - -from onionshare import strings - - -class Download(QtWidgets.QWidget): - def __init__(self, common, download_id, total_bytes): - super(Download, self).__init__() - self.common = common - - self.download_id = download_id - self.started = time.time() - self.total_bytes = total_bytes - self.downloaded_bytes = 0 - - self.setStyleSheet('QWidget { border: 1px solid red; }') - - # Progress bar - self.progress_bar = QtWidgets.QProgressBar() - self.progress_bar.setTextVisible(True) - self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) - self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) - self.progress_bar.setMinimum(0) - self.progress_bar.setMaximum(total_bytes) - self.progress_bar.setValue(0) - self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar']) - self.progress_bar.total_bytes = total_bytes - - # Layout - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.progress_bar) - self.setLayout(layout) - - # Start at 0 - self.update(0) - - def update(self, downloaded_bytes): - self.downloaded_bytes = downloaded_bytes - - self.progress_bar.setValue(downloaded_bytes) - if downloaded_bytes == self.progress_bar.total_bytes: - pb_fmt = strings._('gui_download_upload_progress_complete').format( - self.common.format_seconds(time.time() - self.started)) - else: - elapsed = time.time() - self.started - if elapsed < 10: - # Wait a couple of seconds for the download rate to stabilize. - # This prevents a "Windows copy dialog"-esque experience at - # the beginning of the download. - pb_fmt = strings._('gui_download_upload_progress_starting').format( - self.common.human_readable_filesize(downloaded_bytes)) - else: - pb_fmt = strings._('gui_download_upload_progress_eta').format( - self.common.human_readable_filesize(downloaded_bytes), - self.estimated_time_remaining) - - self.progress_bar.setFormat(pb_fmt) - - def cancel(self): - self.progress_bar.setFormat(strings._('gui_canceled')) - - @property - def estimated_time_remaining(self): - return self.common.estimated_time_remaining(self.downloaded_bytes, - self.total_bytes, - self.started) - - -class DownloadList(QtWidgets.QScrollArea): - """ - List of download progress bars. - """ - def __init__(self, common): - super(DownloadList, self).__init__() - self.common = common - - self.downloads = {} - - # The layout that holds all of the downloads - self.downloads_layout = QtWidgets.QVBoxLayout() - self.downloads_layout.setContentsMargins(0, 0, 0, 0) - self.downloads_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) - - # Wrapper layout that also contains a stretch - wrapper_layout = QtWidgets.QVBoxLayout() - wrapper_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) - wrapper_layout.addLayout(self.downloads_layout) - wrapper_layout.addStretch() - - # The internal widget of the scroll area - widget = QtWidgets.QWidget() - widget.setLayout(wrapper_layout) - self.setWidget(widget) - self.setWidgetResizable(True) - - # Other scroll area settings - self.setBackgroundRole(QtGui.QPalette.Light) - self.verticalScrollBar().rangeChanged.connect(self.resizeScroll) - - def resizeScroll(self, minimum, maximum): - """ - Scroll to the bottom of the window when the range changes. - """ - self.verticalScrollBar().setValue(maximum) - - def add(self, download_id, content_length): - """ - Add a new download progress bar. - """ - download = Download(self.common, download_id, content_length) - self.downloads[download_id] = download - self.downloads_layout.addWidget(download) - - def update(self, download_id, downloaded_bytes): - """ - Update the progress of a download progress bar. - """ - self.downloads[download_id].update(downloaded_bytes) - - def cancel(self, download_id): - """ - Update a download progress bar to show that it has been canceled. - """ - self.downloads[download_id].cancel() - - def reset(self): - """ - Reset the downloads back to zero - """ - for download in self.downloads.values(): - self.downloads_layout.removeWidget(download) - download.progress_bar.close() - self.downloads = {} - - -class Downloads(QtWidgets.QWidget): - """ - The downloads chunk of the GUI. This lists all of the active download - progress bars. - """ - def __init__(self, common): - super(Downloads, self).__init__() - self.common = common - - self.setMinimumWidth(350) - - # When there are no downloads - empty_image = QtWidgets.QLabel() - empty_image.setAlignment(QtCore.Qt.AlignCenter) - empty_image.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/downloads_transparent.png')))) - empty_text = QtWidgets.QLabel(strings._('gui_no_downloads', True)) - empty_text.setAlignment(QtCore.Qt.AlignCenter) - empty_text.setStyleSheet(self.common.css['downloads_uploads_empty_text']) - empty_layout = QtWidgets.QVBoxLayout() - empty_layout.addStretch() - empty_layout.addWidget(empty_image) - empty_layout.addWidget(empty_text) - empty_layout.addStretch() - self.empty = QtWidgets.QWidget() - self.empty.setStyleSheet(self.common.css['downloads_uploads_empty']) - self.empty.setLayout(empty_layout) - - # When there are downloads - self.download_list = DownloadList(self.common) - - # Download header - downloads_label = QtWidgets.QLabel(strings._('gui_downloads', True)) - downloads_label.setStyleSheet(self.common.css['downloads_uploads_label']) - clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) - clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) - clear_button.setFlat(True) - clear_button.clicked.connect(self.reset) - download_header = QtWidgets.QHBoxLayout() - download_header.addWidget(downloads_label) - download_header.addStretch() - download_header.addWidget(clear_button) - - # Download layout - not_empty_layout = QtWidgets.QVBoxLayout() - not_empty_layout.addLayout(download_header) - not_empty_layout.addWidget(self.download_list) - self.not_empty = QtWidgets.QWidget() - self.not_empty.setLayout(not_empty_layout) - - # Layout - layout = QtWidgets.QVBoxLayout() - layout.setContentsMargins(0, 0, 0, 0) - layout.addWidget(self.empty) - layout.addWidget(self.not_empty) - self.setLayout(layout) - - # Reset once at the beginning - self.reset() - - def add(self, download_id, content_length): - """ - Add a new download progress bar. - """ - self.common.log('Downloads', 'add', 'download_id: {}, content_length: {}'.format(download_id, content_length)) - - # Hide empty, show not empty - self.empty.hide() - self.not_empty.show() - - # Add it to the list - self.download_list.add(download_id, content_length) - - def update(self, download_id, downloaded_bytes): - """ - Update the progress of a download progress bar. - """ - self.download_list.update(download_id, downloaded_bytes) - - def cancel(self, download_id): - """ - Update a download progress bar to show that it has been canceled. - """ - self.download_list.cancel(download_id) - - def reset(self): - """ - Reset the downloads back to zero - """ - self.download_list.reset() - - # Hide not empty, show empty - self.not_empty.hide() - self.empty.show() diff --git a/onionshare_gui/mode/toggle_history.py b/onionshare_gui/mode/toggle_history.py deleted file mode 100644 index 81ecde86..00000000 --- a/onionshare_gui/mode/toggle_history.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2014-2018 Micah Lee - -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 . -""" -from PyQt5 import QtCore, QtWidgets, QtGui - -from onionshare import strings - - -class ToggleHistory(QtWidgets.QPushButton): - """ - Widget for toggling download/upload history on or off, as well as keeping track - of the indicator counter - """ - def __init__(self, common, current_mode, history_widget, icon, selected_icon): - super(ToggleHistory, self).__init__() - self.common = common - self.current_mode = current_mode - self.history_widget = history_widget - self.icon = icon - self.selected_icon = selected_icon - - # Toggle button - self.setDefault(False) - self.setFixedWidth(35) - self.setFixedHeight(30) - self.setFlat(True) - self.setIcon(icon) - self.clicked.connect(self.toggle_clicked) - - # Keep track of indicator - self.indicator_count = 0 - self.indicator_label = QtWidgets.QLabel(parent=self) - self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) - self.update_indicator() - - def update_indicator(self, increment=False): - """ - Update the display of the indicator count. If increment is True, then - only increment the counter if Downloads is hidden. - """ - if increment and not self.history_widget.isVisible(): - self.indicator_count += 1 - - self.indicator_label.setText("{}".format(self.indicator_count)) - - if self.indicator_count == 0: - self.indicator_label.hide() - else: - size = self.indicator_label.sizeHint() - self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) - self.indicator_label.show() - - def toggle_clicked(self): - """ - Toggle showing and hiding the history widget - """ - self.common.log('ToggleHistory', 'toggle_clicked') - - if self.history_widget.isVisible(): - self.history_widget.hide() - self.setIcon(self.icon) - self.setFlat(True) - else: - self.history_widget.show() - self.setIcon(self.selected_icon) - self.setFlat(False) - - # Reset the indicator count - self.indicator_count = 0 - self.update_indicator() - - self.current_mode.resize_window() From d047f1261aa230afee832134c0f09b0b1a4db27f Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 18:09:02 -0700 Subject: [PATCH 051/142] Delete Info widget, and move completed and in progress widgets into the header of history --- onionshare_gui/mode/history.py | 68 ++++++++-- onionshare_gui/mode/share_mode/__init__.py | 40 +++--- onionshare_gui/mode/share_mode/info.py | 149 --------------------- share/locale/en.json | 4 +- 4 files changed, 72 insertions(+), 189 deletions(-) delete mode 100644 onionshare_gui/mode/share_mode/info.py diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index 31b4a646..a28340a4 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -179,6 +179,30 @@ class History(QtWidgets.QWidget): self.setMinimumWidth(350) + # In progress and completed counters + self.in_progress_count = 0 + self.completed_count = 0 + + # In progress and completed labels + self.in_progress_label = QtWidgets.QLabel() + self.in_progress_label.setStyleSheet(self.common.css['mode_info_label']) + self.completed_label = QtWidgets.QLabel() + self.completed_label.setStyleSheet(self.common.css['mode_info_label']) + + # Header + self.header_label = QtWidgets.QLabel(header_text) + self.header_label.setStyleSheet(self.common.css['downloads_uploads_label']) + clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) + clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) + clear_button.setFlat(True) + 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(clear_button) + # When there are no items self.empty_image = QtWidgets.QLabel() self.empty_image.setAlignment(QtCore.Qt.AlignCenter) @@ -195,22 +219,9 @@ class History(QtWidgets.QWidget): self.empty.setStyleSheet(self.common.css['downloads_uploads_empty']) self.empty.setLayout(empty_layout) - # Header - self.header_label = QtWidgets.QLabel(header_text) - self.header_label.setStyleSheet(self.common.css['downloads_uploads_label']) - clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) - clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) - clear_button.setFlat(True) - clear_button.clicked.connect(self.reset) - header_layout = QtWidgets.QHBoxLayout() - header_layout.addWidget(self.header_label) - header_layout.addStretch() - header_layout.addWidget(clear_button) - # When there are items self.item_list = HistoryItemList(self.common) self.not_empty_layout = QtWidgets.QVBoxLayout() - self.not_empty_layout.addLayout(header_layout) self.not_empty_layout.addWidget(self.item_list) self.not_empty = QtWidgets.QWidget() self.not_empty.setLayout(self.not_empty_layout) @@ -218,12 +229,15 @@ class History(QtWidgets.QWidget): # Layout layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) + layout.addLayout(header_layout) layout.addWidget(self.empty) layout.addWidget(self.not_empty) self.setLayout(layout) # Reset once at the beginning self.reset() + self.update_completed() + self.update_in_progress() def add(self, id, item): """ @@ -261,6 +275,34 @@ class History(QtWidgets.QWidget): self.not_empty.hide() self.empty.show() + # Reset counters + self.completed_count = 0 + self.in_progress_count = 0 + self.update_completed() + self.update_in_progress() + + def update_completed(self): + """ + Update the 'completed' widget. + """ + if self.completed_count == 0: + image = self.common.get_resource_path('images/share_completed_none.png') + else: + image = self.common.get_resource_path('images/share_completed.png') + self.completed_label.setText(' {1:d}'.format(image, self.completed_count)) + self.completed_label.setToolTip(strings._('history_completed_tooltip').format(self.completed_count)) + + def update_in_progress(self): + """ + Update the 'in progress' widget. + """ + if self.in_progress_count == 0: + image = self.common.get_resource_path('images/share_in_progress_none.png') + else: + image = self.common.get_resource_path('images/share_in_progress.png') + self.in_progress_label.setText(' {1:d}'.format(image, self.in_progress_count)) + self.in_progress_label.setToolTip(strings._('history_in_progress_tooltip', True).format(self.in_progress_count)) + class ToggleHistory(QtWidgets.QPushButton): """ diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py index bae4bec8..0bf094c0 100644 --- a/onionshare_gui/mode/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -79,11 +79,6 @@ class ShareMode(Mode): strings._('gui_downloads') ) self.history.hide() - self.downloads_in_progress = 0 - self.downloads_completed = 0 - - # Information about share, and show downloads button - #self.info = ShareModeInfo(self.common, self) # Info label self.info_label = QtWidgets.QLabel() @@ -211,9 +206,9 @@ class ShareMode(Mode): self._zip_progress_bar = None self.filesize_warning.hide() - self.downloads_in_progress = 0 - self.downloads_completed = 0 - #self.info.update_downloads_in_progress() + self.history.in_progress_count = 0 + self.history.completed_count = 0 + self.history.update_in_progress() self.file_selection.file_list.adjustSize() def cancel_server_custom(self): @@ -249,8 +244,8 @@ class ShareMode(Mode): item = DownloadHistoryItem(self.common, event["data"]["id"], filesize) self.history.add(event["data"]["id"], item) self.toggle_history.update_indicator(True) - self.downloads_in_progress += 1 - #self.info.update_downloads_in_progress() + self.history.in_progress_count += 1 + self.history.update_in_progress() self.system_tray.showMessage(strings._('systray_download_started_title', True), strings._('systray_download_started_message', True)) @@ -264,12 +259,11 @@ class ShareMode(Mode): if event["data"]["bytes"] == self.web.share_mode.filesize: self.system_tray.showMessage(strings._('systray_download_completed_title', True), strings._('systray_download_completed_message', True)) - # Update the total 'completed downloads' info - self.downloads_completed += 1 - #self.info.update_downloads_completed() - # Update the 'in progress downloads' info - self.downloads_in_progress -= 1 - #self.info.update_downloads_in_progress() + # Update completed and in progress labels + self.history.completed_count += 1 + self.history.in_progress_count -= 1 + self.history.update_completed() + self.history.update_in_progress() # Close on finish? if self.common.settings.get('close_after_first_download'): @@ -279,8 +273,8 @@ class ShareMode(Mode): else: if self.server_status.status == self.server_status.STATUS_STOPPED: self.history.cancel(event["data"]["id"]) - self.downloads_in_progress = 0 - #self.info.update_downloads_in_progress() + self.history.in_progress_count = 0 + self.history.update_in_progress() def handle_request_canceled(self, event): """ @@ -288,9 +282,9 @@ class ShareMode(Mode): """ self.history.cancel(event["data"]["id"]) - # Update the 'in progress downloads' info - self.downloads_in_progress -= 1 - #self.info.update_downloads_in_progress() + # Update in progress count + self.history.in_progress_count -= 1 + self.history.update_in_progress() self.system_tray.showMessage(strings._('systray_download_canceled_title', True), strings._('systray_download_canceled_message', True)) def on_reload_settings(self): @@ -334,10 +328,6 @@ class ShareMode(Mode): """ Set the info counters back to zero. """ - self.downloads_completed = 0 - self.downloads_in_progress = 0 - #self.info.update_downloads_completed() - #self.info.update_downloads_in_progress() self.history.reset() def resize_window(self): diff --git a/onionshare_gui/mode/share_mode/info.py b/onionshare_gui/mode/share_mode/info.py deleted file mode 100644 index c692649c..00000000 --- a/onionshare_gui/mode/share_mode/info.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2014-2018 Micah Lee - -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 . -""" -from PyQt5 import QtCore, QtWidgets, QtGui - -from onionshare import strings - - -class ShareModeInfo(QtWidgets.QWidget): - """ - Share mode information widget - """ - def __init__(self, common, share_mode): - super(ShareModeInfo, self).__init__() - self.common = common - self.share_mode = share_mode - - # Label - self.label_text = "" - self.label = QtWidgets.QLabel() - self.label.setStyleSheet(self.common.css['mode_info_label']) - - # In progress and completed labels - self.in_progress_downloads_count = QtWidgets.QLabel() - self.in_progress_downloads_count.setStyleSheet(self.common.css['mode_info_label']) - self.completed_downloads_count = QtWidgets.QLabel() - self.completed_downloads_count.setStyleSheet(self.common.css['mode_info_label']) - - # Toggle button - self.toggle_button = QtWidgets.QPushButton() - self.toggle_button.setDefault(False) - self.toggle_button.setFixedWidth(35) - self.toggle_button.setFixedHeight(30) - self.toggle_button.setFlat(True) - self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) - self.toggle_button.clicked.connect(self.toggle_downloads) - - # Keep track of indicator - self.indicator_count = 0 - self.indicator_label = QtWidgets.QLabel(parent=self.toggle_button) - self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) - self.update_indicator() - - # Layout - layout = QtWidgets.QHBoxLayout() - layout.addWidget(self.label) - layout.addStretch() - layout.addWidget(self.in_progress_downloads_count) - layout.addWidget(self.completed_downloads_count) - layout.addWidget(self.toggle_button) - self.setLayout(layout) - - self.update_downloads_completed() - self.update_downloads_in_progress() - - def update_label(self, s): - """ - Updates the text of the label. - """ - self.label_text = s - self.label.setText(self.label_text) - - def update_indicator(self, increment=False): - """ - Update the display of the indicator count. If increment is True, then - only increment the counter if Downloads is hidden. - """ - if increment and not self.share_mode.downloads.isVisible(): - self.indicator_count += 1 - - self.indicator_label.setText("{}".format(self.indicator_count)) - - if self.indicator_count == 0: - self.indicator_label.hide() - else: - size = self.indicator_label.sizeHint() - self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) - self.indicator_label.show() - - def update_downloads_completed(self): - """ - Update the 'Downloads completed' info widget. - """ - if self.share_mode.downloads_completed == 0: - image = self.common.get_resource_path('images/share_completed_none.png') - else: - image = self.common.get_resource_path('images/share_completed.png') - self.completed_downloads_count.setText(' {1:d}'.format(image, self.share_mode.downloads_completed)) - self.completed_downloads_count.setToolTip(strings._('info_completed_downloads_tooltip', True).format(self.share_mode.downloads_completed)) - - def update_downloads_in_progress(self): - """ - Update the 'Downloads in progress' info widget. - """ - if self.share_mode.downloads_in_progress == 0: - image = self.common.get_resource_path('images/share_in_progress_none.png') - else: - image = self.common.get_resource_path('images/share_in_progress.png') - self.in_progress_downloads_count.setText(' {1:d}'.format(image, self.share_mode.downloads_in_progress)) - self.in_progress_downloads_count.setToolTip(strings._('info_in_progress_downloads_tooltip', True).format(self.share_mode.downloads_in_progress)) - - def toggle_downloads(self): - """ - Toggle showing and hiding the Downloads widget - """ - self.common.log('ShareModeInfo', 'toggle_downloads') - - if self.share_mode.downloads.isVisible(): - self.share_mode.downloads.hide() - self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')) ) - self.toggle_button.setFlat(True) - else: - self.share_mode.downloads.show() - self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) ) - self.toggle_button.setFlat(False) - - # Reset the indicator count - self.indicator_count = 0 - self.update_indicator() - - self.share_mode.resize_window() - - def show_less(self): - """ - Remove clutter widgets that aren't necessary. - """ - self.label.setText("") - - def show_more(self): - """ - Show all widgets. - """ - self.label.setText(self.label_text) diff --git a/share/locale/en.json b/share/locale/en.json index c7beb6ba..3537b0a2 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -151,8 +151,8 @@ "gui_status_indicator_receive_started": "Receiving", "gui_file_info": "{} files, {}", "gui_file_info_single": "{} file, {}", - "info_in_progress_downloads_tooltip": "{} download(s) in progress", - "info_completed_downloads_tooltip": "{} download(s) completed", + "history_in_progress_tooltip": "{} in progress", + "history_completed_tooltip": "{} completed", "info_in_progress_uploads_tooltip": "{} upload(s) in progress", "info_completed_uploads_tooltip": "{} upload(s) completed", "error_cannot_create_downloads_dir": "Could not create receive mode folder: {}", From c10d56e0117e3f0c934c6a1002c27705870da2a7 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 18:20:13 -0700 Subject: [PATCH 052/142] The History header is now only shown if there are items again, and the clear history button resets everything. Also, reset hides individual items because, for some reason, they still show up otherwise. --- onionshare_gui/mode/history.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index a28340a4..0f8ccdca 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -165,6 +165,7 @@ class HistoryItemList(QtWidgets.QScrollArea): """ for item in self.items.values(): self.items_layout.removeWidget(item) + item.hide() self.items = {} @@ -222,6 +223,7 @@ class History(QtWidgets.QWidget): # When there are items self.item_list = HistoryItemList(self.common) self.not_empty_layout = QtWidgets.QVBoxLayout() + self.not_empty_layout.addLayout(header_layout) self.not_empty_layout.addWidget(self.item_list) self.not_empty = QtWidgets.QWidget() self.not_empty.setLayout(self.not_empty_layout) @@ -229,15 +231,12 @@ class History(QtWidgets.QWidget): # Layout layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) - layout.addLayout(header_layout) layout.addWidget(self.empty) layout.addWidget(self.not_empty) self.setLayout(layout) # Reset once at the beginning self.reset() - self.update_completed() - self.update_in_progress() def add(self, id, item): """ @@ -252,7 +251,6 @@ class History(QtWidgets.QWidget): # Add it to the list self.item_list.add(id, item) - def update(self, id, data): """ Update an item. From 9ccacb07e42bea0074f8ad7d0a81eae9dcd083dd Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 18:49:09 -0700 Subject: [PATCH 053/142] Start fixing the GUI tests. Also, refactor CommonTests to pass in a Mode object instead of the string "share" or "receive" --- tests_gui_local/commontests.py | 182 +++++------------- ...re_share_mode_download_test_public_mode.py | 38 ++-- 2 files changed, 69 insertions(+), 151 deletions(-) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/commontests.py index 21e8cfad..5ceee668 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/commontests.py @@ -6,6 +6,9 @@ import zipfile from PyQt5 import QtCore, QtTest from onionshare import strings +from onionshare_gui.mode.receive_mode import ReceiveMode +from onionshare_gui.mode.share_mode import ShareMode + class CommonTests(object): def test_gui_loaded(self): @@ -24,71 +27,42 @@ class CommonTests(object): '''Test that the status bar is visible''' self.assertTrue(self.gui.status_bar.isVisible()) - def test_info_widget_shows_less(self, mode): - '''Test that minimum information (no label) is displayed in the info bar''' - if mode == 'share': - self.assertFalse(self.gui.share_mode.info.label.text() == "") - if mode == 'receive': - # There's no minimal display in receive mode - self.assertTrue(False) - def test_click_mode(self, mode): '''Test that we can switch Mode by clicking the button''' - if mode == 'receive': + 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 mode == 'share': + if type(mode) == ShareMode: QtTest.QTest.mouseClick(self.gui.share_mode_button, QtCore.Qt.LeftButton) self.assertTrue(self.gui.mode, self.gui.MODE_SHARE) def test_click_toggle_history(self, mode): '''Test that we can toggle Download or Upload history by clicking the toggle button''' - if mode == 'receive': - currently_visible = self.gui.receive_mode.uploads.isVisible() - QtTest.QTest.mouseClick(self.gui.receive_mode.info.toggle_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.receive_mode.uploads.isVisible(), not currently_visible) - if mode == 'share': - currently_visible = self.gui.receive_mode.uploads.isVisible() - QtTest.QTest.mouseClick(self.gui.share_mode.info.toggle_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.share_mode.downloads.isVisible(), not currently_visible) + currently_visible = mode.history.isVisible() + QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton) + self.assertEqual(mode.history.isVisible(), not currently_visible) def test_history_indicator(self, mode, public_mode): '''Test that we can make sure the history is toggled off, do an action, and the indiciator works''' - if mode == 'receive': - # Make sure history is toggled off - if self.gui.receive_mode.uploads.isVisible(): - QtTest.QTest.mouseClick(self.gui.receive_mode.info.toggle_button, QtCore.Qt.LeftButton) - self.assertFalse(self.gui.receive_mode.uploads.isVisible()) + # 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(self.gui.receive_mode.info.indicator_label.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')} if not public_mode: - path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, self.gui.receive_mode.web.slug) + path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, mode.web.slug) else: path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) response = requests.post(path, files=files) QtTest.QTest.qWait(2000) - # Indicator should be visible, have a value of "1" - self.assertTrue(self.gui.receive_mode.info.indicator_label.isVisible()) - self.assertEqual(self.gui.receive_mode.info.indicator_label.text(), "1") - - # Toggle history back on, indicator should be hidden again - QtTest.QTest.mouseClick(self.gui.receive_mode.info.toggle_button, QtCore.Qt.LeftButton) - self.assertFalse(self.gui.receive_mode.info.indicator_label.isVisible()) - - if mode == 'share': - # Make sure history is toggled off - if self.gui.share_mode.downloads.isVisible(): - QtTest.QTest.mouseClick(self.gui.share_mode.info.toggle_button, QtCore.Qt.LeftButton) - self.assertFalse(self.gui.share_mode.downloads.isVisible()) - - # Indicator should not be visible yet - self.assertFalse(self.gui.share_mode.info.indicator_label.isVisible()) - + if type(mode) == ShareMode: # Download files if public_mode: url = "http://127.0.0.1:{}/download".format(self.gui.app.port) @@ -97,44 +71,31 @@ class CommonTests(object): r = requests.get(url) QtTest.QTest.qWait(2000) - # Indicator should be visible, have a value of "1" - self.assertTrue(self.gui.share_mode.info.indicator_label.isVisible()) - self.assertEqual(self.gui.share_mode.info.indicator_label.text(), "1") + # 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(self.gui.share_mode.info.toggle_button, QtCore.Qt.LeftButton) - self.assertFalse(self.gui.share_mode.info.indicator_label.isVisible()) + # 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 test_history_is_not_visible(self, mode): '''Test that the History section is not visible''' - if mode == 'receive': - self.assertFalse(self.gui.receive_mode.uploads.isVisible()) - if mode == 'share': - self.assertFalse(self.gui.share_mode.downloads.isVisible()) + self.assertFalse(mode.history.isVisible()) def test_history_is_visible(self, mode): '''Test that the History section is visible''' - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.uploads.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.downloads.isVisible()) + self.assertTrue(mode.history.isVisible()) def test_server_working_on_start_button_pressed(self, mode): '''Test we can start the service''' # Should be in SERVER_WORKING state - if mode == 'receive': - QtTest.QTest.mouseClick(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.receive_mode.server_status.status, 1) - if mode == 'share': - QtTest.QTest.mouseClick(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.share_mode.server_status.status, 1) + QtTest.QTest.mouseClick(mode.server_status.server_button, QtCore.Qt.LeftButton) + self.assertEqual(mode.server_status.status, 1) def test_server_status_indicator_says_starting(self, mode): '''Test that the Server Status indicator shows we are Starting''' - if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) - if mode == 'share': - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) + self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_share_working', True)) def test_settings_button_is_hidden(self): '''Test that the settings button is hidden when the server starts''' @@ -144,10 +105,7 @@ class CommonTests(object): '''Test that the server has started''' QtTest.QTest.qWait(2000) # Should now be in SERVER_STARTED state - if mode == 'receive': - self.assertEqual(self.gui.receive_mode.server_status.status, 2) - if mode == 'share': - self.assertEqual(self.gui.share_mode.server_status.status, 2) + self.assertEqual(mode.server_status.status, 2) def test_a_web_server_is_running(self): '''Test that the web server has started''' @@ -157,38 +115,26 @@ class CommonTests(object): def test_have_a_slug(self, mode, public_mode): '''Test that we have a valid slug''' - if mode == 'receive': - if not public_mode: - self.assertRegex(self.gui.receive_mode.server_status.web.slug, r'(\w+)-(\w+)') - else: - self.assertIsNone(self.gui.receive_mode.server_status.web.slug, r'(\w+)-(\w+)') - if mode == 'share': - if not public_mode: - self.assertRegex(self.gui.share_mode.server_status.web.slug, r'(\w+)-(\w+)') - else: - self.assertIsNone(self.gui.share_mode.server_status.web.slug, r'(\w+)-(\w+)') + if not public_mode: + self.assertRegex(mode.server_status.web.slug, r'(\w+)-(\w+)') + else: + self.assertIsNone(mode.server_status.web.slug, r'(\w+)-(\w+)') def test_url_description_shown(self, mode): '''Test that the URL label is showing''' - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.server_status.url_description.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.server_status.url_description.isVisible()) + self.assertTrue(mode.server_status.url_description.isVisible()) def test_have_copy_url_button(self, mode): '''Test that the Copy URL button is shown''' - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.server_status.copy_url_button.isVisible()) - if mode == 'share': - self.assertTrue(self.gui.share_mode.server_status.copy_url_button.isVisible()) + self.assertTrue(mode.server_status.copy_url_button.isVisible()) def test_server_status_indicator_says_started(self, mode): '''Test that the Server Status indicator shows we are started''' - if mode == 'receive': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) - if mode == 'share': - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) + if type(mode) == ReceiveMode: + self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_receive_started', True)) + if type(mode) == ShareMode: + self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_share_started', True)) def test_web_page(self, mode, string, public_mode): '''Test that the web page contains a string''' @@ -197,10 +143,7 @@ class CommonTests(object): s.connect(('127.0.0.1', self.gui.app.port)) if not public_mode: - if mode == 'receive': - path = '/{}'.format(self.gui.receive_mode.server_status.web.slug) - if mode == 'share': - path = '/{}'.format(self.gui.share_mode.server_status.web.slug) + path = '/{}'.format(mode.server_status.web.slug) else: path = '/' @@ -223,29 +166,18 @@ class CommonTests(object): def test_history_widgets_present(self, mode): '''Test that the relevant widgets are present in the history view after activity has taken place''' - if mode == 'receive': - self.assertFalse(self.gui.receive_mode.uploads.empty.isVisible()) - self.assertTrue(self.gui.receive_mode.uploads.not_empty.isVisible()) - if mode == 'share': - self.assertFalse(self.gui.share_mode.downloads.empty.isVisible()) - self.assertTrue(self.gui.share_mode.downloads.not_empty.isVisible()) + self.assertFalse(mode.history.empty.isVisible()) + self.assertTrue(mode.history.not_empty.isVisible()) def test_counter_incremented(self, mode, count): '''Test that the counter has incremented''' - if mode == 'receive': - self.assertEquals(self.gui.receive_mode.uploads_completed, count) - if mode == 'share': - self.assertEquals(self.gui.share_mode.downloads_completed, count) + self.assertEquals(mode.uploads_completed, count) def test_server_is_stopped(self, mode, stay_open): '''Test that the server stops when we click Stop''' - if mode == 'receive': - QtTest.QTest.mouseClick(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.receive_mode.server_status.status, 0) - if mode == 'share': - if stay_open: - QtTest.QTest.mouseClick(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(self.gui.share_mode.server_status.status, 0) + if type(mode) == ReceiveMode or (type(mode) == ShareMode and stay_open): + QtTest.QTest.mouseClick(mode.server_status.server_button, QtCore.Qt.LeftButton) + self.assertEquals(mode.server_status.status, 0) def test_web_service_is_stopped(self): '''Test that the web server also stopped''' @@ -257,9 +189,9 @@ class CommonTests(object): def test_server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' - if mode == 'receive': + if type(mode) == ReceiveMode: self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) - if mode == 'share': + if type(mode) == ShareMode: if stay_open: self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped', True)) else: @@ -269,28 +201,18 @@ class CommonTests(object): def test_set_timeout(self, mode, timeout): '''Test that the timeout can be set''' timer = QtCore.QDateTime.currentDateTime().addSecs(timeout) - if mode == 'receive': - self.gui.receive_mode.server_status.shutdown_timeout.setDateTime(timer) - self.assertTrue(self.gui.receive_mode.server_status.shutdown_timeout.dateTime(), timer) - if mode == 'share': - self.gui.share_mode.server_status.shutdown_timeout.setDateTime(timer) - self.assertTrue(self.gui.share_mode.server_status.shutdown_timeout.dateTime(), timer) + mode.server_status.shutdown_timeout.setDateTime(timer) + self.assertTrue(mode.server_status.shutdown_timeout.dateTime(), timer) def test_timeout_widget_hidden(self, mode): '''Test that the timeout widget is hidden when share has started''' - if mode == 'receive': - self.assertFalse(self.gui.receive_mode.server_status.shutdown_timeout_container.isVisible()) - if mode == 'share': - self.assertFalse(self.gui.share_mode.server_status.shutdown_timeout_container.isVisible()) + self.assertFalse(mode.server_status.shutdown_timeout_container.isVisible()) def test_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 - if mode == 'receive': - self.assertEqual(self.gui.receive_mode.server_status.status, 0) - if mode == 'share': - self.assertEqual(self.gui.share_mode.server_status.status, 0) + self.assertEqual(mode.server_status.status, 0) # Receive-specific tests def test_upload_file(self, public_mode, expected_file): diff --git a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py index a10ee4c2..82f1989c 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py +++ b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py @@ -96,21 +96,17 @@ class OnionShareGuiTest(unittest.TestCase): def test_file_selection_widget_has_a_file(self): CommonTests.test_file_selection_widget_has_a_file(self) - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - @pytest.mark.run(order=7) def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') + CommonTests.test_history_is_not_visible(self, self.gui.share_mode) @pytest.mark.run(order=8) def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') + CommonTests.test_click_toggle_history(self, self.gui.share_mode) @pytest.mark.run(order=9) def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') + CommonTests.test_history_is_visible(self, self.gui.share_mode) @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): @@ -126,11 +122,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') + CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): @@ -142,7 +138,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=17) def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_a_server_is_started(self, self.gui.share_mode) @pytest.mark.run(order=18) def test_a_web_server_is_running(self): @@ -150,23 +146,23 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=19) def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', True) + CommonTests.test_have_a_slug(self, self.gui.share_mode, True) @pytest.mark.run(order=20) def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') + CommonTests.test_url_description_shown(self, self.gui.share_mode) @pytest.mark.run(order=21) def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') + CommonTests.test_have_copy_url_button(self, self.gui.share_mode) @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') + CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) @pytest.mark.run(order=23) def test_web_page(self): - CommonTests.test_web_page(self, 'share', 'Total size', True) + CommonTests.test_web_page(self, self.gui.share_mode, 'Total size', True) @pytest.mark.run(order=24) def test_download_share(self): @@ -174,11 +170,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=25) def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'share') + CommonTests.test_history_widgets_present(self, self.gui.share_mode) @pytest.mark.run(order=26) def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', False) + CommonTests.test_server_is_stopped(self, self.gui.share_mode, False) @pytest.mark.run(order=27) def test_web_service_is_stopped(self): @@ -186,7 +182,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=28) def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', False) + CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, False) @pytest.mark.run(order=29) def test_add_button_visible(self): @@ -194,9 +190,9 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=30) def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - CommonTests.test_a_server_is_started(self, 'share') - CommonTests.test_history_indicator(self, 'share', True) + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) + CommonTests.test_a_server_is_started(self, self.gui.share_mode) + CommonTests.test_history_indicator(self, self.gui.share_mode, True) if __name__ == "__main__": From c316be91f0d1daa5a4f1f5ae17c4e497556db066 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 20:37:54 -0700 Subject: [PATCH 054/142] Refactor CommonTests to pass in actual Mode objects, and fix all tests. Now all ShareMode tests pass --- tests_gui_local/commontests.py | 2 +- .../onionshare_receive_mode_upload_test.py | 36 ++++++++-------- ...re_receive_mode_upload_test_public_mode.py | 36 ++++++++-------- .../onionshare_share_mode_download_test.py | 38 ++++++++--------- ...hare_share_mode_download_test_stay_open.py | 42 +++++++++---------- .../onionshare_slug_persistent_test.py | 38 ++++++++--------- tests_gui_local/onionshare_timer_test.py | 18 ++++---- 7 files changed, 97 insertions(+), 113 deletions(-) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/commontests.py index 5ceee668..d311c7bb 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/commontests.py @@ -171,7 +171,7 @@ class CommonTests(object): def test_counter_incremented(self, mode, count): '''Test that the counter has incremented''' - self.assertEquals(mode.uploads_completed, count) + self.assertEquals(mode.history.completed_count, count) def test_server_is_stopped(self, mode, stay_open): '''Test that the server stops when we click Stop''' diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index 19674aa3..1ce91ba2 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -96,27 +96,27 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=6) def test_click_mode(self): - CommonTests.test_click_mode(self, 'receive') + CommonTests.test_click_mode(self, self.gui.receive_mode) @pytest.mark.run(order=6) def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'receive') + CommonTests.test_history_is_not_visible(self, self.gui.receive_mode) @pytest.mark.run(order=7) def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'receive') + CommonTests.test_click_toggle_history(self, self.gui.receive_mode) @pytest.mark.run(order=8) def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'receive') + CommonTests.test_history_is_visible(self, self.gui.receive_mode) @pytest.mark.run(order=8) def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'receive') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) @pytest.mark.run(order=9) def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'receive') + CommonTests.test_server_status_indicator_says_starting(self, self.gui.receive_mode) @pytest.mark.run(order=10) def test_settings_button_is_hidden(self): @@ -124,7 +124,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=11) def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'receive') + CommonTests.test_a_server_is_started(self, self.gui.receive_mode) @pytest.mark.run(order=12) def test_a_web_server_is_running(self): @@ -132,23 +132,23 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=14) def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'receive', False) + CommonTests.test_have_a_slug(self, self.gui.receive_mode, False) @pytest.mark.run(order=15) def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'receive') + CommonTests.test_url_description_shown(self, self.gui.receive_mode) @pytest.mark.run(order=16) def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'receive') + CommonTests.test_have_copy_url_button(self, self.gui.receive_mode) @pytest.mark.run(order=17) def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'receive') + CommonTests.test_server_status_indicator_says_started(self, self.gui.receive_mode) @pytest.mark.run(order=18) def test_web_page(self): - CommonTests.test_web_page(self, 'receive', 'Select the files you want to send, then click', False) + CommonTests.test_web_page(self, self.gui.receive_mode, 'Select the files you want to send, then click', False) @pytest.mark.run(order=19) def test_upload_file(self): @@ -156,11 +156,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=20) def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'receive') + CommonTests.test_history_widgets_present(self, self.gui.receive_mode) @pytest.mark.run(order=21) def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, 'receive', 1) + CommonTests.test_counter_incremented(self, self.gui.receive_mode, 1) @pytest.mark.run(order=22) def test_upload_same_file_is_renamed(self): @@ -168,15 +168,15 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=23) def test_upload_count_incremented_again(self): - CommonTests.test_counter_incremented(self, 'receive', 2) + CommonTests.test_counter_incremented(self, self.gui.receive_mode, 2) @pytest.mark.run(order=24) def test_history_indicator(self): - CommonTests.test_history_indicator(self, 'receive', False) + CommonTests.test_history_indicator(self, self.gui.receive_mode, False) @pytest.mark.run(order=25) def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'receive', False) + CommonTests.test_server_is_stopped(self, self.gui.receive_mode, False) @pytest.mark.run(order=26) def test_web_service_is_stopped(self): @@ -184,7 +184,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=27) def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) + CommonTests.test_server_status_indicator_says_closed(self, self.gui.receive_mode, False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py index e3f85731..6591a884 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py @@ -96,27 +96,27 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=5) def test_click_mode(self): - CommonTests.test_click_mode(self, 'receive') + CommonTests.test_click_mode(self, self.gui.receive_mode) @pytest.mark.run(order=6) def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'receive') + CommonTests.test_history_is_not_visible(self, self.gui.receive_mode) @pytest.mark.run(order=7) def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'receive') + CommonTests.test_click_toggle_history(self, self.gui.receive_mode) @pytest.mark.run(order=8) def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'receive') + CommonTests.test_history_is_visible(self, self.gui.receive_mode) @pytest.mark.run(order=9) def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'receive') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) @pytest.mark.run(order=10) def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'receive') + CommonTests.test_server_status_indicator_says_starting(self, self.gui.receive_mode) @pytest.mark.run(order=11) def test_settings_button_is_hidden(self): @@ -124,7 +124,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=12) def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'receive') + CommonTests.test_a_server_is_started(self, self.gui.receive_mode) @pytest.mark.run(order=13) def test_a_web_server_is_running(self): @@ -132,23 +132,23 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=14) def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'receive', True) + CommonTests.test_have_a_slug(self, self.gui.receive_mode, True) @pytest.mark.run(order=15) def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'receive') + CommonTests.test_url_description_shown(self, self.gui.receive_mode) @pytest.mark.run(order=16) def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'receive') + CommonTests.test_have_copy_url_button(self, self.gui.receive_mode) @pytest.mark.run(order=17) def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'receive') + CommonTests.test_server_status_indicator_says_started(self, self.gui.receive_mode) @pytest.mark.run(order=18) def test_web_page(self): - CommonTests.test_web_page(self, 'receive', 'Select the files you want to send, then click', True) + CommonTests.test_web_page(self, self.gui.receive_mode, 'Select the files you want to send, then click', True) @pytest.mark.run(order=19) def test_upload_file(self): @@ -156,11 +156,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=20) def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'receive') + CommonTests.test_history_widgets_present(self, self.gui.receive_mode) @pytest.mark.run(order=21) def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, 'receive', 1) + CommonTests.test_counter_incremented(self, self.gui.receive_mode, 1) @pytest.mark.run(order=22) def test_upload_same_file_is_renamed(self): @@ -168,15 +168,15 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=23) def test_upload_count_incremented_again(self): - CommonTests.test_counter_incremented(self, 'receive', 2) + CommonTests.test_counter_incremented(self, self.gui.receive_mode, 2) @pytest.mark.run(order=24) def test_history_indicator(self): - CommonTests.test_history_indicator(self, 'receive', True) + CommonTests.test_history_indicator(self, self.gui.receive_mode, True) @pytest.mark.run(order=25) def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'receive', False) + CommonTests.test_server_is_stopped(self, self.gui.receive_mode, False) @pytest.mark.run(order=26) def test_web_service_is_stopped(self): @@ -184,7 +184,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=27) def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) + CommonTests.test_server_status_indicator_says_closed(self, self.gui.receive_mode, False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index c4a60101..6842f1a6 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -96,21 +96,17 @@ class OnionShareGuiTest(unittest.TestCase): def test_file_selection_widget_has_a_file(self): CommonTests.test_file_selection_widget_has_a_file(self) - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - @pytest.mark.run(order=7) def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') + CommonTests.test_history_is_not_visible(self, self.gui.share_mode) @pytest.mark.run(order=8) def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') + CommonTests.test_click_toggle_history(self, self.gui.share_mode) @pytest.mark.run(order=9) def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') + CommonTests.test_history_is_visible(self, self.gui.share_mode) @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): @@ -126,11 +122,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') + CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): @@ -142,7 +138,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=17) def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_a_server_is_started(self, self.gui.share_mode) @pytest.mark.run(order=18) def test_a_web_server_is_running(self): @@ -150,23 +146,23 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=19) def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) + CommonTests.test_have_a_slug(self, self.gui.share_mode, False) @pytest.mark.run(order=20) def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') + CommonTests.test_url_description_shown(self, self.gui.share_mode) @pytest.mark.run(order=21) def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') + CommonTests.test_have_copy_url_button(self, self.gui.share_mode) @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') + CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) @pytest.mark.run(order=23) def test_web_page(self): - CommonTests.test_web_page(self, 'share', 'Total size', False) + CommonTests.test_web_page(self, self.gui.share_mode, 'Total size', False) @pytest.mark.run(order=24) def test_download_share(self): @@ -174,11 +170,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=25) def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'share') + CommonTests.test_history_widgets_present(self, self.gui.share_mode) @pytest.mark.run(order=26) def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', False) + CommonTests.test_server_is_stopped(self, self.gui.share_mode, False) @pytest.mark.run(order=27) def test_web_service_is_stopped(self): @@ -186,7 +182,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=28) def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', False) + CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, False) @pytest.mark.run(order=29) def test_add_button_visible(self): @@ -194,9 +190,9 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=30) def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - CommonTests.test_a_server_is_started(self, 'share') - CommonTests.test_history_indicator(self, 'share', False) + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) + CommonTests.test_a_server_is_started(self, self.gui.share_mode) + CommonTests.test_history_indicator(self, self.gui.share_mode, False) if __name__ == "__main__": diff --git a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py index 8426c264..df9bc857 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py +++ b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py @@ -96,21 +96,17 @@ class OnionShareGuiTest(unittest.TestCase): def test_file_selection_widget_has_a_file(self): CommonTests.test_file_selection_widget_has_a_file(self) - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - @pytest.mark.run(order=7) def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') + CommonTests.test_history_is_not_visible(self, self.gui.share_mode) @pytest.mark.run(order=8) def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') + CommonTests.test_click_toggle_history(self, self.gui.share_mode) @pytest.mark.run(order=9) def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') + CommonTests.test_history_is_visible(self, self.gui.share_mode) @pytest.mark.run(order=10) def test_deleting_only_file_hides_delete_button(self): @@ -126,11 +122,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=13) def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) @pytest.mark.run(order=14) def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') + CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) @pytest.mark.run(order=15) def test_add_delete_buttons_hidden(self): @@ -142,7 +138,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=17) def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_a_server_is_started(self, self.gui.share_mode) @pytest.mark.run(order=18) def test_a_web_server_is_running(self): @@ -150,23 +146,23 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=19) def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', True) + CommonTests.test_have_a_slug(self, self.gui.share_mode, True) @pytest.mark.run(order=20) def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') + CommonTests.test_url_description_shown(self, self.gui.share_mode) @pytest.mark.run(order=21) def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') + CommonTests.test_have_copy_url_button(self, self.gui.share_mode) @pytest.mark.run(order=22) def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') + CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) @pytest.mark.run(order=23) def test_web_page(self): - CommonTests.test_web_page(self, 'share', 'Total size', True) + CommonTests.test_web_page(self, self.gui.share_mode, 'Total size', True) @pytest.mark.run(order=24) def test_download_share(self): @@ -174,11 +170,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=25) def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'share') + CommonTests.test_history_widgets_present(self, self.gui.share_mode) @pytest.mark.run(order=26) def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, 'share', 1) + CommonTests.test_counter_incremented(self, self.gui.share_mode, 1) @pytest.mark.run(order=27) def test_download_share_again(self): @@ -186,11 +182,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=28) def test_counter_incremented_again(self): - CommonTests.test_counter_incremented(self, 'share', 2) + CommonTests.test_counter_incremented(self, self.gui.share_mode, 2) @pytest.mark.run(order=29) def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', True) + CommonTests.test_server_is_stopped(self, self.gui.share_mode, True) @pytest.mark.run(order=30) def test_web_service_is_stopped(self): @@ -198,7 +194,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=31) def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', True) + CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, True) @pytest.mark.run(order=32) def test_add_button_visible(self): @@ -206,9 +202,9 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=33) def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - CommonTests.test_a_server_is_started(self, 'share') - CommonTests.test_history_indicator(self, 'share', True) + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) + CommonTests.test_a_server_is_started(self, self.gui.share_mode) + CommonTests.test_history_indicator(self, self.gui.share_mode, True) if __name__ == "__main__": diff --git a/tests_gui_local/onionshare_slug_persistent_test.py b/tests_gui_local/onionshare_slug_persistent_test.py index 9fb623dd..5b825dad 100644 --- a/tests_gui_local/onionshare_slug_persistent_test.py +++ b/tests_gui_local/onionshare_slug_persistent_test.py @@ -94,29 +94,25 @@ class OnionShareGuiTest(unittest.TestCase): def test_server_status_bar_is_visible(self): CommonTests.test_server_status_bar_is_visible(self) - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - @pytest.mark.run(order=7) def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') + CommonTests.test_history_is_not_visible(self, self.gui.share_mode) @pytest.mark.run(order=8) def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') + CommonTests.test_click_toggle_history(self, self.gui.share_mode) @pytest.mark.run(order=9) def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') + CommonTests.test_history_is_visible(self, self.gui.share_mode) @pytest.mark.run(order=10) def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) @pytest.mark.run(order=11) def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') + CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) @pytest.mark.run(order=12) def test_settings_button_is_hidden(self): @@ -124,7 +120,7 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=13) def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_a_server_is_started(self, self.gui.share_mode) @pytest.mark.run(order=14) def test_a_web_server_is_running(self): @@ -132,17 +128,17 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=15) def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) + CommonTests.test_have_a_slug(self, self.gui.share_mode, False) global slug slug = self.gui.share_mode.server_status.web.slug @pytest.mark.run(order=16) def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') + CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) @pytest.mark.run(order=17) def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', True) + CommonTests.test_server_is_stopped(self, self.gui.share_mode, True) @pytest.mark.run(order=18) def test_web_service_is_stopped(self): @@ -150,13 +146,13 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=19) def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', True) + CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, True) @pytest.mark.run(order=20) def test_server_started_again(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - CommonTests.test_server_status_indicator_says_starting(self, 'share') - CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) + CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) + CommonTests.test_a_server_is_started(self, self.gui.share_mode) @pytest.mark.run(order=21) def test_have_same_slug(self): @@ -165,14 +161,14 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=22) def test_server_is_stopped_again(self): - CommonTests.test_server_is_stopped(self, 'share', True) + CommonTests.test_server_is_stopped(self, self.gui.share_mode, True) CommonTests.test_web_service_is_stopped(self) @pytest.mark.run(order=23) def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - CommonTests.test_a_server_is_started(self, 'share') - CommonTests.test_history_indicator(self, 'share', False) + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) + CommonTests.test_a_server_is_started(self, self.gui.share_mode) + CommonTests.test_history_indicator(self, self.gui.share_mode, False) if __name__ == "__main__": diff --git a/tests_gui_local/onionshare_timer_test.py b/tests_gui_local/onionshare_timer_test.py index 701d9a21..4aaaf364 100644 --- a/tests_gui_local/onionshare_timer_test.py +++ b/tests_gui_local/onionshare_timer_test.py @@ -96,29 +96,25 @@ class OnionShareGuiTest(unittest.TestCase): def test_file_selection_widget_has_a_file(self): CommonTests.test_file_selection_widget_has_a_file(self) - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - @pytest.mark.run(order=7) def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') + CommonTests.test_history_is_not_visible(self, self.gui.share_mode) @pytest.mark.run(order=8) def test_set_timeout(self): - CommonTests.test_set_timeout(self, 'share', 5) + CommonTests.test_set_timeout(self, self.gui.share_mode, 5) @pytest.mark.run(order=9) def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') + CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) @pytest.mark.run(order=10) def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') + CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) @pytest.mark.run(order=11) def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') + CommonTests.test_a_server_is_started(self, self.gui.share_mode) @pytest.mark.run(order=12) def test_a_web_server_is_running(self): @@ -126,11 +122,11 @@ class OnionShareGuiTest(unittest.TestCase): @pytest.mark.run(order=13) def test_timeout_widget_hidden(self): - CommonTests.test_timeout_widget_hidden(self, 'share') + CommonTests.test_timeout_widget_hidden(self, self.gui.share_mode) @pytest.mark.run(order=14) def test_timeout(self): - CommonTests.test_server_timed_out(self, 'share', 10000) + CommonTests.test_server_timed_out(self, self.gui.share_mode, 10000) @pytest.mark.run(order=15) def test_web_service_is_stopped(self): From 38e7738543feccdf4bf0bae38fa556f45f84f96b Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 21:14:20 -0700 Subject: [PATCH 055/142] Update ReceiveMode to use History directly, and now all GUI tests pass --- onionshare_gui/mode/history.py | 182 +++++++++ onionshare_gui/mode/receive_mode/__init__.py | 97 ++--- onionshare_gui/mode/receive_mode/uploads.py | 395 ------------------- 3 files changed, 234 insertions(+), 440 deletions(-) delete mode 100644 onionshare_gui/mode/receive_mode/uploads.py diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index 0f8ccdca..4f5b2cef 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -18,6 +18,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ import time +import subprocess +from datetime import datetime from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings @@ -103,6 +105,186 @@ class DownloadHistoryItem(HistoryItem): self.started) +class UploadHistoryItemFile(QtWidgets.QWidget): + def __init__(self, common, filename): + super(UploadHistoryItemFile, self).__init__() + self.common = common + + self.common.log('UploadHistoryItemFile', '__init__', 'filename: {}'.format(filename)) + + self.filename = filename + self.started = datetime.now() + + # Filename label + self.filename_label = QtWidgets.QLabel(self.filename) + self.filename_label_width = self.filename_label.width() + + # File size label + self.filesize_label = QtWidgets.QLabel() + self.filesize_label.setStyleSheet(self.common.css['receive_file_size']) + self.filesize_label.hide() + + # Folder button + folder_pixmap = QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/open_folder.png'))) + folder_icon = QtGui.QIcon(folder_pixmap) + self.folder_button = QtWidgets.QPushButton() + self.folder_button.clicked.connect(self.open_folder) + self.folder_button.setIcon(folder_icon) + self.folder_button.setIconSize(folder_pixmap.rect().size()) + self.folder_button.setFlat(True) + self.folder_button.hide() + + # Layouts + layout = QtWidgets.QHBoxLayout() + layout.addWidget(self.filename_label) + layout.addWidget(self.filesize_label) + layout.addStretch() + layout.addWidget(self.folder_button) + self.setLayout(layout) + + def update(self, uploaded_bytes, complete): + self.filesize_label.setText(self.common.human_readable_filesize(uploaded_bytes)) + self.filesize_label.show() + + if complete: + self.folder_button.show() + + def rename(self, new_filename): + self.filename = new_filename + self.filename_label.setText(self.filename) + + def open_folder(self): + """ + Open the downloads folder, with the file selected, in a cross-platform manner + """ + self.common.log('UploadHistoryItemFile', 'open_folder') + + abs_filename = os.path.join(self.common.settings.get('downloads_dir'), self.filename) + + # Linux + if self.common.platform == 'Linux' or self.common.platform == 'BSD': + try: + # If nautilus is available, open it + subprocess.Popen(['nautilus', abs_filename]) + except: + Alert(self.common, strings._('gui_open_folder_error_nautilus').format(abs_filename)) + + # macOS + elif self.common.platform == 'Darwin': + # TODO: Implement opening folder with file selected in macOS + # This seems helpful: https://stackoverflow.com/questions/3520493/python-show-in-finder + self.common.log('UploadHistoryItemFile', 'open_folder', 'not implemented for Darwin yet') + + # Windows + elif self.common.platform == 'Windows': + # TODO: Implement opening folder with file selected in Windows + # This seems helpful: https://stackoverflow.com/questions/6631299/python-opening-a-folder-in-explorer-nautilus-mac-thingie + self.common.log('UploadHistoryItemFile', 'open_folder', 'not implemented for Windows yet') + + +class UploadHistoryItem(HistoryItem): + def __init__(self, common, id, content_length): + super(UploadHistoryItem, self).__init__() + self.common = common + self.id = id + self.content_length = content_length + self.started = datetime.now() + + # Label + self.label = QtWidgets.QLabel(strings._('gui_upload_in_progress', True).format(self.started.strftime("%b %d, %I:%M%p"))) + + # Progress bar + self.progress_bar = QtWidgets.QProgressBar() + self.progress_bar.setTextVisible(True) + self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) + self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) + self.progress_bar.setMinimum(0) + self.progress_bar.setValue(0) + self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar']) + + # This layout contains file widgets + self.files_layout = QtWidgets.QVBoxLayout() + self.files_layout.setContentsMargins(0, 0, 0, 0) + files_widget = QtWidgets.QWidget() + files_widget.setStyleSheet(self.common.css['receive_file']) + files_widget.setLayout(self.files_layout) + + # Layout + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.label) + layout.addWidget(self.progress_bar) + layout.addWidget(files_widget) + layout.addStretch() + self.setLayout(layout) + + # We're also making a dictionary of file widgets, to make them easier to access + self.files = {} + + def update(self, data): + """ + Using the progress from Web, update the progress bar and file size labels + for each file + """ + if data['action'] == 'progress': + total_uploaded_bytes = 0 + for filename in data['progress']: + total_uploaded_bytes += data['progress'][filename]['uploaded_bytes'] + + # Update the progress bar + self.progress_bar.setMaximum(self.content_length) + self.progress_bar.setValue(total_uploaded_bytes) + + elapsed = datetime.now() - self.started + if elapsed.seconds < 10: + pb_fmt = strings._('gui_download_upload_progress_starting').format( + self.common.human_readable_filesize(total_uploaded_bytes)) + else: + estimated_time_remaining = self.common.estimated_time_remaining( + total_uploaded_bytes, + self.content_length, + self.started.timestamp()) + pb_fmt = strings._('gui_download_upload_progress_eta').format( + self.common.human_readable_filesize(total_uploaded_bytes), + estimated_time_remaining) + + # Using list(progress) to avoid "RuntimeError: dictionary changed size during iteration" + for filename in list(data['progress']): + # Add a new file if needed + if filename not in self.files: + self.files[filename] = UploadHistoryItemFile(self.common, filename) + self.files_layout.addWidget(self.files[filename]) + + # Update the file + self.files[filename].update(data['progress'][filename]['uploaded_bytes'], data['progress'][filename]['complete']) + + elif data['action'] == 'rename': + self.files[data['old_filename']].rename(data['new_filename']) + self.files[data['new_filename']] = self.files.pop(data['old_filename']) + + elif data['action'] == 'finished': + # Hide the progress bar + self.progress_bar.hide() + + # Change the label + self.ended = self.started = datetime.now() + if self.started.year == self.ended.year and self.started.month == self.ended.month and self.started.day == self.ended.day: + if self.started.hour == self.ended.hour and self.started.minute == self.ended.minute: + text = strings._('gui_upload_finished', True).format( + self.started.strftime("%b %d, %I:%M%p") + ) + else: + text = strings._('gui_upload_finished_range', True).format( + self.started.strftime("%b %d, %I:%M%p"), + self.ended.strftime("%I:%M%p") + ) + else: + text = strings._('gui_upload_finished_range', True).format( + self.started.strftime("%b %d, %I:%M%p"), + self.ended.strftime("%b %d, %I:%M%p") + ) + self.label.setText(text) + + class HistoryItemList(QtWidgets.QScrollArea): """ List of items diff --git a/onionshare_gui/mode/receive_mode/__init__.py b/onionshare_gui/mode/receive_mode/__init__.py index 96c76dbf..ffa259e7 100644 --- a/onionshare_gui/mode/receive_mode/__init__.py +++ b/onionshare_gui/mode/receive_mode/__init__.py @@ -22,8 +22,7 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.web import Web -from .uploads import Uploads -from .info import ReceiveModeInfo +from ..history import History, ToggleHistory, UploadHistoryItem from .. import Mode class ReceiveMode(Mode): @@ -47,26 +46,36 @@ class ReceiveMode(Mode): self.server_status.web = self.web self.server_status.update() - # Uploads - self.uploads = Uploads(self.common) - self.uploads.hide() - self.uploads_in_progress = 0 - self.uploads_completed = 0 - self.new_upload = False # For scrolling to the bottom of the uploads list + # Upload history + self.history = History( + self.common, + QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/uploads_transparent.png'))), + strings._('gui_no_uploads'), + strings._('gui_uploads') + ) + self.history.hide() - # Information about share, and show uploads button - self.info = ReceiveModeInfo(self.common, self) - self.info.show_less() + # Toggle history + self.toggle_history = ToggleHistory( + self.common, self, self.history, + QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')), + QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle_selected.png')) + ) - # Receive mode info - self.receive_info = QtWidgets.QLabel(strings._('gui_receive_mode_warning', True)) - self.receive_info.setMinimumHeight(80) - self.receive_info.setWordWrap(True) + # Receive mode warning + receive_warning = QtWidgets.QLabel(strings._('gui_receive_mode_warning', True)) + receive_warning.setMinimumHeight(80) + receive_warning.setWordWrap(True) + + # Top bar + top_bar_layout = QtWidgets.QHBoxLayout() + top_bar_layout.addStretch() + top_bar_layout.addWidget(self.toggle_history) # Main layout self.main_layout = QtWidgets.QVBoxLayout() - self.main_layout.addWidget(self.info) - self.main_layout.addWidget(self.receive_info) + self.main_layout.addLayout(top_bar_layout) + self.main_layout.addWidget(receive_warning) self.main_layout.addWidget(self.primary_action) self.main_layout.addStretch() self.main_layout.addWidget(self.min_width_widget) @@ -74,7 +83,7 @@ class ReceiveMode(Mode): # Wrapper layout self.wrapper_layout = QtWidgets.QHBoxLayout() self.wrapper_layout.addLayout(self.main_layout) - self.wrapper_layout.addWidget(self.uploads) + self.wrapper_layout.addWidget(self.history) self.setLayout(self.wrapper_layout) def get_stop_server_shutdown_timeout_text(self): @@ -114,7 +123,7 @@ class ReceiveMode(Mode): Connection to Tor broke. """ self.primary_action.hide() - self.info.show_less() + #self.info.show_less() def handle_request_load(self, event): """ @@ -126,10 +135,11 @@ class ReceiveMode(Mode): """ Handle REQUEST_STARTED event. """ - self.uploads.add(event["data"]["id"], event["data"]["content_length"]) - self.info.update_indicator(True) - self.uploads_in_progress += 1 - self.info.update_uploads_in_progress() + item = UploadHistoryItem(self.common, event["data"]["id"], event["data"]["content_length"]) + self.history.add(event["data"]["id"], item) + self.toggle_history.update_indicator(True) + self.history.in_progress_count += 1 + self.history.update_in_progress() self.system_tray.showMessage(strings._('systray_upload_started_title', True), strings._('systray_upload_started_message', True)) @@ -137,7 +147,10 @@ class ReceiveMode(Mode): """ Handle REQUEST_PROGRESS event. """ - self.uploads.update(event["data"]["id"], event["data"]["progress"]) + self.history.update(event["data"]["id"], { + 'action': 'progress', + 'progress': event["data"]["progress"] + }) def handle_request_close_server(self, event): """ @@ -150,51 +163,45 @@ class ReceiveMode(Mode): """ Handle REQUEST_UPLOAD_FILE_RENAMED event. """ - self.uploads.rename(event["data"]["id"], event["data"]["old_filename"], event["data"]["new_filename"]) + self.history.update(event["data"]["id"], { + 'action': 'rename', + 'old_filename': event["data"]["old_filename"], + 'new_filename': event["data"]["new_filename"] + }) def handle_request_upload_finished(self, event): """ Handle REQUEST_UPLOAD_FINISHED event. """ - self.uploads.finished(event["data"]["id"]) - # Update the total 'completed uploads' info - self.uploads_completed += 1 - self.info.update_uploads_completed() - # Update the 'in progress uploads' info - self.uploads_in_progress -= 1 - self.info.update_uploads_in_progress() + self.history.update(event["data"]["id"], { + 'action': 'finished' + }) + self.history.completed_count += 1 + self.history.in_progress_count -= 1 + self.history.update_completed() + self.history.update_in_progress() def on_reload_settings(self): """ We should be ok to re-enable the 'Start Receive Mode' button now. """ self.primary_action.show() - self.info.show_more() + #self.info.show_more() def reset_info_counters(self): """ Set the info counters back to zero. """ - self.uploads_completed = 0 - self.uploads_in_progress = 0 - self.info.update_uploads_completed() - self.info.update_uploads_in_progress() - self.uploads.reset() + self.history.reset() def update_primary_action(self): self.common.log('ReceiveMode', 'update_primary_action') - # Show the info widget when the server is active - if self.server_status.status == self.server_status.STATUS_STARTED: - self.info.show_more() - else: - self.info.show_less() - # Resize window self.resize_window() def resize_window(self): min_width = self.common.min_window_width - if self.uploads.isVisible(): + if self.history.isVisible(): min_width += 300 self.adjust_size.emit(min_width) diff --git a/onionshare_gui/mode/receive_mode/uploads.py b/onionshare_gui/mode/receive_mode/uploads.py deleted file mode 100644 index c445be47..00000000 --- a/onionshare_gui/mode/receive_mode/uploads.py +++ /dev/null @@ -1,395 +0,0 @@ -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2014-2018 Micah Lee - -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 . -""" -import os -import subprocess -import textwrap -from datetime import datetime -from PyQt5 import QtCore, QtWidgets, QtGui - -from onionshare import strings -from ...widgets import Alert - - -class File(QtWidgets.QWidget): - def __init__(self, common, filename): - super(File, self).__init__() - self.common = common - - self.common.log('File', '__init__', 'filename: {}'.format(filename)) - - self.filename = filename - self.started = datetime.now() - - # Filename label - self.filename_label = QtWidgets.QLabel(self.filename) - self.filename_label_width = self.filename_label.width() - - # File size label - self.filesize_label = QtWidgets.QLabel() - self.filesize_label.setStyleSheet(self.common.css['receive_file_size']) - self.filesize_label.hide() - - # Folder button - folder_pixmap = QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/open_folder.png'))) - folder_icon = QtGui.QIcon(folder_pixmap) - self.folder_button = QtWidgets.QPushButton() - self.folder_button.clicked.connect(self.open_folder) - self.folder_button.setIcon(folder_icon) - self.folder_button.setIconSize(folder_pixmap.rect().size()) - self.folder_button.setFlat(True) - self.folder_button.hide() - - # Layouts - layout = QtWidgets.QHBoxLayout() - layout.addWidget(self.filename_label) - layout.addWidget(self.filesize_label) - layout.addStretch() - layout.addWidget(self.folder_button) - self.setLayout(layout) - - def update(self, uploaded_bytes, complete): - self.filesize_label.setText(self.common.human_readable_filesize(uploaded_bytes)) - self.filesize_label.show() - - if complete: - self.folder_button.show() - - def rename(self, new_filename): - self.filename = new_filename - self.filename_label.setText(self.filename) - - def open_folder(self): - """ - Open the downloads folder, with the file selected, in a cross-platform manner - """ - self.common.log('File', 'open_folder') - - abs_filename = os.path.join(self.common.settings.get('downloads_dir'), self.filename) - - # Linux - if self.common.platform == 'Linux' or self.common.platform == 'BSD': - try: - # If nautilus is available, open it - subprocess.Popen(['nautilus', abs_filename]) - except: - Alert(self.common, strings._('gui_open_folder_error_nautilus').format(abs_filename)) - - # macOS - elif self.common.platform == 'Darwin': - # TODO: Implement opening folder with file selected in macOS - # This seems helpful: https://stackoverflow.com/questions/3520493/python-show-in-finder - self.common.log('File', 'open_folder', 'not implemented for Darwin yet') - - # Windows - elif self.common.platform == 'Windows': - # TODO: Implement opening folder with file selected in Windows - # This seems helpful: https://stackoverflow.com/questions/6631299/python-opening-a-folder-in-explorer-nautilus-mac-thingie - self.common.log('File', 'open_folder', 'not implemented for Windows yet') - - -class Upload(QtWidgets.QWidget): - def __init__(self, common, upload_id, content_length): - super(Upload, self).__init__() - self.common = common - self.upload_id = upload_id - self.content_length = content_length - self.started = datetime.now() - - # Label - self.label = QtWidgets.QLabel(strings._('gui_upload_in_progress', True).format(self.started.strftime("%b %d, %I:%M%p"))) - - # Progress bar - self.progress_bar = QtWidgets.QProgressBar() - self.progress_bar.setTextVisible(True) - self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) - self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) - self.progress_bar.setMinimum(0) - self.progress_bar.setValue(0) - self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar']) - - # This layout contains file widgets - self.files_layout = QtWidgets.QVBoxLayout() - self.files_layout.setContentsMargins(0, 0, 0, 0) - files_widget = QtWidgets.QWidget() - files_widget.setStyleSheet(self.common.css['receive_file']) - files_widget.setLayout(self.files_layout) - - # Layout - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.label) - layout.addWidget(self.progress_bar) - layout.addWidget(files_widget) - layout.addStretch() - self.setLayout(layout) - - # We're also making a dictionary of file widgets, to make them easier to access - self.files = {} - - def update(self, progress): - """ - Using the progress from Web, update the progress bar and file size labels - for each file - """ - total_uploaded_bytes = 0 - for filename in progress: - total_uploaded_bytes += progress[filename]['uploaded_bytes'] - - # Update the progress bar - self.progress_bar.setMaximum(self.content_length) - self.progress_bar.setValue(total_uploaded_bytes) - - elapsed = datetime.now() - self.started - if elapsed.seconds < 10: - pb_fmt = strings._('gui_download_upload_progress_starting').format( - self.common.human_readable_filesize(total_uploaded_bytes)) - else: - estimated_time_remaining = self.common.estimated_time_remaining( - total_uploaded_bytes, - self.content_length, - self.started.timestamp()) - pb_fmt = strings._('gui_download_upload_progress_eta').format( - self.common.human_readable_filesize(total_uploaded_bytes), - estimated_time_remaining) - - # Using list(progress) to avoid "RuntimeError: dictionary changed size during iteration" - for filename in list(progress): - # Add a new file if needed - if filename not in self.files: - self.files[filename] = File(self.common, filename) - self.files_layout.addWidget(self.files[filename]) - - # Update the file - self.files[filename].update(progress[filename]['uploaded_bytes'], progress[filename]['complete']) - - def rename(self, old_filename, new_filename): - self.files[old_filename].rename(new_filename) - self.files[new_filename] = self.files.pop(old_filename) - - def finished(self): - # Hide the progress bar - self.progress_bar.hide() - - # Change the label - self.ended = self.started = datetime.now() - if self.started.year == self.ended.year and self.started.month == self.ended.month and self.started.day == self.ended.day: - if self.started.hour == self.ended.hour and self.started.minute == self.ended.minute: - text = strings._('gui_upload_finished', True).format( - self.started.strftime("%b %d, %I:%M%p") - ) - else: - text = strings._('gui_upload_finished_range', True).format( - self.started.strftime("%b %d, %I:%M%p"), - self.ended.strftime("%I:%M%p") - ) - else: - text = strings._('gui_upload_finished_range', True).format( - self.started.strftime("%b %d, %I:%M%p"), - self.ended.strftime("%b %d, %I:%M%p") - ) - self.label.setText(text) - - -class UploadList(QtWidgets.QScrollArea): - """ - List of upload progess bars. - """ - def __init__(self, common): - super(UploadList, self).__init__() - self.common = common - - self.uploads = {} - - # The layout that holds all of the uploads - self.uploads_layout = QtWidgets.QVBoxLayout() - self.uploads_layout.setContentsMargins(0, 0, 0, 0) - self.uploads_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) - - # Wrapper layout that also contains a stretch - wrapper_layout = QtWidgets.QVBoxLayout() - wrapper_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) - wrapper_layout.addLayout(self.uploads_layout) - wrapper_layout.addStretch() - - # The internal widget of the scroll area - widget = QtWidgets.QWidget() - widget.setLayout(wrapper_layout) - self.setWidget(widget) - self.setWidgetResizable(True) - - # Other scroll area settings - self.setBackgroundRole(QtGui.QPalette.Light) - self.verticalScrollBar().rangeChanged.connect(self.resizeScroll) - - def resizeScroll(self, minimum, maximum): - """ - Scroll to the bottom of the window when the range changes. - """ - self.verticalScrollBar().setValue(maximum) - - def add(self, upload_id, content_length): - """ - Add a new upload progress bar. - """ - upload = Upload(self.common, upload_id, content_length) - self.uploads[upload_id] = upload - self.uploads_layout.addWidget(upload) - - def update(self, upload_id, progress): - """ - Update the progress of an upload. - """ - self.uploads[upload_id].update(progress) - - def rename(self, upload_id, old_filename, new_filename): - """ - Rename a file, which happens if the filename already exists in downloads_dir. - """ - self.uploads[upload_id].rename(old_filename, new_filename) - - def finished(self, upload_id): - """ - An upload has finished. - """ - self.uploads[upload_id].finished() - - def cancel(self, upload_id): - """ - Update an upload progress bar to show that it has been canceled. - """ - self.common.log('Uploads', 'cancel', 'upload_id: {}'.format(upload_id)) - self.uploads[upload_id].cancel() - - def reset(self): - """ - Reset the uploads back to zero - """ - for upload in self.uploads.values(): - self.uploads_layout.removeWidget(upload) - upload.progress_bar.close() - self.uploads = {} - - -class Uploads(QtWidgets.QWidget): - """ - The uploads chunk of the GUI. This lists all of the active upload - progress bars, as well as information about each upload. - """ - def __init__(self, common): - super(Uploads, self).__init__() - self.common = common - self.common.log('Uploads', '__init__') - - self.setMinimumWidth(350) - - # When there are no uploads - empty_image = QtWidgets.QLabel() - empty_image.setAlignment(QtCore.Qt.AlignCenter) - empty_image.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/uploads_transparent.png')))) - empty_text = QtWidgets.QLabel(strings._('gui_no_uploads', True)) - empty_text.setAlignment(QtCore.Qt.AlignCenter) - empty_text.setStyleSheet(self.common.css['downloads_uploads_empty_text']) - empty_layout = QtWidgets.QVBoxLayout() - empty_layout.addStretch() - empty_layout.addWidget(empty_image) - empty_layout.addWidget(empty_text) - empty_layout.addStretch() - self.empty = QtWidgets.QWidget() - self.empty.setStyleSheet(self.common.css['downloads_uploads_empty']) - self.empty.setLayout(empty_layout) - - # When there are uploads - self.upload_list = UploadList(self.common) - - # Upload header - uploads_label = QtWidgets.QLabel(strings._('gui_uploads', True)) - uploads_label.setStyleSheet(self.common.css['downloads_uploads_label']) - clear_button = QtWidgets.QPushButton(strings._('gui_clear_history', True)) - clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) - clear_button.setFlat(True) - clear_button.clicked.connect(self.reset) - upload_header = QtWidgets.QHBoxLayout() - upload_header.addWidget(uploads_label) - upload_header.addStretch() - upload_header.addWidget(clear_button) - - # Upload layout - not_empty_layout = QtWidgets.QVBoxLayout() - not_empty_layout.addLayout(upload_header) - not_empty_layout.addWidget(self.upload_list) - self.not_empty = QtWidgets.QWidget() - self.not_empty.setLayout(not_empty_layout) - - # Layout - layout = QtWidgets.QVBoxLayout() - layout.setContentsMargins(0, 0, 0, 0) - layout.addWidget(self.empty) - layout.addWidget(self.not_empty) - self.setLayout(layout) - - # Reset once at the beginning - self.reset() - - def add(self, upload_id, content_length): - """ - Add a new upload. - """ - self.common.log('Uploads', 'add', 'upload_id: {}, content_length: {}'.format(upload_id, content_length)) - - # Hide empty, show not empty - self.empty.hide() - self.not_empty.show() - - # Add it to the list - self.upload_list.add(upload_id, content_length) - - def update(self, upload_id, progress): - """ - Update the progress of an upload. - """ - self.upload_list.update(upload_id, progress) - - def rename(self, upload_id, old_filename, new_filename): - """ - Rename a file, which happens if the filename already exists in downloads_dir. - """ - self.upload_list.rename(upload_id, old_filename, new_filename) - - def finished(self, upload_id): - """ - An upload has finished. - """ - self.upload_list.finished(upload_id) - - def cancel(self, upload_id): - """ - Update an upload progress bar to show that it has been canceled. - """ - self.common.log('Uploads', 'cancel', 'upload_id: {}'.format(upload_id)) - self.upload_list.cancel(upload_id) - - def reset(self): - """ - Reset the uploads back to zero - """ - self.upload_list.reset() - - # Hide not empty, show empty - self.not_empty.hide() - self.empty.show() From 1cdbe4538ca2c4cccb0bcd7cfaed929f4cc03936 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 21:28:10 -0700 Subject: [PATCH 056/142] Remove obsolete ReceiveModeInfo file --- onionshare_gui/mode/receive_mode/info.py | 136 ----------------------- 1 file changed, 136 deletions(-) delete mode 100644 onionshare_gui/mode/receive_mode/info.py diff --git a/onionshare_gui/mode/receive_mode/info.py b/onionshare_gui/mode/receive_mode/info.py deleted file mode 100644 index c23f8496..00000000 --- a/onionshare_gui/mode/receive_mode/info.py +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2014-2018 Micah Lee - -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 . -""" -from PyQt5 import QtCore, QtWidgets, QtGui - -from onionshare import strings - - -class ReceiveModeInfo(QtWidgets.QWidget): - """ - Receive mode information widget - """ - def __init__(self, common, receive_mode): - super(ReceiveModeInfo, self).__init__() - self.common = common - self.receive_mode = receive_mode - - # In progress and completed labels - self.in_progress_uploads_count = QtWidgets.QLabel() - self.in_progress_uploads_count.setStyleSheet(self.common.css['mode_info_label']) - self.completed_uploads_count = QtWidgets.QLabel() - self.completed_uploads_count.setStyleSheet(self.common.css['mode_info_label']) - - # Toggle button - self.toggle_button = QtWidgets.QPushButton() - self.toggle_button.setDefault(False) - self.toggle_button.setFixedWidth(35) - self.toggle_button.setFixedHeight(30) - self.toggle_button.setFlat(True) - self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) - self.toggle_button.clicked.connect(self.toggle_uploads) - - # Keep track of indicator - self.indicator_count = 0 - self.indicator_label = QtWidgets.QLabel(parent=self.toggle_button) - self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) - self.update_indicator() - - # Layout - layout = QtWidgets.QHBoxLayout() - layout.addStretch() - layout.addWidget(self.in_progress_uploads_count) - layout.addWidget(self.completed_uploads_count) - layout.addWidget(self.toggle_button) - self.setLayout(layout) - - self.update_uploads_completed() - self.update_uploads_in_progress() - - def update_indicator(self, increment=False): - """ - Update the display of the indicator count. If increment is True, then - only increment the counter if Uploads is hidden. - """ - if increment and not self.receive_mode.uploads.isVisible(): - self.indicator_count += 1 - - self.indicator_label.setText("{}".format(self.indicator_count)) - - if self.indicator_count == 0: - self.indicator_label.hide() - else: - size = self.indicator_label.sizeHint() - self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) - self.indicator_label.show() - - def update_uploads_completed(self): - """ - Update the 'Uploads completed' info widget. - """ - if self.receive_mode.uploads_completed == 0: - image = self.common.get_resource_path('images/share_completed_none.png') - else: - image = self.common.get_resource_path('images/share_completed.png') - self.completed_uploads_count.setText(' {1:d}'.format(image, self.receive_mode.uploads_completed)) - self.completed_uploads_count.setToolTip(strings._('info_completed_uploads_tooltip', True).format(self.receive_mode.uploads_completed)) - - def update_uploads_in_progress(self): - """ - Update the 'Uploads in progress' info widget. - """ - if self.receive_mode.uploads_in_progress == 0: - image = self.common.get_resource_path('images/share_in_progress_none.png') - else: - image = self.common.get_resource_path('images/share_in_progress.png') - self.in_progress_uploads_count.setText(' {1:d}'.format(image, self.receive_mode.uploads_in_progress)) - self.in_progress_uploads_count.setToolTip(strings._('info_in_progress_uploads_tooltip', True).format(self.receive_mode.uploads_in_progress)) - - def toggle_uploads(self): - """ - Toggle showing and hiding the Uploads widget - """ - self.common.log('ReceiveModeInfo', 'toggle_uploads') - - if self.receive_mode.uploads.isVisible(): - self.receive_mode.uploads.hide() - self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle.png')) ) - self.toggle_button.setFlat(True) - else: - self.receive_mode.uploads.show() - self.toggle_button.setIcon( QtGui.QIcon(self.common.get_resource_path('images/uploads_toggle_selected.png')) ) - self.toggle_button.setFlat(False) - - # Reset the indicator count - self.indicator_count = 0 - self.update_indicator() - - self.receive_mode.resize_window() - - def show_less(self): - """ - Remove clutter widgets that aren't necessary. - """ - pass - - def show_more(self): - """ - Show all widgets. - """ - pass From bf56548e7e54dd4b232160fd39bc409bae7f8efb Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 21:46:16 -0700 Subject: [PATCH 057/142] Properly close items inside the item list, instead of just hiding them --- onionshare_gui/mode/history.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index 4f5b2cef..ff31e3a9 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -347,7 +347,7 @@ class HistoryItemList(QtWidgets.QScrollArea): """ for item in self.items.values(): self.items_layout.removeWidget(item) - item.hide() + item.close() self.items = {} From 331d7bf9c7afaaa1881f2a58a5e21b91467780cf Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 8 Oct 2018 10:59:11 +1100 Subject: [PATCH 058/142] adjust widget sizes when switching mode --- onionshare_gui/onionshare_gui.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 6a7eb63a..35088ebe 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -200,12 +200,14 @@ class OnionShareGui(QtWidgets.QMainWindow): self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.receive_mode.hide() + self.adjust_size(self.common.min_window_width) self.share_mode.show() else: self.share_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_selected_style']) self.share_mode.hide() + self.adjust_size(self.common.min_window_width) self.receive_mode.show() self.update_server_status_indicator() From 806766268548b4ca5e23c6386db7edc9f6d4b3fd Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 21:57:45 -0700 Subject: [PATCH 059/142] Missing imports --- onionshare_gui/mode/history.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index ff31e3a9..07121363 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -19,10 +19,12 @@ along with this program. If not, see . """ import time import subprocess +import os from datetime import datetime from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings +from ..widgets import Alert class HistoryItem(QtWidgets.QWidget): From d73acb125856016e540fac0132d37e856afa4918 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 22:07:19 -0700 Subject: [PATCH 060/142] Rip out all of the adjust size logic and let Qt just handle it --- onionshare_gui/mode/__init__.py | 25 +----------- onionshare_gui/mode/receive_mode/__init__.py | 9 ---- onionshare_gui/mode/share_mode/__init__.py | 9 ---- onionshare_gui/onionshare_gui.py | 43 +------------------- 4 files changed, 2 insertions(+), 84 deletions(-) diff --git a/onionshare_gui/mode/__init__.py b/onionshare_gui/mode/__init__.py index cfbb235b..0971ff32 100644 --- a/onionshare_gui/mode/__init__.py +++ b/onionshare_gui/mode/__init__.py @@ -36,7 +36,6 @@ class Mode(QtWidgets.QWidget): starting_server_step3 = QtCore.pyqtSignal() starting_server_error = QtCore.pyqtSignal(str) set_server_active = QtCore.pyqtSignal(bool) - adjust_size = QtCore.pyqtSignal(int) def __init__(self, common, qtapp, app, status_bar, server_status_label, system_tray, filenames=None, local_only=False): super(Mode, self).__init__() @@ -50,8 +49,6 @@ class Mode(QtWidgets.QWidget): self.filenames = filenames - self.setMinimumWidth(self.common.min_window_width) - # The web object gets created in init() self.web = None @@ -83,7 +80,7 @@ class Mode(QtWidgets.QWidget): # Hack to allow a minimum width on the main layout # Note: It's up to the downstream Mode to add this to its layout self.min_width_widget = QtWidgets.QWidget() - self.min_width_widget.setMinimumWidth(self.common.min_window_width) + self.min_width_widget.setMinimumWidth(600) def init(self): """ @@ -332,23 +329,3 @@ class Mode(QtWidgets.QWidget): Handle REQUEST_UPLOAD_FINISHED event. """ pass - - def resize_window(self): - """ - We call this to force the OnionShare window to resize itself to be smaller. - For this to do anything, the Mode needs to override it and call: - - self.adjust_size.emit(min_width) - - It can calculate min_width (the new minimum window width) based on what - widgets are visible. - """ - pass - - def show(self): - """ - Always resize the window after showing this Mode widget. - """ - super(Mode, self).show() - self.qtapp.processEvents() - self.resize_window() diff --git a/onionshare_gui/mode/receive_mode/__init__.py b/onionshare_gui/mode/receive_mode/__init__.py index ffa259e7..66e0bbe7 100644 --- a/onionshare_gui/mode/receive_mode/__init__.py +++ b/onionshare_gui/mode/receive_mode/__init__.py @@ -196,12 +196,3 @@ class ReceiveMode(Mode): def update_primary_action(self): self.common.log('ReceiveMode', 'update_primary_action') - - # Resize window - self.resize_window() - - def resize_window(self): - min_width = self.common.min_window_width - if self.history.isVisible(): - min_width += 300 - self.adjust_size.emit(min_width) diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py index 0bf094c0..b3d7c549 100644 --- a/onionshare_gui/mode/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -321,21 +321,12 @@ class ShareMode(Mode): self.primary_action.hide() self.info_label.hide() - # Resize window - self.resize_window() - def reset_info_counters(self): """ Set the info counters back to zero. """ self.history.reset() - def resize_window(self): - min_width = self.common.min_window_width - if self.history.isVisible(): - min_width += 300 - self.adjust_size.emit(min_width) - @staticmethod def _compute_total_size(filenames): total_size = 0 diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 35088ebe..9a71ae28 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -45,7 +45,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.common = common self.common.log('OnionShareGui', '__init__') - self.common.min_window_width = 460 + self.setMinimumWidth(700) self.onion = onion self.qtapp = qtapp @@ -133,7 +133,6 @@ class OnionShareGui(QtWidgets.QMainWindow): self.share_mode.server_status.url_copied.connect(self.copy_url) self.share_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) self.share_mode.set_server_active.connect(self.set_server_active) - self.share_mode.adjust_size.connect(self.adjust_size) # Receive mode self.receive_mode = ReceiveMode(self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray, None, self.local_only) @@ -148,7 +147,6 @@ class OnionShareGui(QtWidgets.QMainWindow): self.receive_mode.server_status.url_copied.connect(self.copy_url) self.receive_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) self.receive_mode.set_server_active.connect(self.set_server_active) - self.receive_mode.adjust_size.connect(self.adjust_size) self.update_mode_switcher() self.update_server_status_indicator() @@ -169,9 +167,6 @@ class OnionShareGui(QtWidgets.QMainWindow): self.setCentralWidget(central_widget) self.show() - # Adjust window size, to start with a minimum window width - self.adjust_size(self.common.min_window_width) - # The server isn't active yet self.set_server_active(False) @@ -200,14 +195,12 @@ class OnionShareGui(QtWidgets.QMainWindow): self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.receive_mode.hide() - self.adjust_size(self.common.min_window_width) self.share_mode.show() else: self.share_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_selected_style']) self.share_mode.hide() - self.adjust_size(self.common.min_window_width) self.receive_mode.show() self.update_server_status_indicator() @@ -450,40 +443,6 @@ class OnionShareGui(QtWidgets.QMainWindow): # Disable settings menu action when server is active self.settings_action.setEnabled(not active) - def adjust_size(self, min_width): - """ - Recursively adjust size on all widgets. min_width is the new minimum width - of the window. - """ - self.setMinimumWidth(min_width) - - def adjust_size_layout(layout): - count = layout.count() - for i in range(count): - item = layout.itemAt(i) - if item: - child_widget = item.widget() - if child_widget: - adjust_size_widget(child_widget) - child_layout = item.layout() - if child_layout: - adjust_size_layout(child_layout) - - def adjust_size_widget(widget): - layout = widget.layout() - if layout: - adjust_size_layout(layout) - widget.adjustSize() - - # Adjust sizes of each mode - for mode in [self.share_mode, self.receive_mode]: - self.qtapp.processEvents() - adjust_size_widget(mode) - - # Adjust window size - self.qtapp.processEvents() - self.adjustSize() - def closeEvent(self, e): self.common.log('OnionShareGui', 'closeEvent') try: From 9eec5f82f43837980994d22fb14b98ff9e605e44 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Sun, 7 Oct 2018 22:09:57 -0700 Subject: [PATCH 061/142] Remove one more reference to resize_window --- onionshare_gui/mode/history.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index 07121363..cf944aa0 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -548,5 +548,3 @@ class ToggleHistory(QtWidgets.QPushButton): # Reset the indicator count self.indicator_count = 0 self.update_indicator() - - self.current_mode.resize_window() From 93d21c6041a50a2f97b4e90b29380d96f7236f8b Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Tue, 9 Oct 2018 20:51:10 -0700 Subject: [PATCH 062/142] Set min width and height so everything always looks good, and change onion address to monospace font --- onionshare/common.py | 1 + onionshare_gui/onionshare_gui.py | 3 ++- onionshare_gui/server_status.py | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/onionshare/common.py b/onionshare/common.py index fb3b1e7a..96f9d2ad 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -211,6 +211,7 @@ class Common(object): color: #000000; padding: 10px; border: 1px solid #666666; + font-size: 12px; } """, diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 9a71ae28..3175f0f9 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -45,7 +45,8 @@ class OnionShareGui(QtWidgets.QMainWindow): self.common = common self.common.log('OnionShareGui', '__init__') - self.setMinimumWidth(700) + self.setMinimumWidth(820) + self.setMinimumHeight(530) self.onion = onion self.qtapp = qtapp diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 32135ca4..99aaa9f1 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -90,20 +90,20 @@ class ServerStatus(QtWidgets.QWidget): self.server_button.clicked.connect(self.server_button_clicked) # URL layout - url_font = QtGui.QFont() + url_font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont) self.url_description = QtWidgets.QLabel() self.url_description.setWordWrap(True) self.url_description.setMinimumHeight(50) self.url = QtWidgets.QLabel() self.url.setFont(url_font) self.url.setWordWrap(True) - self.url.setMinimumHeight(65) self.url.setMinimumSize(self.url.sizeHint()) self.url.setStyleSheet(self.common.css['server_status_url']) self.copy_url_button = QtWidgets.QPushButton(strings._('gui_copy_url', True)) self.copy_url_button.setFlat(True) self.copy_url_button.setStyleSheet(self.common.css['server_status_url_buttons']) + self.copy_url_button.setMinimumHeight(65) self.copy_url_button.clicked.connect(self.copy_url) self.copy_hidservauth_button = QtWidgets.QPushButton(strings._('gui_copy_hidservauth', True)) self.copy_hidservauth_button.setFlat(True) From acf40c4c26caa277a8108e81f5428f5b301829ec Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Tue, 9 Oct 2018 21:15:42 -0700 Subject: [PATCH 063/142] Actually, the window needs to be taller --- onionshare_gui/onionshare_gui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 3175f0f9..1e03bc3e 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -46,7 +46,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.common = common self.common.log('OnionShareGui', '__init__') self.setMinimumWidth(820) - self.setMinimumHeight(530) + self.setMinimumHeight(620) self.onion = onion self.qtapp = qtapp @@ -154,7 +154,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # Layouts contents_layout = QtWidgets.QVBoxLayout() - contents_layout.setContentsMargins(10, 10, 10, 10) + contents_layout.setContentsMargins(10, 0, 10, 0) contents_layout.addWidget(self.receive_mode) contents_layout.addWidget(self.share_mode) From 0f6ef3797f7f47910257d654b8015450ee9f3156 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Tue, 9 Oct 2018 21:18:26 -0700 Subject: [PATCH 064/142] Stop hiding the share mode info label when tor breaks --- onionshare_gui/mode/receive_mode/__init__.py | 1 - onionshare_gui/mode/share_mode/__init__.py | 1 - 2 files changed, 2 deletions(-) diff --git a/onionshare_gui/mode/receive_mode/__init__.py b/onionshare_gui/mode/receive_mode/__init__.py index 66e0bbe7..e312a55b 100644 --- a/onionshare_gui/mode/receive_mode/__init__.py +++ b/onionshare_gui/mode/receive_mode/__init__.py @@ -123,7 +123,6 @@ class ReceiveMode(Mode): Connection to Tor broke. """ self.primary_action.hide() - #self.info.show_less() def handle_request_load(self, event): """ diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py index b3d7c549..1c1f33ae 100644 --- a/onionshare_gui/mode/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -224,7 +224,6 @@ class ShareMode(Mode): Connection to Tor broke. """ self.primary_action.hide() - self.info_label.hide() def handle_request_load(self, event): """ From 84cafcbd3d28446fe474cc8a5a99d888a5ebe789 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Tue, 9 Oct 2018 21:49:05 -0700 Subject: [PATCH 065/142] Make the history indicator label circular again --- onionshare/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare/common.py b/onionshare/common.py index 96f9d2ad..cab1e747 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -287,7 +287,7 @@ class Common(object): font-weight: bold; font-size: 10px; padding: 2px; - border-radius: 8px; + border-radius: 7px; text-align: center; }""", From 3cf36c4531507bf5cc932a8e58f906faf3327292 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Tue, 9 Oct 2018 22:21:03 -0700 Subject: [PATCH 066/142] Add "download started" date/time to download history progress bars --- onionshare_gui/mode/history.py | 7 +++++-- share/locale/en.json | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index cf944aa0..8cfa0ed5 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -50,11 +50,13 @@ class DownloadHistoryItem(HistoryItem): self.common = common self.id = id - self.started = time.time() self.total_bytes = total_bytes self.downloaded_bytes = 0 + self.started = time.time() + self.started_dt = datetime.fromtimestamp(self.started) - self.setStyleSheet('QWidget { border: 1px solid red; }') + # Label + self.label = QtWidgets.QLabel(strings._('gui_download_in_progress').format(self.started_dt.strftime("%b %d, %I:%M%p"))) # Progress bar self.progress_bar = QtWidgets.QProgressBar() @@ -69,6 +71,7 @@ class DownloadHistoryItem(HistoryItem): # Layout layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.label) layout.addWidget(self.progress_bar) self.setLayout(layout) diff --git a/share/locale/en.json b/share/locale/en.json index 3537b0a2..e5d9a3be 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -180,5 +180,6 @@ "gui_upload_in_progress": "Upload Started {}", "gui_upload_finished_range": "Uploaded {} to {}", "gui_upload_finished": "Uploaded {}", + "gui_download_in_progress": "Download Started {}", "gui_open_folder_error_nautilus": "Cannot open folder because nautilus is not available. The file is here: {}" } From ff00007db3f19c0e60393800e1713aeafa60353a Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 10 Oct 2018 16:49:42 +1100 Subject: [PATCH 067/142] Raise minimumHeight again to account for overlap issues on MacOS caused by Mac's Qt widget padding --- onionshare_gui/onionshare_gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 1e03bc3e..e672d74e 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -46,7 +46,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.common = common self.common.log('OnionShareGui', '__init__') self.setMinimumWidth(820) - self.setMinimumHeight(620) + self.setMinimumHeight(650) self.onion = onion self.qtapp = qtapp From c02f6a9306bb54adf5213377c52bef3568031da1 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 10 Oct 2018 18:09:43 +1100 Subject: [PATCH 068/142] Remove commented out obsolete code --- onionshare_gui/mode/receive_mode/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/onionshare_gui/mode/receive_mode/__init__.py b/onionshare_gui/mode/receive_mode/__init__.py index e312a55b..b73acca2 100644 --- a/onionshare_gui/mode/receive_mode/__init__.py +++ b/onionshare_gui/mode/receive_mode/__init__.py @@ -185,7 +185,6 @@ class ReceiveMode(Mode): We should be ok to re-enable the 'Start Receive Mode' button now. """ self.primary_action.show() - #self.info.show_more() def reset_info_counters(self): """ From 6d448b7cde311c7886f405b0fc9f388cfdcfc47d Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Wed, 10 Oct 2018 18:16:08 -0700 Subject: [PATCH 069/142] Final few tweaks to make this look perfect in macOS --- onionshare_gui/mode/share_mode/file_selection.py | 3 ++- onionshare_gui/onionshare_gui.py | 2 +- onionshare_gui/server_status.py | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/onionshare_gui/mode/share_mode/file_selection.py b/onionshare_gui/mode/share_mode/file_selection.py index d59df234..6bfa7dbf 100644 --- a/onionshare_gui/mode/share_mode/file_selection.py +++ b/onionshare_gui/mode/share_mode/file_selection.py @@ -89,7 +89,7 @@ class FileList(QtWidgets.QListWidget): self.setAcceptDrops(True) self.setIconSize(QtCore.QSize(32, 32)) self.setSortingEnabled(True) - self.setMinimumHeight(205) + self.setMinimumHeight(160) self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.drop_here_image = DropHereLabel(self.common, self, True) self.drop_here_text = DropHereLabel(self.common, self, False) @@ -261,6 +261,7 @@ class FileList(QtWidgets.QListWidget): # Item info widget, with a white background item_info_layout = QtWidgets.QHBoxLayout() + item_info_layout.setContentsMargins(0, 0, 0, 0) item_info_layout.addWidget(item_size) item_info_layout.addWidget(item.item_button) item_info = QtWidgets.QWidget() diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index e672d74e..c2e6657b 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -46,7 +46,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.common = common self.common.log('OnionShareGui', '__init__') self.setMinimumWidth(820) - self.setMinimumHeight(650) + self.setMinimumHeight(660) self.onion = onion self.qtapp = qtapp diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 99aaa9f1..0267d826 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -142,12 +142,12 @@ class ServerStatus(QtWidgets.QWidget): When the widget is resized, try and adjust the display of a v3 onion URL. """ try: - self.get_url() + # Wrap the URL label url_length=len(self.get_url()) if url_length > 60: width = self.frameGeometry().width() if width < 530: - wrapped_onion_url = textwrap.fill(self.get_url(), 50) + wrapped_onion_url = textwrap.fill(self.get_url(), 46) self.url.setText(wrapped_onion_url) else: self.url.setText(self.get_url()) From 186a174e622c15be1689b9a2796cf946088639c5 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Wed, 10 Oct 2018 18:45:55 -0700 Subject: [PATCH 070/142] Fix various bugs so local GUI tests pass again after merges --- onionshare_gui/mode/history.py | 12 ++++++------ onionshare_gui/mode/receive_mode/__init__.py | 2 +- tests_gui_local/commontests.py | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index 8cfa0ed5..b446b9fb 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -196,7 +196,7 @@ class UploadHistoryItem(HistoryItem): self.started = datetime.now() # Label - self.label = QtWidgets.QLabel(strings._('gui_upload_in_progress', True).format(self.started.strftime("%b %d, %I:%M%p"))) + self.label = QtWidgets.QLabel(strings._('gui_upload_in_progress').format(self.started.strftime("%b %d, %I:%M%p"))) # Progress bar self.progress_bar = QtWidgets.QProgressBar() @@ -274,16 +274,16 @@ class UploadHistoryItem(HistoryItem): self.ended = self.started = datetime.now() if self.started.year == self.ended.year and self.started.month == self.ended.month and self.started.day == self.ended.day: if self.started.hour == self.ended.hour and self.started.minute == self.ended.minute: - text = strings._('gui_upload_finished', True).format( + text = strings._('gui_upload_finished').format( self.started.strftime("%b %d, %I:%M%p") ) else: - text = strings._('gui_upload_finished_range', True).format( + text = strings._('gui_upload_finished_range').format( self.started.strftime("%b %d, %I:%M%p"), self.ended.strftime("%I:%M%p") ) else: - text = strings._('gui_upload_finished_range', True).format( + text = strings._('gui_upload_finished_range').format( self.started.strftime("%b %d, %I:%M%p"), self.ended.strftime("%b %d, %I:%M%p") ) @@ -380,7 +380,7 @@ 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_clear_history', True)) + clear_button = QtWidgets.QPushButton(strings._('gui_clear_history')) clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) clear_button.setFlat(True) clear_button.clicked.connect(self.reset) @@ -486,7 +486,7 @@ class History(QtWidgets.QWidget): else: image = self.common.get_resource_path('images/share_in_progress.png') self.in_progress_label.setText(' {1:d}'.format(image, self.in_progress_count)) - self.in_progress_label.setToolTip(strings._('history_in_progress_tooltip', True).format(self.in_progress_count)) + self.in_progress_label.setToolTip(strings._('history_in_progress_tooltip').format(self.in_progress_count)) class ToggleHistory(QtWidgets.QPushButton): diff --git a/onionshare_gui/mode/receive_mode/__init__.py b/onionshare_gui/mode/receive_mode/__init__.py index d22dd149..f070f963 100644 --- a/onionshare_gui/mode/receive_mode/__init__.py +++ b/onionshare_gui/mode/receive_mode/__init__.py @@ -63,7 +63,7 @@ class ReceiveMode(Mode): ) # Receive mode warning - receive_warning = QtWidgets.QLabel(strings._('gui_receive_mode_warning', True)) + receive_warning = QtWidgets.QLabel(strings._('gui_receive_mode_warning')) receive_warning.setMinimumHeight(80) receive_warning.setWordWrap(True) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/commontests.py index c057386d..27e406c1 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/commontests.py @@ -14,6 +14,8 @@ from onionshare.settings import Settings from onionshare.onion import Onion 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 class CommonTests(object): @@ -236,7 +238,7 @@ class CommonTests(object): def test_server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' if type(mode) == ReceiveMode: - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped', True)) + self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped')) if type(mode) == ShareMode: if stay_open: self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped')) From af97c131bdc042180c88b82ccda245787de760ed Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 11 Oct 2018 15:09:27 +1100 Subject: [PATCH 071/142] Refactor local tests to reuse most of their code --- .../{commontests.py => GuiBaseTest.py} | 93 +++++++++++- tests_gui_local/__init__.py | 2 +- .../onionshare_receive_mode_upload_test.py | 117 +-------------- ...re_receive_mode_upload_test_public_mode.py | 117 +-------------- .../onionshare_share_mode_download_test.py | 129 +--------------- ...re_share_mode_download_test_public_mode.py | 129 ++-------------- ...hare_share_mode_download_test_stay_open.py | 142 ++---------------- .../onionshare_slug_persistent_test.py | 99 ++---------- tests_gui_local/onionshare_timer_test.py | 66 ++------ 9 files changed, 154 insertions(+), 740 deletions(-) rename tests_gui_local/{commontests.py => GuiBaseTest.py} (72%) diff --git a/tests_gui_local/commontests.py b/tests_gui_local/GuiBaseTest.py similarity index 72% rename from tests_gui_local/commontests.py rename to tests_gui_local/GuiBaseTest.py index 27e406c1..e7d25031 100644 --- a/tests_gui_local/commontests.py +++ b/tests_gui_local/GuiBaseTest.py @@ -18,7 +18,7 @@ from onionshare_gui.mode.share_mode import ShareMode from onionshare_gui.mode.receive_mode import ReceiveMode -class CommonTests(object): +class GuiBaseTest(object): @staticmethod def set_up(test_settings): '''Create GUI with given settings''' @@ -59,6 +59,7 @@ class CommonTests(object): except: pass + def test_gui_loaded(self): '''Test that the GUI actually is shown''' self.assertTrue(self.gui.show) @@ -168,7 +169,6 @@ class CommonTests(object): else: self.assertIsNone(mode.server_status.web.slug, r'(\w+)-(\w+)') - def test_url_description_shown(self, mode): '''Test that the URL label is showing''' self.assertTrue(mode.server_status.url_description.isVisible()) @@ -337,3 +337,92 @@ class CommonTests(object): def test_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()) + + + # The following are 'groupings' of tests used by other objects that inherit GuiBaseTest + + def run_all_common_setup_tests(self): + GuiBaseTest.test_gui_loaded(self) + GuiBaseTest.test_windowTitle_seen(self) + GuiBaseTest.test_settings_button_is_visible(self) + GuiBaseTest.test_server_status_bar_is_visible(self) + + def run_all_share_mode_setup_tests(self): + """Tests in share mode prior to starting a share""" + GuiBaseTest.test_click_mode(self, self.gui.share_mode) + GuiBaseTest.test_file_selection_widget_has_a_file(self) + GuiBaseTest.test_history_is_not_visible(self, self.gui.share_mode) + GuiBaseTest.test_click_toggle_history(self, self.gui.share_mode) + GuiBaseTest.test_history_is_visible(self, self.gui.share_mode) + GuiBaseTest.test_deleting_only_file_hides_delete_button(self) + GuiBaseTest.test_add_a_file_and_delete_using_its_delete_widget(self) + GuiBaseTest.test_file_selection_widget_readd_files(self) + + def run_all_share_mode_started_tests(self, public_mode): + """Tests in share mode after starting a share""" + GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.share_mode) + GuiBaseTest.test_server_status_indicator_says_starting(self, self.gui.share_mode) + GuiBaseTest.test_add_delete_buttons_hidden(self) + GuiBaseTest.test_settings_button_is_hidden(self) + GuiBaseTest.test_a_server_is_started(self, self.gui.share_mode) + GuiBaseTest.test_a_web_server_is_running(self) + GuiBaseTest.test_have_a_slug(self, self.gui.share_mode, public_mode) + GuiBaseTest.test_url_description_shown(self, self.gui.share_mode) + GuiBaseTest.test_have_copy_url_button(self, self.gui.share_mode) + GuiBaseTest.test_server_status_indicator_says_started(self, self.gui.share_mode) + GuiBaseTest.test_web_page(self, self.gui.share_mode, 'Total size', public_mode) + + def run_all_share_mode_download_tests(self, public_mode, stay_open): + """Tests in share mode after downloading a share""" + GuiBaseTest.test_download_share(self, public_mode) + GuiBaseTest.test_history_widgets_present(self, self.gui.share_mode) + GuiBaseTest.test_server_is_stopped(self, self.gui.share_mode, stay_open) + GuiBaseTest.test_web_service_is_stopped(self) + GuiBaseTest.test_server_status_indicator_says_closed(self, self.gui.share_mode, stay_open) + GuiBaseTest.test_add_button_visible(self) + GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.share_mode) + GuiBaseTest.test_a_server_is_started(self, self.gui.share_mode) + GuiBaseTest.test_history_indicator(self, self.gui.share_mode, public_mode) + + def run_all_share_mode_tests(self, public_mode, stay_open): + """End-to-end share tests""" + GuiBaseTest.run_all_share_mode_setup_tests(self) + GuiBaseTest.run_all_share_mode_started_tests(self, public_mode) + GuiBaseTest.run_all_share_mode_download_tests(self, public_mode, stay_open) + + def run_all_share_mode_timer_tests(self, public_mode): + """Auto-stop timer tests in share mode""" + GuiBaseTest.run_all_share_mode_setup_tests(self) + GuiBaseTest.test_set_timeout(self, self.gui.share_mode, 5) + GuiBaseTest.run_all_share_mode_started_tests(self, public_mode) + GuiBaseTest.test_timeout_widget_hidden(self, self.gui.share_mode) + GuiBaseTest.test_server_timed_out(self, self.gui.share_mode, 10000) + GuiBaseTest.test_web_service_is_stopped(self) + + def run_all_receive_mode_tests(self, public_mode, receive_allow_receiver_shutdown): + GuiBaseTest.test_click_mode(self, self.gui.receive_mode) + GuiBaseTest.test_history_is_not_visible(self, self.gui.receive_mode) + GuiBaseTest.test_click_toggle_history(self, self.gui.receive_mode) + GuiBaseTest.test_history_is_visible(self, self.gui.receive_mode) + GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) + GuiBaseTest.test_server_status_indicator_says_starting(self, self.gui.receive_mode) + GuiBaseTest.test_settings_button_is_hidden(self) + GuiBaseTest.test_a_server_is_started(self, self.gui.receive_mode) + GuiBaseTest.test_a_web_server_is_running(self) + GuiBaseTest.test_have_a_slug(self, self.gui.receive_mode, public_mode) + GuiBaseTest.test_url_description_shown(self, self.gui.receive_mode) + GuiBaseTest.test_have_copy_url_button(self, self.gui.receive_mode) + GuiBaseTest.test_server_status_indicator_says_started(self, self.gui.receive_mode) + GuiBaseTest.test_web_page(self, self.gui.receive_mode, 'Select the files you want to send, then click', public_mode) + GuiBaseTest.test_upload_file(self, public_mode, '/tmp/OnionShare/test.txt') + GuiBaseTest.test_history_widgets_present(self, self.gui.receive_mode) + GuiBaseTest.test_counter_incremented(self, self.gui.receive_mode, 1) + GuiBaseTest.test_upload_file(self, public_mode, '/tmp/OnionShare/test-2.txt') + GuiBaseTest.test_counter_incremented(self, self.gui.receive_mode, 2) + GuiBaseTest.test_history_indicator(self, self.gui.receive_mode, public_mode) + GuiBaseTest.test_server_is_stopped(self, self.gui.receive_mode, False) + GuiBaseTest.test_web_service_is_stopped(self) + GuiBaseTest.test_server_status_indicator_says_closed(self, self.gui.receive_mode, False) + GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) + GuiBaseTest.test_a_server_is_started(self, self.gui.receive_mode) + GuiBaseTest.test_history_indicator(self, self.gui.receive_mode, public_mode) diff --git a/tests_gui_local/__init__.py b/tests_gui_local/__init__.py index bb2b2182..7cf168eb 100644 --- a/tests_gui_local/__init__.py +++ b/tests_gui_local/__init__.py @@ -1 +1 @@ -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index 91013d92..262c7aba 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -12,128 +12,27 @@ from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest -class OnionShareGuiTest(unittest.TestCase): +class ReceiveModeTest(unittest.TestCase): @classmethod def setUpClass(cls): test_settings = { - "public_mode": False, "receive_allow_receiver_shutdown": True } - cls.gui = CommonTests.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): - CommonTests.tear_down() + GuiBaseTest.tear_down() @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) + def test_run_all_common_setup_tests(self): + GuiBaseTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=6) - def test_click_mode(self): - CommonTests.test_click_mode(self, self.gui.receive_mode) - - @pytest.mark.run(order=6) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, self.gui.receive_mode) - - @pytest.mark.run(order=7) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, self.gui.receive_mode) - - @pytest.mark.run(order=8) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, self.gui.receive_mode) - - @pytest.mark.run(order=8) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) - - @pytest.mark.run(order=9) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, self.gui.receive_mode) - - @pytest.mark.run(order=10) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=11) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, self.gui.receive_mode) - - @pytest.mark.run(order=12) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=14) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, self.gui.receive_mode, False) - - @pytest.mark.run(order=15) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, self.gui.receive_mode) - - @pytest.mark.run(order=16) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, self.gui.receive_mode) - - @pytest.mark.run(order=17) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, self.gui.receive_mode) - - @pytest.mark.run(order=18) - def test_web_page(self): - CommonTests.test_web_page(self, self.gui.receive_mode, 'Select the files you want to send, then click', False) - - @pytest.mark.run(order=19) - def test_upload_file(self): - CommonTests.test_upload_file(self, False, '/tmp/OnionShare/test.txt') - - @pytest.mark.run(order=20) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, self.gui.receive_mode) - - @pytest.mark.run(order=21) - def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, self.gui.receive_mode, 1) - - @pytest.mark.run(order=22) - def test_upload_same_file_is_renamed(self): - CommonTests.test_upload_file(self, False, '/tmp/OnionShare/test-2.txt') - - @pytest.mark.run(order=23) - def test_upload_count_incremented_again(self): - CommonTests.test_counter_incremented(self, self.gui.receive_mode, 2) - - @pytest.mark.run(order=24) - def test_history_indicator(self): - CommonTests.test_history_indicator(self, self.gui.receive_mode, False) - - @pytest.mark.run(order=25) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, self.gui.receive_mode, False) - - @pytest.mark.run(order=26) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=27) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, self.gui.receive_mode, False) + def test_run_all_share_mode_tests(self): + GuiBaseTest.run_all_receive_mode_tests(self, False, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py index 42f237c9..201402c2 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py @@ -8,133 +8,32 @@ import json from PyQt5 import QtWidgets from onionshare.common import Common -from onionshare.settings import Settings from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest -class OnionShareGuiTest(unittest.TestCase): +class ReceiveModePublicModeTest(unittest.TestCase): @classmethod def setUpClass(cls): test_settings = { "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = CommonTests.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): - CommonTests.tear_down() + GuiBaseTest.tear_down() @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) + def test_run_all_common_setup_tests(self): + GuiBaseTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_click_mode(self): - CommonTests.test_click_mode(self, self.gui.receive_mode) - - @pytest.mark.run(order=6) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, self.gui.receive_mode) - - @pytest.mark.run(order=7) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, self.gui.receive_mode) - - @pytest.mark.run(order=8) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, self.gui.receive_mode) - - @pytest.mark.run(order=9) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) - - @pytest.mark.run(order=10) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, self.gui.receive_mode) - - @pytest.mark.run(order=11) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=12) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, self.gui.receive_mode) - - @pytest.mark.run(order=13) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=14) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, self.gui.receive_mode, True) - - @pytest.mark.run(order=15) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, self.gui.receive_mode) - - @pytest.mark.run(order=16) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, self.gui.receive_mode) - - @pytest.mark.run(order=17) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, self.gui.receive_mode) - - @pytest.mark.run(order=18) - def test_web_page(self): - CommonTests.test_web_page(self, self.gui.receive_mode, 'Select the files you want to send, then click', True) - - @pytest.mark.run(order=19) - def test_upload_file(self): - CommonTests.test_upload_file(self, True, '/tmp/OnionShare/test.txt') - - @pytest.mark.run(order=20) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, self.gui.receive_mode) - - @pytest.mark.run(order=21) - def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, self.gui.receive_mode, 1) - - @pytest.mark.run(order=22) - def test_upload_same_file_is_renamed(self): - CommonTests.test_upload_file(self, True, '/tmp/OnionShare/test-2.txt') - - @pytest.mark.run(order=23) - def test_upload_count_incremented_again(self): - CommonTests.test_counter_incremented(self, self.gui.receive_mode, 2) - - @pytest.mark.run(order=24) - def test_history_indicator(self): - CommonTests.test_history_indicator(self, self.gui.receive_mode, True) - - @pytest.mark.run(order=25) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, self.gui.receive_mode, False) - - @pytest.mark.run(order=26) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=27) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, self.gui.receive_mode, False) + def test_run_all_share_mode_tests(self): + GuiBaseTest.run_all_receive_mode_tests(self, True, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index 9caad8b1..b24a3a78 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -12,139 +12,26 @@ from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest -class OnionShareGuiTest(unittest.TestCase): +class ShareModeTest(unittest.TestCase): @classmethod def setUpClass(cls): test_settings = { - "public_mode": False, - "close_after_first_download": True } - cls.gui = CommonTests.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): - CommonTests.tear_down() + GuiBaseTest.tear_down() @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) + def test_run_all_common_setup_tests(self): + GuiBaseTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, self.gui.share_mode) - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, self.gui.share_mode, False) - - @pytest.mark.run(order=20) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, self.gui.share_mode) - - @pytest.mark.run(order=21) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, self.gui.share_mode) - - @pytest.mark.run(order=22) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) - - @pytest.mark.run(order=23) - def test_web_page(self): - CommonTests.test_web_page(self, self.gui.share_mode, 'Total size', False) - - @pytest.mark.run(order=24) - def test_download_share(self): - CommonTests.test_download_share(self, False) - - @pytest.mark.run(order=25) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, self.gui.share_mode) - - @pytest.mark.run(order=26) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, self.gui.share_mode, False) - - @pytest.mark.run(order=27) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=28) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, False) - - @pytest.mark.run(order=29) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - @pytest.mark.run(order=30) - def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - CommonTests.test_history_indicator(self, self.gui.share_mode, False) - + def test_run_all_share_mode_tests(self): + GuiBaseTest.run_all_share_mode_tests(self, False, False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py index c7b05543..e59b53f4 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py +++ b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py @@ -12,138 +12,27 @@ from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest -class OnionShareGuiTest(unittest.TestCase): +class ShareModePublicModeTest(unittest.TestCase): @classmethod def setUpClass(cls): test_settings = { - "public_mode": True + "public_mode": True, } - cls.gui = CommonTests.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): - CommonTests.tear_down() + GuiBaseTest.tear_down() @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) + def test_run_all_common_setup_tests(self): + GuiBaseTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, self.gui.share_mode) - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, self.gui.share_mode, True) - - @pytest.mark.run(order=20) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, self.gui.share_mode) - - @pytest.mark.run(order=21) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, self.gui.share_mode) - - @pytest.mark.run(order=22) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) - - @pytest.mark.run(order=23) - def test_web_page(self): - CommonTests.test_web_page(self, self.gui.share_mode, 'Total size', True) - - @pytest.mark.run(order=24) - def test_download_share(self): - CommonTests.test_download_share(self, True) - - @pytest.mark.run(order=25) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, self.gui.share_mode) - - @pytest.mark.run(order=26) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, self.gui.share_mode, False) - - @pytest.mark.run(order=27) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=28) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, False) - - @pytest.mark.run(order=29) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - @pytest.mark.run(order=30) - def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - CommonTests.test_history_indicator(self, self.gui.share_mode, True) - + def test_run_all_share_mode_tests(self): + GuiBaseTest.run_all_share_mode_tests(self, True, False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py index 478177c0..9394c34a 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py +++ b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py @@ -12,151 +12,27 @@ from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest -class OnionShareGuiTest(unittest.TestCase): +class ShareModeStayOpenTest(unittest.TestCase): @classmethod def setUpClass(cls): test_settings = { - "public_mode": True, - "close_after_first_download": False + "close_after_first_download": False, } - cls.gui = CommonTests.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): - CommonTests.tear_down() + GuiBaseTest.tear_down() @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) + def test_run_all_common_setup_tests(self): + GuiBaseTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, self.gui.share_mode) - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, self.gui.share_mode, True) - - @pytest.mark.run(order=20) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, self.gui.share_mode) - - @pytest.mark.run(order=21) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, self.gui.share_mode) - - @pytest.mark.run(order=22) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) - - @pytest.mark.run(order=23) - def test_web_page(self): - CommonTests.test_web_page(self, self.gui.share_mode, 'Total size', True) - - @pytest.mark.run(order=24) - def test_download_share(self): - CommonTests.test_download_share(self, True) - - @pytest.mark.run(order=25) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, self.gui.share_mode) - - @pytest.mark.run(order=26) - def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, self.gui.share_mode, 1) - - @pytest.mark.run(order=27) - def test_download_share_again(self): - CommonTests.test_download_share(self, True) - - @pytest.mark.run(order=28) - def test_counter_incremented_again(self): - CommonTests.test_counter_incremented(self, self.gui.share_mode, 2) - - @pytest.mark.run(order=29) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, self.gui.share_mode, True) - - @pytest.mark.run(order=30) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=31) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, True) - - @pytest.mark.run(order=32) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - @pytest.mark.run(order=33) - def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - CommonTests.test_history_indicator(self, self.gui.share_mode, True) - + def test_run_all_share_mode_tests(self): + GuiBaseTest.run_all_share_mode_tests(self, False, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_slug_persistent_test.py b/tests_gui_local/onionshare_slug_persistent_test.py index f4139afb..ab845f8e 100644 --- a/tests_gui_local/onionshare_slug_persistent_test.py +++ b/tests_gui_local/onionshare_slug_persistent_test.py @@ -12,114 +12,37 @@ from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest -class OnionShareGuiTest(unittest.TestCase): +class ShareModePersistentSlugTest(unittest.TestCase): @classmethod def setUpClass(cls): test_settings = { "public_mode": False, "slug": "", - "save_private_key": True + "save_private_key": True, + "close_after_first_download": False, } - cls.gui = CommonTests.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): - CommonTests.tear_down() + GuiBaseTest.tear_down() @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) + def test_run_all_common_setup_tests(self): + GuiBaseTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, self.gui.share_mode) - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=10) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - - @pytest.mark.run(order=11) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) - - @pytest.mark.run(order=12) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=13) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - - @pytest.mark.run(order=14) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=15) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, self.gui.share_mode, False) + def test_run_all_share_mode_tests(self): + GuiBaseTest.run_all_share_mode_tests(self, False, True) global slug slug = self.gui.share_mode.server_status.web.slug - @pytest.mark.run(order=16) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, self.gui.share_mode) - - @pytest.mark.run(order=17) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, self.gui.share_mode, True) - - @pytest.mark.run(order=18) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=19) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, self.gui.share_mode, True) - - @pytest.mark.run(order=20) - def test_server_started_again(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - - @pytest.mark.run(order=21) + @pytest.mark.run(order=3) def test_have_same_slug(self): '''Test that we have the same slug''' self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) - @pytest.mark.run(order=22) - def test_server_is_stopped_again(self): - CommonTests.test_server_is_stopped(self, self.gui.share_mode, True) - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=23) - def test_history_indicator(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - CommonTests.test_history_indicator(self, self.gui.share_mode, False) - - if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_timer_test.py b/tests_gui_local/onionshare_timer_test.py index ef55886e..60c616cc 100644 --- a/tests_gui_local/onionshare_timer_test.py +++ b/tests_gui_local/onionshare_timer_test.py @@ -12,76 +12,28 @@ from onionshare.web import Web from onionshare import onion, strings from onionshare_gui import * -from .commontests import CommonTests +from .GuiBaseTest import GuiBaseTest -class OnionShareGuiTest(unittest.TestCase): +class ShareModeTimerTest(unittest.TestCase): @classmethod def setUpClass(cls): test_settings = { "public_mode": False, - "shutdown_timeout": True + "shutdown_timeout": True, } - cls.gui = CommonTests.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): - CommonTests.tear_down() + GuiBaseTest.tear_down() @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) + def test_run_all_common_setup_tests(self): + GuiBaseTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, self.gui.share_mode) - - @pytest.mark.run(order=8) - def test_set_timeout(self): - CommonTests.test_set_timeout(self, self.gui.share_mode, 5) - - @pytest.mark.run(order=9) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - - @pytest.mark.run(order=10) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, self.gui.share_mode) - - @pytest.mark.run(order=11) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, self.gui.share_mode) - - @pytest.mark.run(order=12) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=13) - def test_timeout_widget_hidden(self): - CommonTests.test_timeout_widget_hidden(self, self.gui.share_mode) - - @pytest.mark.run(order=14) - def test_timeout(self): - CommonTests.test_server_timed_out(self, self.gui.share_mode, 10000) - - @pytest.mark.run(order=15) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) + def test_run_all_share_mode_timer_tests(self): + GuiBaseTest.run_all_share_mode_timer_tests(self, False) if __name__ == "__main__": unittest.main() From cd6931ec8c6f2010b7c39ce117211f274987a7a6 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 11 Oct 2018 16:04:37 +1100 Subject: [PATCH 072/142] Try and move local tests into main tests dir. Rename local tests. Save test settings to unique json files to avoid race conditions --- .travis.yml | 3 +- {tests_gui_local => tests}/GuiBaseTest.py | 3 +- tests/__init__.py | 1 + .../local_receive_mode_public_mode_test.py | 2 +- .../local_receive_mode_test.py | 2 +- .../local_share_mode_persistent_slug_test.py | 10 +- .../local_share_mode_public_mode_test.py | 2 +- .../local_share_mode_stay_open_test.py | 2 +- .../local_share_mode_test.py | 2 +- .../local_share_mode_timer_test.py | 2 +- tests_gui_local/__init__.py | 1 - tests_gui_local/conftest.py | 160 ------------------ tests_gui_local/run_unit_tests.sh | 5 - 13 files changed, 14 insertions(+), 181 deletions(-) rename {tests_gui_local => tests}/GuiBaseTest.py (99%) rename tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py => tests/local_receive_mode_public_mode_test.py (90%) rename tests_gui_local/onionshare_receive_mode_upload_test.py => tests/local_receive_mode_test.py (91%) rename tests_gui_local/onionshare_slug_persistent_test.py => tests/local_share_mode_persistent_slug_test.py (81%) rename tests_gui_local/onionshare_share_mode_download_test_public_mode.py => tests/local_share_mode_public_mode_test.py (90%) rename tests_gui_local/onionshare_share_mode_download_test_stay_open.py => tests/local_share_mode_stay_open_test.py (90%) rename tests_gui_local/onionshare_share_mode_download_test.py => tests/local_share_mode_test.py (91%) rename tests_gui_local/onionshare_timer_test.py => tests/local_share_mode_timer_test.py (91%) delete mode 100644 tests_gui_local/__init__.py delete mode 100644 tests_gui_local/conftest.py delete mode 100755 tests_gui_local/run_unit_tests.sh diff --git a/.travis.yml b/.travis.yml index e0b5b822..24255416 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,5 +19,4 @@ before_script: - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics # run CLI tests and local GUI tests script: - - pytest --cov=onionshare tests/ - - cd tests_gui_local/ && xvfb-run ./run_unit_tests.sh + - xvfb-run pytest --cov=onionshare tests/ diff --git a/tests_gui_local/GuiBaseTest.py b/tests/GuiBaseTest.py similarity index 99% rename from tests_gui_local/GuiBaseTest.py rename to tests/GuiBaseTest.py index e7d25031..7aec97f7 100644 --- a/tests_gui_local/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -20,7 +20,7 @@ from onionshare_gui.mode.receive_mode import ReceiveMode class GuiBaseTest(object): @staticmethod - def set_up(test_settings): + def set_up(test_settings, settings_filename='/tmp/testsettings.json'): '''Create GUI with given settings''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -45,7 +45,6 @@ class GuiBaseTest(object): app = OnionShare(common, testonion, True, 0) web = Web(common, False, True) - settings_filename = '/tmp/testsettings.json' open(settings_filename, 'w').write(json.dumps(test_settings)) gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], settings_filename, True) diff --git a/tests/__init__.py b/tests/__init__.py index e69de29b..1def7f5e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1 @@ +from .GuiBaseTest import GuiBaseTest diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests/local_receive_mode_public_mode_test.py similarity index 90% rename from tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py rename to tests/local_receive_mode_public_mode_test.py index 201402c2..0bc00833 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ b/tests/local_receive_mode_public_mode_test.py @@ -21,7 +21,7 @@ class ReceiveModePublicModeTest(unittest.TestCase): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ReceiveModePublicModeTest.json') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests/local_receive_mode_test.py similarity index 91% rename from tests_gui_local/onionshare_receive_mode_upload_test.py rename to tests/local_receive_mode_test.py index 262c7aba..82d7529a 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests/local_receive_mode_test.py @@ -20,7 +20,7 @@ class ReceiveModeTest(unittest.TestCase): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ReceiveModeTest.json') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_slug_persistent_test.py b/tests/local_share_mode_persistent_slug_test.py similarity index 81% rename from tests_gui_local/onionshare_slug_persistent_test.py rename to tests/local_share_mode_persistent_slug_test.py index ab845f8e..cad01ed9 100644 --- a/tests_gui_local/onionshare_slug_persistent_test.py +++ b/tests/local_share_mode_persistent_slug_test.py @@ -23,23 +23,23 @@ class ShareModePersistentSlugTest(unittest.TestCase): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModePersistentSlugTest.json') @classmethod def tearDownClass(cls): GuiBaseTest.tear_down() - @pytest.mark.run(order=1) + @pytest.mark.run(order=1000) def test_run_all_common_setup_tests(self): GuiBaseTest.run_all_common_setup_tests(self) - @pytest.mark.run(order=2) - def test_run_all_share_mode_tests(self): + @pytest.mark.run(order=1001) + def test_run_all_persistent_share_mode_tests(self): GuiBaseTest.run_all_share_mode_tests(self, False, True) global slug slug = self.gui.share_mode.server_status.web.slug - @pytest.mark.run(order=3) + @pytest.mark.run(order=1002) def test_have_same_slug(self): '''Test that we have the same slug''' self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) diff --git a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py b/tests/local_share_mode_public_mode_test.py similarity index 90% rename from tests_gui_local/onionshare_share_mode_download_test_public_mode.py rename to tests/local_share_mode_public_mode_test.py index e59b53f4..2aa3caea 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py +++ b/tests/local_share_mode_public_mode_test.py @@ -20,7 +20,7 @@ class ShareModePublicModeTest(unittest.TestCase): test_settings = { "public_mode": True, } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModePublicModeTest.json') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py b/tests/local_share_mode_stay_open_test.py similarity index 90% rename from tests_gui_local/onionshare_share_mode_download_test_stay_open.py rename to tests/local_share_mode_stay_open_test.py index 9394c34a..0a2db984 100644 --- a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py +++ b/tests/local_share_mode_stay_open_test.py @@ -20,7 +20,7 @@ class ShareModeStayOpenTest(unittest.TestCase): test_settings = { "close_after_first_download": False, } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModeStayOpenTest.json') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests/local_share_mode_test.py similarity index 91% rename from tests_gui_local/onionshare_share_mode_download_test.py rename to tests/local_share_mode_test.py index b24a3a78..ca1bed2c 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests/local_share_mode_test.py @@ -19,7 +19,7 @@ class ShareModeTest(unittest.TestCase): def setUpClass(cls): test_settings = { } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModeTest.json') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_timer_test.py b/tests/local_share_mode_timer_test.py similarity index 91% rename from tests_gui_local/onionshare_timer_test.py rename to tests/local_share_mode_timer_test.py index 60c616cc..ffa138a6 100644 --- a/tests_gui_local/onionshare_timer_test.py +++ b/tests/local_share_mode_timer_test.py @@ -21,7 +21,7 @@ class ShareModeTimerTest(unittest.TestCase): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModeTimerTest.json') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/__init__.py b/tests_gui_local/__init__.py deleted file mode 100644 index 7cf168eb..00000000 --- a/tests_gui_local/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .GuiBaseTest import GuiBaseTest diff --git a/tests_gui_local/conftest.py b/tests_gui_local/conftest.py deleted file mode 100644 index 8ac7efb8..00000000 --- a/tests_gui_local/conftest.py +++ /dev/null @@ -1,160 +0,0 @@ -import sys -# Force tests to look for resources in the source code tree -sys.onionshare_dev_mode = True - -import os -import shutil -import tempfile - -import pytest - -from onionshare import common, web, settings - -@pytest.fixture -def temp_dir_1024(): - """ Create a temporary directory that has a single file of a - particular size (1024 bytes). - """ - - tmp_dir = tempfile.mkdtemp() - tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) - with open(tmp_file, 'wb') as f: - f.write(b'*' * 1024) - return tmp_dir - - -# pytest > 2.9 only needs @pytest.fixture -@pytest.yield_fixture -def temp_dir_1024_delete(): - """ Create a temporary directory that has a single file of a - particular size (1024 bytes). The temporary directory (including - the file inside) will be deleted after fixture usage. - """ - - with tempfile.TemporaryDirectory() as tmp_dir: - tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) - with open(tmp_file, 'wb') as f: - f.write(b'*' * 1024) - yield tmp_dir - - -@pytest.fixture -def temp_file_1024(): - """ Create a temporary file of a particular size (1024 bytes). """ - - with tempfile.NamedTemporaryFile(delete=False) 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(): - """ - Create a temporary file of a particular size (1024 bytes). - The temporary file will be deleted after fixture usage. - """ - - with tempfile.NamedTemporaryFile() as tmp_file: - 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) - shutil.rmtree(tmp_dir) - - -@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' - return settings.Settings(_common) diff --git a/tests_gui_local/run_unit_tests.sh b/tests_gui_local/run_unit_tests.sh deleted file mode 100755 index 7d207a57..00000000 --- a/tests_gui_local/run_unit_tests.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -for test in `ls -1 | egrep ^onionshare_`; do - pytest $test -vvv || exit 1 -done From bc90b7de93407166a8d90d3b71e05880fe6193d4 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 11 Oct 2018 16:07:16 +1100 Subject: [PATCH 073/142] Revert "Try and move local tests into main tests dir. Rename local tests. Save test settings to unique json files to avoid race conditions" This reverts commit cd6931ec8c6f2010b7c39ce117211f274987a7a6. --- .travis.yml | 3 +- tests/__init__.py | 1 - {tests => tests_gui_local}/GuiBaseTest.py | 3 +- tests_gui_local/__init__.py | 1 + tests_gui_local/conftest.py | 160 ++++++++++++++++++ .../onionshare_receive_mode_upload_test.py | 2 +- ...re_receive_mode_upload_test_public_mode.py | 2 +- .../onionshare_share_mode_download_test.py | 2 +- ...re_share_mode_download_test_public_mode.py | 2 +- ...hare_share_mode_download_test_stay_open.py | 2 +- .../onionshare_slug_persistent_test.py | 10 +- .../onionshare_timer_test.py | 2 +- tests_gui_local/run_unit_tests.sh | 5 + 13 files changed, 181 insertions(+), 14 deletions(-) rename {tests => tests_gui_local}/GuiBaseTest.py (99%) create mode 100644 tests_gui_local/__init__.py create mode 100644 tests_gui_local/conftest.py rename tests/local_receive_mode_test.py => tests_gui_local/onionshare_receive_mode_upload_test.py (91%) rename tests/local_receive_mode_public_mode_test.py => tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py (90%) rename tests/local_share_mode_test.py => tests_gui_local/onionshare_share_mode_download_test.py (91%) rename tests/local_share_mode_public_mode_test.py => tests_gui_local/onionshare_share_mode_download_test_public_mode.py (90%) rename tests/local_share_mode_stay_open_test.py => tests_gui_local/onionshare_share_mode_download_test_stay_open.py (90%) rename tests/local_share_mode_persistent_slug_test.py => tests_gui_local/onionshare_slug_persistent_test.py (81%) rename tests/local_share_mode_timer_test.py => tests_gui_local/onionshare_timer_test.py (91%) create mode 100755 tests_gui_local/run_unit_tests.sh diff --git a/.travis.yml b/.travis.yml index 24255416..e0b5b822 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,4 +19,5 @@ before_script: - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics # run CLI tests and local GUI tests script: - - xvfb-run pytest --cov=onionshare tests/ + - pytest --cov=onionshare tests/ + - cd tests_gui_local/ && xvfb-run ./run_unit_tests.sh diff --git a/tests/__init__.py b/tests/__init__.py index 1def7f5e..e69de29b 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +0,0 @@ -from .GuiBaseTest import GuiBaseTest diff --git a/tests/GuiBaseTest.py b/tests_gui_local/GuiBaseTest.py similarity index 99% rename from tests/GuiBaseTest.py rename to tests_gui_local/GuiBaseTest.py index 7aec97f7..e7d25031 100644 --- a/tests/GuiBaseTest.py +++ b/tests_gui_local/GuiBaseTest.py @@ -20,7 +20,7 @@ from onionshare_gui.mode.receive_mode import ReceiveMode class GuiBaseTest(object): @staticmethod - def set_up(test_settings, settings_filename='/tmp/testsettings.json'): + def set_up(test_settings): '''Create GUI with given settings''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -45,6 +45,7 @@ class GuiBaseTest(object): app = OnionShare(common, testonion, True, 0) web = Web(common, False, True) + settings_filename = '/tmp/testsettings.json' open(settings_filename, 'w').write(json.dumps(test_settings)) gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], settings_filename, True) diff --git a/tests_gui_local/__init__.py b/tests_gui_local/__init__.py new file mode 100644 index 00000000..7cf168eb --- /dev/null +++ b/tests_gui_local/__init__.py @@ -0,0 +1 @@ +from .GuiBaseTest import GuiBaseTest diff --git a/tests_gui_local/conftest.py b/tests_gui_local/conftest.py new file mode 100644 index 00000000..8ac7efb8 --- /dev/null +++ b/tests_gui_local/conftest.py @@ -0,0 +1,160 @@ +import sys +# Force tests to look for resources in the source code tree +sys.onionshare_dev_mode = True + +import os +import shutil +import tempfile + +import pytest + +from onionshare import common, web, settings + +@pytest.fixture +def temp_dir_1024(): + """ Create a temporary directory that has a single file of a + particular size (1024 bytes). + """ + + tmp_dir = tempfile.mkdtemp() + tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) + with open(tmp_file, 'wb') as f: + f.write(b'*' * 1024) + return tmp_dir + + +# pytest > 2.9 only needs @pytest.fixture +@pytest.yield_fixture +def temp_dir_1024_delete(): + """ Create a temporary directory that has a single file of a + particular size (1024 bytes). The temporary directory (including + the file inside) will be deleted after fixture usage. + """ + + with tempfile.TemporaryDirectory() as tmp_dir: + tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) + with open(tmp_file, 'wb') as f: + f.write(b'*' * 1024) + yield tmp_dir + + +@pytest.fixture +def temp_file_1024(): + """ Create a temporary file of a particular size (1024 bytes). """ + + with tempfile.NamedTemporaryFile(delete=False) 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(): + """ + Create a temporary file of a particular size (1024 bytes). + The temporary file will be deleted after fixture usage. + """ + + with tempfile.NamedTemporaryFile() as tmp_file: + 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) + shutil.rmtree(tmp_dir) + + +@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' + return settings.Settings(_common) diff --git a/tests/local_receive_mode_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py similarity index 91% rename from tests/local_receive_mode_test.py rename to tests_gui_local/onionshare_receive_mode_upload_test.py index 82d7529a..262c7aba 100644 --- a/tests/local_receive_mode_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -20,7 +20,7 @@ class ReceiveModeTest(unittest.TestCase): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ReceiveModeTest.json') + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_receive_mode_public_mode_test.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py similarity index 90% rename from tests/local_receive_mode_public_mode_test.py rename to tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py index 0bc00833..201402c2 100644 --- a/tests/local_receive_mode_public_mode_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py @@ -21,7 +21,7 @@ class ReceiveModePublicModeTest(unittest.TestCase): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ReceiveModePublicModeTest.json') + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_share_mode_test.py b/tests_gui_local/onionshare_share_mode_download_test.py similarity index 91% rename from tests/local_share_mode_test.py rename to tests_gui_local/onionshare_share_mode_download_test.py index ca1bed2c..b24a3a78 100644 --- a/tests/local_share_mode_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -19,7 +19,7 @@ class ShareModeTest(unittest.TestCase): def setUpClass(cls): test_settings = { } - cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModeTest.json') + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_share_mode_public_mode_test.py b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py similarity index 90% rename from tests/local_share_mode_public_mode_test.py rename to tests_gui_local/onionshare_share_mode_download_test_public_mode.py index 2aa3caea..e59b53f4 100644 --- a/tests/local_share_mode_public_mode_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py @@ -20,7 +20,7 @@ class ShareModePublicModeTest(unittest.TestCase): test_settings = { "public_mode": True, } - cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModePublicModeTest.json') + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_share_mode_stay_open_test.py b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py similarity index 90% rename from tests/local_share_mode_stay_open_test.py rename to tests_gui_local/onionshare_share_mode_download_test_stay_open.py index 0a2db984..9394c34a 100644 --- a/tests/local_share_mode_stay_open_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py @@ -20,7 +20,7 @@ class ShareModeStayOpenTest(unittest.TestCase): test_settings = { "close_after_first_download": False, } - cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModeStayOpenTest.json') + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_share_mode_persistent_slug_test.py b/tests_gui_local/onionshare_slug_persistent_test.py similarity index 81% rename from tests/local_share_mode_persistent_slug_test.py rename to tests_gui_local/onionshare_slug_persistent_test.py index cad01ed9..ab845f8e 100644 --- a/tests/local_share_mode_persistent_slug_test.py +++ b/tests_gui_local/onionshare_slug_persistent_test.py @@ -23,23 +23,23 @@ class ShareModePersistentSlugTest(unittest.TestCase): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModePersistentSlugTest.json') + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): GuiBaseTest.tear_down() - @pytest.mark.run(order=1000) + @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): GuiBaseTest.run_all_common_setup_tests(self) - @pytest.mark.run(order=1001) - def test_run_all_persistent_share_mode_tests(self): + @pytest.mark.run(order=2) + def test_run_all_share_mode_tests(self): GuiBaseTest.run_all_share_mode_tests(self, False, True) global slug slug = self.gui.share_mode.server_status.web.slug - @pytest.mark.run(order=1002) + @pytest.mark.run(order=3) def test_have_same_slug(self): '''Test that we have the same slug''' self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) diff --git a/tests/local_share_mode_timer_test.py b/tests_gui_local/onionshare_timer_test.py similarity index 91% rename from tests/local_share_mode_timer_test.py rename to tests_gui_local/onionshare_timer_test.py index ffa138a6..60c616cc 100644 --- a/tests/local_share_mode_timer_test.py +++ b/tests_gui_local/onionshare_timer_test.py @@ -21,7 +21,7 @@ class ShareModeTimerTest(unittest.TestCase): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiBaseTest.set_up(test_settings, '/tmp/ShareModeTimerTest.json') + cls.gui = GuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/run_unit_tests.sh b/tests_gui_local/run_unit_tests.sh new file mode 100755 index 00000000..7d207a57 --- /dev/null +++ b/tests_gui_local/run_unit_tests.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +for test in `ls -1 | egrep ^onionshare_`; do + pytest $test -vvv || exit 1 +done From 70b50827c2cbfd548221a1296e242a60e6958854 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 11:28:47 +1100 Subject: [PATCH 074/142] Refactor tests to use proper inheritance of GuiReceiveTest/GuiShareTest (which inherit from GuiBaseTest). Prevent tests from auto-firing in these base objects. Clean up imported modules, rename files to end in _test.py --- tests_gui_local/GuiBaseTest.py | 260 ++++-------------- tests_gui_local/GuiReceiveTest.py | 45 +++ tests_gui_local/GuiShareTest.py | 154 +++++++++++ tests_gui_local/__init__.py | 1 - ...re_receive_mode_upload_public_mode_test.py | 29 ++ .../onionshare_receive_mode_upload_test.py | 26 +- ...re_receive_mode_upload_test_public_mode.py | 39 --- ...re_share_mode_download_public_mode_test.py | 28 ++ ...hare_share_mode_download_stay_open_test.py | 28 ++ .../onionshare_share_mode_download_test.py | 24 +- ...re_share_mode_download_test_public_mode.py | 38 --- ...hare_share_mode_download_test_stay_open.py | 38 --- ...nshare_share_mode_slug_persistent_test.py} | 24 +- .../onionshare_share_mode_timer_test.py | 29 ++ tests_gui_local/onionshare_timer_test.py | 39 --- 15 files changed, 389 insertions(+), 413 deletions(-) create mode 100644 tests_gui_local/GuiReceiveTest.py create mode 100644 tests_gui_local/GuiShareTest.py create mode 100644 tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py delete mode 100644 tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py create mode 100644 tests_gui_local/onionshare_share_mode_download_public_mode_test.py create mode 100644 tests_gui_local/onionshare_share_mode_download_stay_open_test.py delete mode 100644 tests_gui_local/onionshare_share_mode_download_test_public_mode.py delete mode 100644 tests_gui_local/onionshare_share_mode_download_test_stay_open.py rename tests_gui_local/{onionshare_slug_persistent_test.py => onionshare_share_mode_slug_persistent_test.py} (61%) create mode 100644 tests_gui_local/onionshare_share_mode_timer_test.py delete mode 100644 tests_gui_local/onionshare_timer_test.py diff --git a/tests_gui_local/GuiBaseTest.py b/tests_gui_local/GuiBaseTest.py index e7d25031..8a8b127e 100644 --- a/tests_gui_local/GuiBaseTest.py +++ b/tests_gui_local/GuiBaseTest.py @@ -1,10 +1,9 @@ +import json import os import requests +import shutil import socket import socks -import zipfile -import json -import shutil from PyQt5 import QtCore, QtTest @@ -59,24 +58,28 @@ class GuiBaseTest(object): except: pass - - def test_gui_loaded(self): + + def gui_loaded(self): '''Test that the GUI actually is shown''' self.assertTrue(self.gui.show) - def test_windowTitle_seen(self): + + def windowTitle_seen(self): '''Test that the window title is OnionShare''' self.assertEqual(self.gui.windowTitle(), 'OnionShare') - def test_settings_button_is_visible(self): + + def settings_button_is_visible(self): '''Test that the settings button is visible''' self.assertTrue(self.gui.settings_button.isVisible()) - def test_server_status_bar_is_visible(self): + + def server_status_bar_is_visible(self): '''Test that the status bar is visible''' self.assertTrue(self.gui.status_bar.isVisible()) - def test_click_mode(self, mode): + + 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) @@ -85,13 +88,15 @@ class GuiBaseTest(object): QtTest.QTest.mouseClick(self.gui.share_mode_button, QtCore.Qt.LeftButton) self.assertTrue(self.gui.mode, self.gui.MODE_SHARE) - def test_click_toggle_history(self, mode): + + 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 test_history_indicator(self, mode, public_mode): + + 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(): @@ -128,63 +133,75 @@ class GuiBaseTest(object): QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton) self.assertFalse(mode.toggle_history.indicator_label.isVisible()) - def test_history_is_not_visible(self, mode): + + def history_is_not_visible(self, mode): '''Test that the History section is not visible''' self.assertFalse(mode.history.isVisible()) - def test_history_is_visible(self, mode): + + def history_is_visible(self, mode): '''Test that the History section is visible''' self.assertTrue(mode.history.isVisible()) - def test_server_working_on_start_button_pressed(self, mode): + + 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 test_server_status_indicator_says_starting(self, mode): + + def server_status_indicator_says_starting(self, mode): '''Test that the Server Status indicator shows we are Starting''' self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_share_working')) - def test_settings_button_is_hidden(self): + + 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 test_a_server_is_started(self, mode): + + def a_server_is_started(self, mode): '''Test that the server has started''' QtTest.QTest.qWait(2000) # Should now be in SERVER_STARTED state self.assertEqual(mode.server_status.status, 2) - def test_a_web_server_is_running(self): + + def a_web_server_is_running(self): '''Test that the web server has started''' sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.assertEqual(sock.connect_ex(('127.0.0.1',self.gui.app.port)), 0) - def test_have_a_slug(self, mode, public_mode): + + def have_a_slug(self, mode, public_mode): '''Test that we have a valid slug''' if not public_mode: self.assertRegex(mode.server_status.web.slug, r'(\w+)-(\w+)') else: self.assertIsNone(mode.server_status.web.slug, r'(\w+)-(\w+)') - def test_url_description_shown(self, mode): + + def url_description_shown(self, mode): '''Test that the URL label is showing''' self.assertTrue(mode.server_status.url_description.isVisible()) - def test_have_copy_url_button(self, mode): + + def have_copy_url_button(self, mode): '''Test that the Copy URL button is shown''' self.assertTrue(mode.server_status.copy_url_button.isVisible()) - def test_server_status_indicator_says_started(self, mode): + + def server_status_indicator_says_started(self, mode): '''Test that the Server Status indicator shows we are started''' if type(mode) == ReceiveMode: self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_receive_started')) if type(mode) == ShareMode: self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_share_started')) - def test_web_page(self, mode, string, public_mode): + + def web_page(self, mode, string, public_mode): '''Test that the web page contains a string''' s = socks.socksocket() s.settimeout(60) @@ -212,22 +229,26 @@ class GuiBaseTest(object): self.assertTrue(string in f.read()) f.close() - def test_history_widgets_present(self, mode): + + 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 test_counter_incremented(self, mode, count): + + def counter_incremented(self, mode, count): '''Test that the counter has incremented''' self.assertEquals(mode.history.completed_count, count) - def test_server_is_stopped(self, mode, stay_open): + + 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): QtTest.QTest.mouseClick(mode.server_status.server_button, QtCore.Qt.LeftButton) self.assertEquals(mode.server_status.status, 0) - def test_web_service_is_stopped(self): + + def web_service_is_stopped(self): '''Test that the web server also stopped''' QtTest.QTest.qWait(2000) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -235,7 +256,8 @@ class GuiBaseTest(object): # We should be closed by now. Fail if not! self.assertNotEqual(sock.connect_ex(('127.0.0.1',self.gui.app.port)), 0) - def test_server_status_indicator_says_closed(self, mode, stay_open): + + def server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' if type(mode) == ReceiveMode: self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped')) @@ -245,184 +267,10 @@ class GuiBaseTest(object): else: self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically')) - # Auto-stop timer tests - def test_set_timeout(self, mode, timeout): - '''Test that the timeout can be set''' - timer = QtCore.QDateTime.currentDateTime().addSecs(timeout) - mode.server_status.shutdown_timeout.setDateTime(timer) - self.assertTrue(mode.server_status.shutdown_timeout.dateTime(), timer) - - def test_timeout_widget_hidden(self, mode): - '''Test that the timeout widget is hidden when share has started''' - self.assertFalse(mode.server_status.shutdown_timeout_container.isVisible()) - - def test_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) - - # Receive-specific tests - def test_upload_file(self, public_mode, expected_file): - '''Test that we can upload the file''' - files = {'file[]': open('/tmp/test.txt', 'rb')} - if not public_mode: - path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, self.gui.receive_mode.web.slug) - else: - path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) - response = requests.post(path, files=files) - QtTest.QTest.qWait(2000) - self.assertTrue(os.path.isfile(expected_file)) - - # Share-specific tests - def test_file_selection_widget_has_a_file(self): - '''Test that the number of files in the list is 1''' - self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 1) - - def test_deleting_only_file_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, and since there's no more files, the delete button should be hidden - QtTest.QTest.mouseClick(self.gui.share_mode.server_status.file_selection.delete_button, QtCore.Qt.LeftButton) - self.assertFalse(self.gui.share_mode.server_status.file_selection.delete_button.isVisible()) - - def test_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.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) - - def test_file_selection_widget_readd_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.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 2) - - def test_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 test_download_share(self, public_mode): - '''Test that we can download the share''' - s = socks.socksocket() - s.settimeout(60) - s.connect(('127.0.0.1', self.gui.app.port)) - - if public_mode: - path = '/download' - else: - path = '{}/download'.format(self.gui.share_mode.web.slug) - - http_request = 'GET {} HTTP/1.0\r\n'.format(path) - http_request += 'Host: 127.0.0.1\r\n' - http_request += '\r\n' - s.sendall(http_request.encode('utf-8')) - - with open('/tmp/download.zip', 'wb') as file_to_write: - while True: - data = s.recv(1024) - if not data: - break - file_to_write.write(data) - file_to_write.close() - - zip = zipfile.ZipFile('/tmp/download.zip') - QtTest.QTest.qWait(2000) - self.assertEqual('onionshare', zip.read('test.txt').decode('utf-8')) - - def test_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()) - - - # The following are 'groupings' of tests used by other objects that inherit GuiBaseTest - def run_all_common_setup_tests(self): - GuiBaseTest.test_gui_loaded(self) - GuiBaseTest.test_windowTitle_seen(self) - GuiBaseTest.test_settings_button_is_visible(self) - GuiBaseTest.test_server_status_bar_is_visible(self) + self.gui_loaded() + self.windowTitle_seen() + self.settings_button_is_visible() + self.server_status_bar_is_visible() - def run_all_share_mode_setup_tests(self): - """Tests in share mode prior to starting a share""" - GuiBaseTest.test_click_mode(self, self.gui.share_mode) - GuiBaseTest.test_file_selection_widget_has_a_file(self) - GuiBaseTest.test_history_is_not_visible(self, self.gui.share_mode) - GuiBaseTest.test_click_toggle_history(self, self.gui.share_mode) - GuiBaseTest.test_history_is_visible(self, self.gui.share_mode) - GuiBaseTest.test_deleting_only_file_hides_delete_button(self) - GuiBaseTest.test_add_a_file_and_delete_using_its_delete_widget(self) - GuiBaseTest.test_file_selection_widget_readd_files(self) - def run_all_share_mode_started_tests(self, public_mode): - """Tests in share mode after starting a share""" - GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - GuiBaseTest.test_server_status_indicator_says_starting(self, self.gui.share_mode) - GuiBaseTest.test_add_delete_buttons_hidden(self) - GuiBaseTest.test_settings_button_is_hidden(self) - GuiBaseTest.test_a_server_is_started(self, self.gui.share_mode) - GuiBaseTest.test_a_web_server_is_running(self) - GuiBaseTest.test_have_a_slug(self, self.gui.share_mode, public_mode) - GuiBaseTest.test_url_description_shown(self, self.gui.share_mode) - GuiBaseTest.test_have_copy_url_button(self, self.gui.share_mode) - GuiBaseTest.test_server_status_indicator_says_started(self, self.gui.share_mode) - GuiBaseTest.test_web_page(self, self.gui.share_mode, 'Total size', public_mode) - - def run_all_share_mode_download_tests(self, public_mode, stay_open): - """Tests in share mode after downloading a share""" - GuiBaseTest.test_download_share(self, public_mode) - GuiBaseTest.test_history_widgets_present(self, self.gui.share_mode) - GuiBaseTest.test_server_is_stopped(self, self.gui.share_mode, stay_open) - GuiBaseTest.test_web_service_is_stopped(self) - GuiBaseTest.test_server_status_indicator_says_closed(self, self.gui.share_mode, stay_open) - GuiBaseTest.test_add_button_visible(self) - GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.share_mode) - GuiBaseTest.test_a_server_is_started(self, self.gui.share_mode) - GuiBaseTest.test_history_indicator(self, self.gui.share_mode, public_mode) - - def run_all_share_mode_tests(self, public_mode, stay_open): - """End-to-end share tests""" - GuiBaseTest.run_all_share_mode_setup_tests(self) - GuiBaseTest.run_all_share_mode_started_tests(self, public_mode) - GuiBaseTest.run_all_share_mode_download_tests(self, public_mode, stay_open) - - def run_all_share_mode_timer_tests(self, public_mode): - """Auto-stop timer tests in share mode""" - GuiBaseTest.run_all_share_mode_setup_tests(self) - GuiBaseTest.test_set_timeout(self, self.gui.share_mode, 5) - GuiBaseTest.run_all_share_mode_started_tests(self, public_mode) - GuiBaseTest.test_timeout_widget_hidden(self, self.gui.share_mode) - GuiBaseTest.test_server_timed_out(self, self.gui.share_mode, 10000) - GuiBaseTest.test_web_service_is_stopped(self) - - def run_all_receive_mode_tests(self, public_mode, receive_allow_receiver_shutdown): - GuiBaseTest.test_click_mode(self, self.gui.receive_mode) - GuiBaseTest.test_history_is_not_visible(self, self.gui.receive_mode) - GuiBaseTest.test_click_toggle_history(self, self.gui.receive_mode) - GuiBaseTest.test_history_is_visible(self, self.gui.receive_mode) - GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) - GuiBaseTest.test_server_status_indicator_says_starting(self, self.gui.receive_mode) - GuiBaseTest.test_settings_button_is_hidden(self) - GuiBaseTest.test_a_server_is_started(self, self.gui.receive_mode) - GuiBaseTest.test_a_web_server_is_running(self) - GuiBaseTest.test_have_a_slug(self, self.gui.receive_mode, public_mode) - GuiBaseTest.test_url_description_shown(self, self.gui.receive_mode) - GuiBaseTest.test_have_copy_url_button(self, self.gui.receive_mode) - GuiBaseTest.test_server_status_indicator_says_started(self, self.gui.receive_mode) - GuiBaseTest.test_web_page(self, self.gui.receive_mode, 'Select the files you want to send, then click', public_mode) - GuiBaseTest.test_upload_file(self, public_mode, '/tmp/OnionShare/test.txt') - GuiBaseTest.test_history_widgets_present(self, self.gui.receive_mode) - GuiBaseTest.test_counter_incremented(self, self.gui.receive_mode, 1) - GuiBaseTest.test_upload_file(self, public_mode, '/tmp/OnionShare/test-2.txt') - GuiBaseTest.test_counter_incremented(self, self.gui.receive_mode, 2) - GuiBaseTest.test_history_indicator(self, self.gui.receive_mode, public_mode) - GuiBaseTest.test_server_is_stopped(self, self.gui.receive_mode, False) - GuiBaseTest.test_web_service_is_stopped(self) - GuiBaseTest.test_server_status_indicator_says_closed(self, self.gui.receive_mode, False) - GuiBaseTest.test_server_working_on_start_button_pressed(self, self.gui.receive_mode) - GuiBaseTest.test_a_server_is_started(self, self.gui.receive_mode) - GuiBaseTest.test_history_indicator(self, self.gui.receive_mode, public_mode) diff --git a/tests_gui_local/GuiReceiveTest.py b/tests_gui_local/GuiReceiveTest.py new file mode 100644 index 00000000..1fa5c4dc --- /dev/null +++ b/tests_gui_local/GuiReceiveTest.py @@ -0,0 +1,45 @@ +import os +import requests +from PyQt5 import QtTest +from .GuiBaseTest import GuiBaseTest + +class GuiReceiveTest(GuiBaseTest): + def upload_file(self, public_mode, expected_file): + '''Test that we can upload the file''' + files = {'file[]': open('/tmp/test.txt', 'rb')} + if not public_mode: + path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, self.gui.receive_mode.web.slug) + else: + path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) + response = requests.post(path, files=files) + QtTest.QTest.qWait(2000) + self.assertTrue(os.path.isfile(expected_file)) + + def run_all_receive_mode_tests(self, public_mode, receive_allow_receiver_shutdown): + 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.a_server_is_started(self.gui.receive_mode) + self.a_web_server_is_running() + self.have_a_slug(self.gui.receive_mode, public_mode) + self.url_description_shown(self.gui.receive_mode) + self.have_copy_url_button(self.gui.receive_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/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/OnionShare/test-2.txt') + self.counter_incremented(self.gui.receive_mode, 2) + self.history_indicator(self.gui.receive_mode, public_mode) + self.server_is_stopped(self.gui.receive_mode, False) + self.web_service_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.a_server_is_started(self.gui.receive_mode) + self.history_indicator(self.gui.receive_mode, public_mode) + diff --git a/tests_gui_local/GuiShareTest.py b/tests_gui_local/GuiShareTest.py new file mode 100644 index 00000000..8c3ea2b1 --- /dev/null +++ b/tests_gui_local/GuiShareTest.py @@ -0,0 +1,154 @@ +import socks +import zipfile +from PyQt5 import QtCore, QtTest +from .GuiBaseTest import GuiBaseTest + +class GuiShareTest(GuiBaseTest): + # 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.shutdown_timeout.setDateTime(timer) + self.assertTrue(mode.server_status.shutdown_timeout.dateTime(), timer) + + + def timeout_widget_hidden(self, mode): + '''Test that the timeout widget is hidden when share has started''' + self.assertFalse(mode.server_status.shutdown_timeout_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) + + # Share-specific tests + + def file_selection_widget_has_a_file(self): + '''Test that the number of files in the list is 1''' + self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 1) + + + def deleting_only_file_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, and since there's no more files, the delete button should be hidden + QtTest.QTest.mouseClick(self.gui.share_mode.server_status.file_selection.delete_button, QtCore.Qt.LeftButton) + 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.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) + + + def file_selection_widget_readd_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.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 2) + + + 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''' + s = socks.socksocket() + s.settimeout(60) + s.connect(('127.0.0.1', self.gui.app.port)) + + if public_mode: + path = '/download' + else: + path = '{}/download'.format(self.gui.share_mode.web.slug) + + http_request = 'GET {} HTTP/1.0\r\n'.format(path) + http_request += 'Host: 127.0.0.1\r\n' + http_request += '\r\n' + s.sendall(http_request.encode('utf-8')) + + with open('/tmp/download.zip', 'wb') as file_to_write: + while True: + data = s.recv(1024) + if not data: + break + file_to_write.write(data) + file_to_write.close() + + zip = zipfile.ZipFile('/tmp/download.zip') + QtTest.QTest.qWait(2000) + self.assertEqual('onionshare', zip.read('test.txt').decode('utf-8')) + + + 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()) + + + 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_a_file() + 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_only_file_hides_delete_button() + self.add_a_file_and_delete_using_its_delete_widget() + self.file_selection_widget_readd_files() + + + 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.a_server_is_started(self.gui.share_mode) + self.a_web_server_is_running() + self.have_a_slug(self.gui.share_mode, public_mode) + self.url_description_shown(self.gui.share_mode) + self.have_copy_url_button(self.gui.share_mode) + self.server_status_indicator_says_started(self.gui.share_mode) + self.web_page(self.gui.share_mode, 'Total size', public_mode) + + + def run_all_share_mode_download_tests(self, public_mode, stay_open): + """Tests in share mode after downloading a share""" + 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_service_is_stopped() + self.server_status_indicator_says_closed(self.gui.share_mode, stay_open) + self.add_button_visible() + self.server_working_on_start_button_pressed(self.gui.share_mode) + self.a_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_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.timeout_widget_hidden(self.gui.share_mode) + self.server_timed_out(self.gui.share_mode, 10000) + self.web_service_is_stopped() + diff --git a/tests_gui_local/__init__.py b/tests_gui_local/__init__.py index 7cf168eb..e69de29b 100644 --- a/tests_gui_local/__init__.py +++ b/tests_gui_local/__init__.py @@ -1 +0,0 @@ -from .GuiBaseTest import GuiBaseTest diff --git a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py new file mode 100644 index 00000000..f41a2ce2 --- /dev/null +++ b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +import pytest +import unittest + +from .GuiReceiveTest import GuiReceiveTest + +class ReceiveModePublicModeTest(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.run(order=1) + def test_run_all_common_setup_tests(self): + GuiReceiveTest.run_all_common_setup_tests(self) + + @pytest.mark.run(order=2) + def test_run_all_receive_mode_tests(self): + GuiReceiveTest.run_all_receive_mode_tests(self, True, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index 262c7aba..8a7661dd 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -1,38 +1,28 @@ #!/usr/bin/env python3 -import os -import sys -import unittest import pytest -import json +import unittest -from PyQt5 import QtWidgets +from .GuiReceiveTest import GuiReceiveTest -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .GuiBaseTest import GuiBaseTest - -class ReceiveModeTest(unittest.TestCase): +class ReceiveModeTest(unittest.TestCase, GuiReceiveTest): @classmethod def setUpClass(cls): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): - GuiBaseTest.tear_down() + GuiReceiveTest.tear_down() @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiBaseTest.run_all_common_setup_tests(self) + GuiReceiveTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) - def test_run_all_share_mode_tests(self): - GuiBaseTest.run_all_receive_mode_tests(self, False, True) + def test_run_all_receive_mode_tests(self): + GuiReceiveTest.run_all_receive_mode_tests(self, False, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py deleted file mode 100644 index 201402c2..00000000 --- a/tests_gui_local/onionshare_receive_mode_upload_test_public_mode.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .GuiBaseTest import GuiBaseTest - -class ReceiveModePublicModeTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - test_settings = { - "public_mode": True, - "receive_allow_receiver_shutdown": True - } - cls.gui = GuiBaseTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiBaseTest.tear_down() - - @pytest.mark.run(order=1) - def test_run_all_common_setup_tests(self): - GuiBaseTest.run_all_common_setup_tests(self) - - @pytest.mark.run(order=2) - def test_run_all_share_mode_tests(self): - GuiBaseTest.run_all_receive_mode_tests(self, True, True) - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py new file mode 100644 index 00000000..53d1fb8c --- /dev/null +++ b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +import pytest +import unittest + +from .GuiShareTest import GuiShareTest + +class ShareModePublicModeTest(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.run(order=1) + def test_run_all_common_setup_tests(self): + GuiShareTest.run_all_common_setup_tests(self) + + @pytest.mark.run(order=2) + def test_run_all_share_mode_tests(self): + GuiShareTest.run_all_share_mode_tests(self, True, False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py new file mode 100644 index 00000000..b398f654 --- /dev/null +++ b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +import pytest +import unittest + +from .GuiShareTest import GuiShareTest + +class ShareModeStayOpenTest(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.run(order=1) + def test_run_all_common_setup_tests(self): + GuiShareTest.run_all_common_setup_tests(self) + + @pytest.mark.run(order=2) + def test_run_all_share_mode_tests(self): + GuiShareTest.run_all_share_mode_tests(self, False, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index b24a3a78..34532c59 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -1,37 +1,27 @@ #!/usr/bin/env python3 -import os -import sys -import unittest import pytest -import json +import unittest -from PyQt5 import QtWidgets +from .GuiShareTest import GuiShareTest -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .GuiBaseTest import GuiBaseTest - -class ShareModeTest(unittest.TestCase): +class ShareModeTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): - GuiBaseTest.tear_down() + GuiShareTest.tear_down() @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiBaseTest.run_all_common_setup_tests(self) + GuiShareTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) def test_run_all_share_mode_tests(self): - GuiBaseTest.run_all_share_mode_tests(self, False, False) + GuiShareTest.run_all_share_mode_tests(self, False, False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py b/tests_gui_local/onionshare_share_mode_download_test_public_mode.py deleted file mode 100644 index e59b53f4..00000000 --- a/tests_gui_local/onionshare_share_mode_download_test_public_mode.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .GuiBaseTest import GuiBaseTest - -class ShareModePublicModeTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - test_settings = { - "public_mode": True, - } - cls.gui = GuiBaseTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiBaseTest.tear_down() - - @pytest.mark.run(order=1) - def test_run_all_common_setup_tests(self): - GuiBaseTest.run_all_common_setup_tests(self) - - @pytest.mark.run(order=2) - def test_run_all_share_mode_tests(self): - GuiBaseTest.run_all_share_mode_tests(self, True, False) - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py b/tests_gui_local/onionshare_share_mode_download_test_stay_open.py deleted file mode 100644 index 9394c34a..00000000 --- a/tests_gui_local/onionshare_share_mode_download_test_stay_open.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .GuiBaseTest import GuiBaseTest - -class ShareModeStayOpenTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - test_settings = { - "close_after_first_download": False, - } - cls.gui = GuiBaseTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiBaseTest.tear_down() - - @pytest.mark.run(order=1) - def test_run_all_common_setup_tests(self): - GuiBaseTest.run_all_common_setup_tests(self) - - @pytest.mark.run(order=2) - def test_run_all_share_mode_tests(self): - GuiBaseTest.run_all_share_mode_tests(self, False, True) - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_local/onionshare_slug_persistent_test.py b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py similarity index 61% rename from tests_gui_local/onionshare_slug_persistent_test.py rename to tests_gui_local/onionshare_share_mode_slug_persistent_test.py index ab845f8e..b4c92f36 100644 --- a/tests_gui_local/onionshare_slug_persistent_test.py +++ b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py @@ -1,20 +1,10 @@ #!/usr/bin/env python3 -import os -import sys -import unittest import pytest -import json +import unittest -from PyQt5 import QtWidgets +from .GuiShareTest import GuiShareTest -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .GuiBaseTest import GuiBaseTest - -class ShareModePersistentSlugTest(unittest.TestCase): +class ShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { @@ -23,19 +13,19 @@ class ShareModePersistentSlugTest(unittest.TestCase): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiBaseTest.set_up(test_settings) + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): - GuiBaseTest.tear_down() + GuiShareTest.tear_down() @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiBaseTest.run_all_common_setup_tests(self) + GuiShareTest.run_all_common_setup_tests(self) @pytest.mark.run(order=2) def test_run_all_share_mode_tests(self): - GuiBaseTest.run_all_share_mode_tests(self, False, True) + GuiShareTest.run_all_share_mode_tests(self, False, True) global slug slug = self.gui.share_mode.server_status.web.slug diff --git a/tests_gui_local/onionshare_share_mode_timer_test.py b/tests_gui_local/onionshare_share_mode_timer_test.py new file mode 100644 index 00000000..98902428 --- /dev/null +++ b/tests_gui_local/onionshare_share_mode_timer_test.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +import pytest +import unittest + +from .GuiShareTest import GuiShareTest + +class ShareModeTimerTest(unittest.TestCase, GuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + "public_mode": False, + "shutdown_timeout": True, + } + cls.gui = GuiShareTest.set_up(test_settings) + + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + + @pytest.mark.run(order=1) + def test_run_all_common_setup_tests(self): + GuiShareTest.run_all_common_setup_tests(self) + + @pytest.mark.run(order=2) + def test_run_all_share_mode_timer_tests(self): + GuiShareTest.run_all_share_mode_timer_tests(self, False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui_local/onionshare_timer_test.py b/tests_gui_local/onionshare_timer_test.py deleted file mode 100644 index 60c616cc..00000000 --- a/tests_gui_local/onionshare_timer_test.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .GuiBaseTest import GuiBaseTest - -class ShareModeTimerTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - test_settings = { - "public_mode": False, - "shutdown_timeout": True, - } - cls.gui = GuiBaseTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiBaseTest.tear_down() - - @pytest.mark.run(order=1) - def test_run_all_common_setup_tests(self): - GuiBaseTest.run_all_common_setup_tests(self) - - @pytest.mark.run(order=2) - def test_run_all_share_mode_timer_tests(self): - GuiBaseTest.run_all_share_mode_timer_tests(self, False) - -if __name__ == "__main__": - unittest.main() From 72d0c20aada8ed6d7976f7987511ff3500bbd3e0 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 11:42:40 +1100 Subject: [PATCH 075/142] Write settings json files out to unique files per test --- tests_gui_local/GuiBaseTest.py | 6 +++--- .../onionshare_receive_mode_upload_public_mode_test.py | 2 +- tests_gui_local/onionshare_receive_mode_upload_test.py | 2 +- .../onionshare_share_mode_download_public_mode_test.py | 2 +- .../onionshare_share_mode_download_stay_open_test.py | 2 +- tests_gui_local/onionshare_share_mode_download_test.py | 2 +- .../onionshare_share_mode_slug_persistent_test.py | 2 +- tests_gui_local/onionshare_share_mode_timer_test.py | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests_gui_local/GuiBaseTest.py b/tests_gui_local/GuiBaseTest.py index 8a8b127e..449a5b7e 100644 --- a/tests_gui_local/GuiBaseTest.py +++ b/tests_gui_local/GuiBaseTest.py @@ -19,7 +19,7 @@ from onionshare_gui.mode.receive_mode import ReceiveMode class GuiBaseTest(object): @staticmethod - def set_up(test_settings): + def set_up(test_settings, settings_filename): '''Create GUI with given settings''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -44,8 +44,7 @@ class GuiBaseTest(object): app = OnionShare(common, testonion, True, 0) web = Web(common, False, True) - settings_filename = '/tmp/testsettings.json' - open(settings_filename, 'w').write(json.dumps(test_settings)) + open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], settings_filename, True) return gui @@ -54,6 +53,7 @@ class GuiBaseTest(object): def tear_down(): try: os.remove('/tmp/test.txt') + os.remove('/tmp/download.zip') shutil.rmtree('/tmp/OnionShare') except: pass diff --git a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py index f41a2ce2..32ea8656 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py @@ -11,7 +11,7 @@ class ReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings) + cls.gui = GuiReceiveTest.set_up(test_settings, 'ReceiveModePublicModeTest') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index 8a7661dd..c59ac9c0 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -10,7 +10,7 @@ class ReceiveModeTest(unittest.TestCase, GuiReceiveTest): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings) + cls.gui = GuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py index 53d1fb8c..b6ce3a3c 100644 --- a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py +++ b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py @@ -10,7 +10,7 @@ class ShareModePublicModeTest(unittest.TestCase, GuiShareTest): test_settings = { "public_mode": True, } - cls.gui = GuiShareTest.set_up(test_settings) + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py index b398f654..7ff9aaf2 100644 --- a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py +++ b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py @@ -10,7 +10,7 @@ class ShareModeStayOpenTest(unittest.TestCase, GuiShareTest): test_settings = { "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings) + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index 34532c59..9de0a767 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -9,7 +9,7 @@ class ShareModeTest(unittest.TestCase, GuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings) + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTest') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py index b4c92f36..02cbdd27 100644 --- a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py +++ b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py @@ -13,7 +13,7 @@ class ShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings) + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_timer_test.py b/tests_gui_local/onionshare_share_mode_timer_test.py index 98902428..96c48443 100644 --- a/tests_gui_local/onionshare_share_mode_timer_test.py +++ b/tests_gui_local/onionshare_share_mode_timer_test.py @@ -11,7 +11,7 @@ class ShareModeTimerTest(unittest.TestCase, GuiShareTest): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiShareTest.set_up(test_settings) + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTimerTest') @classmethod def tearDownClass(cls): From 26cd930ecc89c883d693664d9c019584d16d6dfa Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 11:50:12 +1100 Subject: [PATCH 076/142] Revert "Write settings json files out to unique files per test" This reverts commit 72d0c20aada8ed6d7976f7987511ff3500bbd3e0. --- tests_gui_local/GuiBaseTest.py | 6 +++--- .../onionshare_receive_mode_upload_public_mode_test.py | 2 +- tests_gui_local/onionshare_receive_mode_upload_test.py | 2 +- .../onionshare_share_mode_download_public_mode_test.py | 2 +- .../onionshare_share_mode_download_stay_open_test.py | 2 +- tests_gui_local/onionshare_share_mode_download_test.py | 2 +- .../onionshare_share_mode_slug_persistent_test.py | 2 +- tests_gui_local/onionshare_share_mode_timer_test.py | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests_gui_local/GuiBaseTest.py b/tests_gui_local/GuiBaseTest.py index 449a5b7e..8a8b127e 100644 --- a/tests_gui_local/GuiBaseTest.py +++ b/tests_gui_local/GuiBaseTest.py @@ -19,7 +19,7 @@ from onionshare_gui.mode.receive_mode import ReceiveMode class GuiBaseTest(object): @staticmethod - def set_up(test_settings, settings_filename): + def set_up(test_settings): '''Create GUI with given settings''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -44,7 +44,8 @@ class GuiBaseTest(object): app = OnionShare(common, testonion, True, 0) web = Web(common, False, True) - open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) + settings_filename = '/tmp/testsettings.json' + open(settings_filename, 'w').write(json.dumps(test_settings)) gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], settings_filename, True) return gui @@ -53,7 +54,6 @@ class GuiBaseTest(object): def tear_down(): try: os.remove('/tmp/test.txt') - os.remove('/tmp/download.zip') shutil.rmtree('/tmp/OnionShare') except: pass diff --git a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py index 32ea8656..f41a2ce2 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py @@ -11,7 +11,7 @@ class ReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'ReceiveModePublicModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index c59ac9c0..8a7661dd 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -10,7 +10,7 @@ class ReceiveModeTest(unittest.TestCase, GuiReceiveTest): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py index b6ce3a3c..53d1fb8c 100644 --- a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py +++ b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py @@ -10,7 +10,7 @@ class ShareModePublicModeTest(unittest.TestCase, GuiShareTest): test_settings = { "public_mode": True, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py index 7ff9aaf2..b398f654 100644 --- a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py +++ b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py @@ -10,7 +10,7 @@ class ShareModeStayOpenTest(unittest.TestCase, GuiShareTest): test_settings = { "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index 9de0a767..34532c59 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -9,7 +9,7 @@ class ShareModeTest(unittest.TestCase, GuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py index 02cbdd27..b4c92f36 100644 --- a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py +++ b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py @@ -13,7 +13,7 @@ class ShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests_gui_local/onionshare_share_mode_timer_test.py b/tests_gui_local/onionshare_share_mode_timer_test.py index 96c48443..98902428 100644 --- a/tests_gui_local/onionshare_share_mode_timer_test.py +++ b/tests_gui_local/onionshare_share_mode_timer_test.py @@ -11,7 +11,7 @@ class ShareModeTimerTest(unittest.TestCase, GuiShareTest): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTimerTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): From 48a5d45baf62b32961a585125ab08bc655edc771 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 12:18:34 +1100 Subject: [PATCH 077/142] Fix persistence tests, re-introduce separate settings json files, fix call to actual tests to use self. These can now be run with 'xvfb-run pytest tests_gui_local/' instead of via a shell script --- .travis.yml | 2 +- tests_gui_local/GuiBaseTest.py | 7 +++---- tests_gui_local/GuiShareTest.py | 14 ++++++++++++++ ...hare_receive_mode_upload_public_mode_test.py | 10 +++------- .../onionshare_receive_mode_upload_test.py | 10 +++------- ...hare_share_mode_download_public_mode_test.py | 10 +++------- ...nshare_share_mode_download_stay_open_test.py | 10 +++------- .../onionshare_share_mode_download_test.py | 10 +++------- ...nionshare_share_mode_slug_persistent_test.py | 17 +++-------------- .../onionshare_share_mode_timer_test.py | 10 +++------- tests_gui_local/run_unit_tests.sh | 5 ----- 11 files changed, 39 insertions(+), 66 deletions(-) delete mode 100755 tests_gui_local/run_unit_tests.sh diff --git a/.travis.yml b/.travis.yml index e0b5b822..5750536d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,4 @@ before_script: # run CLI tests and local GUI tests script: - pytest --cov=onionshare tests/ - - cd tests_gui_local/ && xvfb-run ./run_unit_tests.sh + - xvfb-run pytest tests_gui_local/ diff --git a/tests_gui_local/GuiBaseTest.py b/tests_gui_local/GuiBaseTest.py index 8a8b127e..138a279a 100644 --- a/tests_gui_local/GuiBaseTest.py +++ b/tests_gui_local/GuiBaseTest.py @@ -19,7 +19,7 @@ from onionshare_gui.mode.receive_mode import ReceiveMode class GuiBaseTest(object): @staticmethod - def set_up(test_settings): + def set_up(test_settings, settings_filename): '''Create GUI with given settings''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -44,10 +44,9 @@ class GuiBaseTest(object): app = OnionShare(common, testonion, True, 0) web = Web(common, False, True) - settings_filename = '/tmp/testsettings.json' - open(settings_filename, 'w').write(json.dumps(test_settings)) + open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) - gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], settings_filename, True) + gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], '/tmp/{}.json'.format(settings_filename), True) return gui @staticmethod diff --git a/tests_gui_local/GuiShareTest.py b/tests_gui_local/GuiShareTest.py index 8c3ea2b1..11df3167 100644 --- a/tests_gui_local/GuiShareTest.py +++ b/tests_gui_local/GuiShareTest.py @@ -24,6 +24,11 @@ class GuiShareTest(GuiBaseTest): # We should have timed out now self.assertEqual(mode.server_status.status, 0) + # Persistence tests + def have_same_slug(self, slug): + '''Test that we have the same slug''' + self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) + # Share-specific tests def file_selection_widget_has_a_file(self): @@ -143,6 +148,15 @@ class GuiShareTest(GuiBaseTest): self.run_all_share_mode_download_tests(public_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 slug is the same on multiple shared""" + self.run_all_share_mode_setup_tests() + self.run_all_share_mode_started_tests(public_mode) + slug = self.gui.share_mode.server_status.web.slug + self.run_all_share_mode_download_tests(public_mode, stay_open) + self.have_same_slug(slug) + + def run_all_share_mode_timer_tests(self, public_mode): """Auto-stop timer tests in share mode""" self.run_all_share_mode_setup_tests() diff --git a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py index f41a2ce2..5b685ef7 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py @@ -11,19 +11,15 @@ class ReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiReceiveTest.tear_down() + cls.gui = GuiReceiveTest.set_up(test_settings, 'ReceiveModePublicModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiReceiveTest.run_all_common_setup_tests(self) + self.run_all_common_setup_tests() @pytest.mark.run(order=2) def test_run_all_receive_mode_tests(self): - GuiReceiveTest.run_all_receive_mode_tests(self, True, True) + self.run_all_receive_mode_tests(True, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui_local/onionshare_receive_mode_upload_test.py index 8a7661dd..7171eaca 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui_local/onionshare_receive_mode_upload_test.py @@ -10,19 +10,15 @@ class ReceiveModeTest(unittest.TestCase, GuiReceiveTest): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiReceiveTest.tear_down() + cls.gui = GuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiReceiveTest.run_all_common_setup_tests(self) + self.run_all_common_setup_tests() @pytest.mark.run(order=2) def test_run_all_receive_mode_tests(self): - GuiReceiveTest.run_all_receive_mode_tests(self, False, True) + self.run_all_receive_mode_tests(False, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py index 53d1fb8c..96cadb90 100644 --- a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py +++ b/tests_gui_local/onionshare_share_mode_download_public_mode_test.py @@ -10,19 +10,15 @@ class ShareModePublicModeTest(unittest.TestCase, GuiShareTest): test_settings = { "public_mode": True, } - cls.gui = GuiShareTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiShareTest.tear_down() + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiShareTest.run_all_common_setup_tests(self) + self.run_all_common_setup_tests() @pytest.mark.run(order=2) def test_run_all_share_mode_tests(self): - GuiShareTest.run_all_share_mode_tests(self, True, False) + self.run_all_share_mode_tests(True, False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py index b398f654..bb9ec2ea 100644 --- a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py +++ b/tests_gui_local/onionshare_share_mode_download_stay_open_test.py @@ -10,19 +10,15 @@ class ShareModeStayOpenTest(unittest.TestCase, GuiShareTest): test_settings = { "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiShareTest.tear_down() + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiShareTest.run_all_common_setup_tests(self) + self.run_all_common_setup_tests() @pytest.mark.run(order=2) def test_run_all_share_mode_tests(self): - GuiShareTest.run_all_share_mode_tests(self, False, True) + self.run_all_share_mode_tests(False, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui_local/onionshare_share_mode_download_test.py index 34532c59..12b914b0 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui_local/onionshare_share_mode_download_test.py @@ -9,19 +9,15 @@ class ShareModeTest(unittest.TestCase, GuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiShareTest.tear_down() + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiShareTest.run_all_common_setup_tests(self) + self.run_all_common_setup_tests() @pytest.mark.run(order=2) def test_run_all_share_mode_tests(self): - GuiShareTest.run_all_share_mode_tests(self, False, False) + self.run_all_share_mode_tests(False, False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py index b4c92f36..25e4e093 100644 --- a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py +++ b/tests_gui_local/onionshare_share_mode_slug_persistent_test.py @@ -13,26 +13,15 @@ class ShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiShareTest.tear_down() + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiShareTest.run_all_common_setup_tests(self) + self.run_all_common_setup_tests() @pytest.mark.run(order=2) def test_run_all_share_mode_tests(self): - GuiShareTest.run_all_share_mode_tests(self, False, True) - global slug - slug = self.gui.share_mode.server_status.web.slug - - @pytest.mark.run(order=3) - def test_have_same_slug(self): - '''Test that we have the same slug''' - self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) + self.run_all_share_mode_persistent_tests(False, True) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/onionshare_share_mode_timer_test.py b/tests_gui_local/onionshare_share_mode_timer_test.py index 98902428..2e654c9d 100644 --- a/tests_gui_local/onionshare_share_mode_timer_test.py +++ b/tests_gui_local/onionshare_share_mode_timer_test.py @@ -11,19 +11,15 @@ class ShareModeTimerTest(unittest.TestCase, GuiShareTest): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiShareTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiShareTest.tear_down() + cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTimerTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): - GuiShareTest.run_all_common_setup_tests(self) + self.run_all_common_setup_tests() @pytest.mark.run(order=2) def test_run_all_share_mode_timer_tests(self): - GuiShareTest.run_all_share_mode_timer_tests(self, False) + self.run_all_share_mode_timer_tests(False) if __name__ == "__main__": unittest.main() diff --git a/tests_gui_local/run_unit_tests.sh b/tests_gui_local/run_unit_tests.sh deleted file mode 100755 index 7d207a57..00000000 --- a/tests_gui_local/run_unit_tests.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -for test in `ls -1 | egrep ^onionshare_`; do - pytest $test -vvv || exit 1 -done From 910bf7e8be4fd7e34878c745eda705879e8c78dc Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 18:53:03 +1100 Subject: [PATCH 078/142] Beginning to move the Tor tests into tests_gui and inheriting what we can from the local tests to avoid code reuse. Add --runtor flag in pytest to run these --- .travis.yml | 2 +- {tests_gui_local => tests_gui}/GuiBaseTest.py | 2 +- .../GuiReceiveTest.py | 0 .../GuiShareTest.py | 2 +- tests_gui/TorGuiBaseTest.py | 154 +++++++++++++ tests_gui/TorGuiReceiveTest.py | 51 +++++ tests_gui/TorGuiShareTest.py | 70 ++++++ {tests_gui_local => tests_gui}/__init__.py | 0 {tests_gui_local => tests_gui}/conftest.py | 16 ++ ...re_receive_mode_upload_public_mode_test.py | 4 +- ...cal_onionshare_receive_mode_upload_test.py | 4 +- ...re_share_mode_download_public_mode_test.py | 4 +- ...hare_share_mode_download_stay_open_test.py | 4 +- ...cal_onionshare_share_mode_download_test.py | 4 +- ...onshare_share_mode_slug_persistent_test.py | 4 +- .../local_onionshare_share_mode_timer_test.py | 4 +- ...re_receive_mode_upload_public_mode_test.py | 27 +++ .../onionshare_receive_mode_upload_test.py | 26 +++ ...re_share_mode_download_public_mode_test.py | 26 +++ ...hare_share_mode_download_stay_open_test.py | 26 +++ .../onionshare_share_mode_download_test.py | 25 ++ .../onionshare_share_mode_persistent_test.py | 30 +++ .../onionshare_share_mode_stealth_test.py | 34 +++ ...e_share_mode_tor_connection_killed_test.py | 42 ++++ tests_gui_tor/__init__.py | 0 tests_gui_tor/commontests.py | 61 ----- tests_gui_tor/conftest.py | 163 -------------- .../onionshare_receive_mode_upload_test.py | 190 ---------------- ...re_receive_mode_upload_test_public_mode.py | 190 ---------------- .../onionshare_share_mode_download_test.py | 193 ---------------- ...re_share_mode_download_test_public_mode.py | 201 ----------------- ...hare_share_mode_download_test_stay_open.py | 213 ------------------ .../onionshare_share_mode_persistent_test.py | 185 --------------- .../onionshare_share_mode_stealth_test.py | 180 --------------- ...e_share_mode_tor_connection_killed_test.py | 185 --------------- .../onionshare_tor_connection_killed_test.py | 185 --------------- tests_gui_tor/run_unit_tests.sh | 5 - 37 files changed, 544 insertions(+), 1968 deletions(-) rename {tests_gui_local => tests_gui}/GuiBaseTest.py (99%) rename {tests_gui_local => tests_gui}/GuiReceiveTest.py (100%) rename {tests_gui_local => tests_gui}/GuiShareTest.py (100%) create mode 100644 tests_gui/TorGuiBaseTest.py create mode 100644 tests_gui/TorGuiReceiveTest.py create mode 100644 tests_gui/TorGuiShareTest.py rename {tests_gui_local => tests_gui}/__init__.py (100%) rename {tests_gui_local => tests_gui}/conftest.py (89%) rename tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py => tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py (77%) rename tests_gui_local/onionshare_receive_mode_upload_test.py => tests_gui/local_onionshare_receive_mode_upload_test.py (78%) rename tests_gui_local/onionshare_share_mode_download_public_mode_test.py => tests_gui/local_onionshare_share_mode_download_public_mode_test.py (76%) rename tests_gui_local/onionshare_share_mode_download_stay_open_test.py => tests_gui/local_onionshare_share_mode_download_stay_open_test.py (77%) rename tests_gui_local/onionshare_share_mode_download_test.py => tests_gui/local_onionshare_share_mode_download_test.py (77%) rename tests_gui_local/onionshare_share_mode_slug_persistent_test.py => tests_gui/local_onionshare_share_mode_slug_persistent_test.py (79%) rename tests_gui_local/onionshare_share_mode_timer_test.py => tests_gui/local_onionshare_share_mode_timer_test.py (79%) create mode 100644 tests_gui/onionshare_receive_mode_upload_public_mode_test.py create mode 100644 tests_gui/onionshare_receive_mode_upload_test.py create mode 100644 tests_gui/onionshare_share_mode_download_public_mode_test.py create mode 100644 tests_gui/onionshare_share_mode_download_stay_open_test.py create mode 100644 tests_gui/onionshare_share_mode_download_test.py create mode 100644 tests_gui/onionshare_share_mode_persistent_test.py create mode 100644 tests_gui/onionshare_share_mode_stealth_test.py create mode 100644 tests_gui/onionshare_share_mode_tor_connection_killed_test.py delete mode 100644 tests_gui_tor/__init__.py delete mode 100644 tests_gui_tor/commontests.py delete mode 100644 tests_gui_tor/conftest.py delete mode 100644 tests_gui_tor/onionshare_receive_mode_upload_test.py delete mode 100644 tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py delete mode 100644 tests_gui_tor/onionshare_share_mode_download_test.py delete mode 100644 tests_gui_tor/onionshare_share_mode_download_test_public_mode.py delete mode 100644 tests_gui_tor/onionshare_share_mode_download_test_stay_open.py delete mode 100644 tests_gui_tor/onionshare_share_mode_persistent_test.py delete mode 100644 tests_gui_tor/onionshare_share_mode_stealth_test.py delete mode 100644 tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py delete mode 100644 tests_gui_tor/onionshare_tor_connection_killed_test.py delete mode 100755 tests_gui_tor/run_unit_tests.sh diff --git a/.travis.yml b/.travis.yml index 5750536d..c54c205d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,4 @@ before_script: # run CLI tests and local GUI tests script: - pytest --cov=onionshare tests/ - - xvfb-run pytest tests_gui_local/ + - xvfb-run pytest tests_gui/ -vvv diff --git a/tests_gui_local/GuiBaseTest.py b/tests_gui/GuiBaseTest.py similarity index 99% rename from tests_gui_local/GuiBaseTest.py rename to tests_gui/GuiBaseTest.py index 138a279a..79543468 100644 --- a/tests_gui_local/GuiBaseTest.py +++ b/tests_gui/GuiBaseTest.py @@ -120,7 +120,7 @@ class GuiBaseTest(object): if public_mode: url = "http://127.0.0.1:{}/download".format(self.gui.app.port) else: - url = "http://127.0.0.1:{}/{}/download".format(self.gui.app.port, self.gui.share_mode.web.slug) + url = "http://127.0.0.1:{}/{}/download".format(self.gui.app.port, mode.web.slug) r = requests.get(url) QtTest.QTest.qWait(2000) diff --git a/tests_gui_local/GuiReceiveTest.py b/tests_gui/GuiReceiveTest.py similarity index 100% rename from tests_gui_local/GuiReceiveTest.py rename to tests_gui/GuiReceiveTest.py diff --git a/tests_gui_local/GuiShareTest.py b/tests_gui/GuiShareTest.py similarity index 100% rename from tests_gui_local/GuiShareTest.py rename to tests_gui/GuiShareTest.py index 11df3167..34149dec 100644 --- a/tests_gui_local/GuiShareTest.py +++ b/tests_gui/GuiShareTest.py @@ -125,11 +125,11 @@ class GuiShareTest(GuiBaseTest): self.url_description_shown(self.gui.share_mode) self.have_copy_url_button(self.gui.share_mode) self.server_status_indicator_says_started(self.gui.share_mode) - self.web_page(self.gui.share_mode, 'Total size', public_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) diff --git a/tests_gui/TorGuiBaseTest.py b/tests_gui/TorGuiBaseTest.py new file mode 100644 index 00000000..1c313726 --- /dev/null +++ b/tests_gui/TorGuiBaseTest.py @@ -0,0 +1,154 @@ +import json +import os +import requests +import shutil +import socket +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, OnionShareGui +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, settings_filename): + '''Create GUI with given settings''' + # 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) + + # Get all of the settings in test_settings + test_settings['connection_type'] = 'automatic' + test_settings['downloads_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/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) + + gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], '/tmp/{}.json'.format(settings_filename), 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'] = 'socks5h://{}:{}'.format(socks_address, socks_port) + + if type(mode) == ReceiveMode: + # Upload a file + files = {'file[]': open('/tmp/test.txt', 'rb')} + if not public_mode: + path = 'http://{}/{}/upload'.format(self.gui.app.onion_host, mode.web.slug) + else: + path = 'http://{}/upload'.format(self.gui.app.onion_host) + response = session.post(path, files=files) + QtTest.QTest.qWait(4000) + + if type(mode) == ShareMode: + # Download files + if public_mode: + path = "http://{}/download".format(self.gui.app.onion_host) + else: + path = "http://{}/{}/download".format(self.gui.app.onion_host, mode.web.slug) + 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 a_server_is_started(self, mode): + '''Test that the server has started (overriding from local tests to wait for longer)''' + QtTest.QTest.qWait(45000) + # Should now be in SERVER_STARTED state + self.assertEqual(mode.server_status.status, 2) + + 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 = '/{}'.format(mode.server_status.web.slug) + else: + path = '/' + http_request = 'GET {} HTTP/1.0\r\n'.format(path) + http_request += 'Host: {}\r\n'.format(self.gui.app.onion_host) + 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 cancel_the_share(self, mode): + '''Test that we can cancel this share before it's started up ''' + QtTest.QTest.mousePress(self.gui.mode.server_status.server_button, QtCore.Qt.LeftButton) + QtTest.QTest.qWait(1000) + QtTest.QTest.mouseRelease(self.gui.mode.server_status.server_button, QtCore.Qt.LeftButton) + self.assertEqual(self.gui.mode.server_status.status, 0) + + # 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 %s [a-zA-Z1-9]' % 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.cleanup(stop_tor=True) + QtTest.QTest.qWait(2500) + self.assertTrue(mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost')) diff --git a/tests_gui/TorGuiReceiveTest.py b/tests_gui/TorGuiReceiveTest.py new file mode 100644 index 00000000..67b6a811 --- /dev/null +++ b/tests_gui/TorGuiReceiveTest.py @@ -0,0 +1,51 @@ +import os +import requests +from PyQt5 import QtTest +from .TorGuiBaseTest import TorGuiBaseTest + +class TorGuiReceiveTest(TorGuiBaseTest): + + def upload_file(self, public_mode, 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'] = 'socks5h://{}:{}'.format(socks_address, socks_port) + files = {'file[]': open('/tmp/test.txt', 'rb')} + if not public_mode: + path = 'http://{}/{}/upload'.format(self.gui.app.onion_host, self.gui.receive_mode.web.slug) + else: + path = 'http://{}/upload'.format(self.gui.app.onion_host) + response = session.post(path, files=files) + QtTest.QTest.qWait(4000) + self.assertTrue(os.path.isfile(expected_file)) + + def run_all_receive_mode_tests(self, public_mode, receive_allow_receiver_shutdown): + 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.a_server_is_started(self.gui.receive_mode) + self.a_web_server_is_running() + self.have_an_onion_service() + self.have_a_slug(self.gui.receive_mode, public_mode) + self.url_description_shown(self.gui.receive_mode) + self.have_copy_url_button(self.gui.receive_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/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/OnionShare/test-2.txt') + self.counter_incremented(self.gui.receive_mode, 2) + self.history_indicator(self.gui.receive_mode, public_mode) + self.server_is_stopped(self.gui.receive_mode, False) + self.web_service_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.a_server_is_started(self.gui.receive_mode) + self.history_indicator(self.gui.receive_mode, public_mode) + diff --git a/tests_gui/TorGuiShareTest.py b/tests_gui/TorGuiShareTest.py new file mode 100644 index 00000000..8d6358c3 --- /dev/null +++ b/tests_gui/TorGuiShareTest.py @@ -0,0 +1,70 @@ +import requests +import socks +import zipfile +from PyQt5 import QtCore, QtTest +from .TorGuiBaseTest import TorGuiBaseTest +from .GuiShareTest import GuiShareTest + +class TorGuiShareTest(TorGuiBaseTest, GuiShareTest): + def download_share(self, public_mode): + # 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'] = 'socks5h://{}:{}'.format(socks_address, socks_port) + + # Download files + if public_mode: + path = "http://{}/download".format(self.gui.app.onion_host) + else: + path = "http://{}/{}/download".format(self.gui.app.onion_host, self.gui.share_mode.web.slug) + 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.assertEquals('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) + + 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.a_server_is_started(self.gui.share_mode) + self.a_web_server_is_running() + self.have_an_onion_service() + self.have_a_slug(self.gui.share_mode, public_mode) + self.url_description_shown(self.gui.share_mode) + self.have_copy_url_button(self.gui.share_mode) + self.server_status_indicator_says_started(self.gui.share_mode) + + def run_all_share_mode_persistent_tests(self, public_mode, stay_open): + """Same as end-to-end share tests but also test the slug is the same on multiple shared""" + self.run_all_share_mode_setup_tests() + self.run_all_share_mode_started_tests(public_mode) + slug = self.gui.share_mode.server_status.web.slug + 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_slug(slug) + + 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.timeout_widget_hidden(self.gui.share_mode) + self.server_timed_out(self.gui.share_mode, 10000) + self.web_service_is_stopped() + diff --git a/tests_gui_local/__init__.py b/tests_gui/__init__.py similarity index 100% rename from tests_gui_local/__init__.py rename to tests_gui/__init__.py diff --git a/tests_gui_local/conftest.py b/tests_gui/conftest.py similarity index 89% rename from tests_gui_local/conftest.py rename to tests_gui/conftest.py index 8ac7efb8..62108e05 100644 --- a/tests_gui_local/conftest.py +++ b/tests_gui/conftest.py @@ -10,6 +10,22 @@ import pytest from onionshare import common, web, settings +def pytest_addoption(parser): + parser.addoption( + "--runtor", action="store_true", default=False, help="run tor tests" + ) + + +def pytest_collection_modifyitems(config, items): + if config.getoption("--runtor"): + # --runtor given in cli: do not skip tor tests + return + 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) + + @pytest.fixture def temp_dir_1024(): """ Create a temporary directory that has a single file of a diff --git a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py b/tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py similarity index 77% rename from tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py rename to tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py index 5b685ef7..1b5722c7 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py @@ -4,14 +4,14 @@ import unittest from .GuiReceiveTest import GuiReceiveTest -class ReceiveModePublicModeTest(unittest.TestCase, 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, 'ReceiveModePublicModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModePublicModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): diff --git a/tests_gui_local/onionshare_receive_mode_upload_test.py b/tests_gui/local_onionshare_receive_mode_upload_test.py similarity index 78% rename from tests_gui_local/onionshare_receive_mode_upload_test.py rename to tests_gui/local_onionshare_receive_mode_upload_test.py index 7171eaca..14a0377d 100644 --- a/tests_gui_local/onionshare_receive_mode_upload_test.py +++ b/tests_gui/local_onionshare_receive_mode_upload_test.py @@ -4,13 +4,13 @@ import unittest from .GuiReceiveTest import GuiReceiveTest -class ReceiveModeTest(unittest.TestCase, GuiReceiveTest): +class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): @classmethod def setUpClass(cls): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): diff --git a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py b/tests_gui/local_onionshare_share_mode_download_public_mode_test.py similarity index 76% rename from tests_gui_local/onionshare_share_mode_download_public_mode_test.py rename to tests_gui/local_onionshare_share_mode_download_public_mode_test.py index 96cadb90..6dcb94df 100644 --- a/tests_gui_local/onionshare_share_mode_download_public_mode_test.py +++ b/tests_gui/local_onionshare_share_mode_download_public_mode_test.py @@ -4,13 +4,13 @@ import unittest from .GuiShareTest import GuiShareTest -class ShareModePublicModeTest(unittest.TestCase, GuiShareTest): +class LocalShareModePublicModeTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { "public_mode": True, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePublicModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): diff --git a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py b/tests_gui/local_onionshare_share_mode_download_stay_open_test.py similarity index 77% rename from tests_gui_local/onionshare_share_mode_download_stay_open_test.py rename to tests_gui/local_onionshare_share_mode_download_stay_open_test.py index bb9ec2ea..62eafff7 100644 --- a/tests_gui_local/onionshare_share_mode_download_stay_open_test.py +++ b/tests_gui/local_onionshare_share_mode_download_stay_open_test.py @@ -4,13 +4,13 @@ import unittest from .GuiShareTest import GuiShareTest -class ShareModeStayOpenTest(unittest.TestCase, GuiShareTest): +class LocalShareModeStayOpenTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeStayOpenTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): diff --git a/tests_gui_local/onionshare_share_mode_download_test.py b/tests_gui/local_onionshare_share_mode_download_test.py similarity index 77% rename from tests_gui_local/onionshare_share_mode_download_test.py rename to tests_gui/local_onionshare_share_mode_download_test.py index 12b914b0..98270523 100644 --- a/tests_gui_local/onionshare_share_mode_download_test.py +++ b/tests_gui/local_onionshare_share_mode_download_test.py @@ -4,12 +4,12 @@ import unittest from .GuiShareTest import GuiShareTest -class ShareModeTest(unittest.TestCase, GuiShareTest): +class LocalShareModeTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTest') + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): diff --git a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py b/tests_gui/local_onionshare_share_mode_slug_persistent_test.py similarity index 79% rename from tests_gui_local/onionshare_share_mode_slug_persistent_test.py rename to tests_gui/local_onionshare_share_mode_slug_persistent_test.py index 25e4e093..9e171ba4 100644 --- a/tests_gui_local/onionshare_share_mode_slug_persistent_test.py +++ b/tests_gui/local_onionshare_share_mode_slug_persistent_test.py @@ -4,7 +4,7 @@ import unittest from .GuiShareTest import GuiShareTest -class ShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): +class LocalShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { @@ -13,7 +13,7 @@ class ShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePersistentSlugTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): diff --git a/tests_gui_local/onionshare_share_mode_timer_test.py b/tests_gui/local_onionshare_share_mode_timer_test.py similarity index 79% rename from tests_gui_local/onionshare_share_mode_timer_test.py rename to tests_gui/local_onionshare_share_mode_timer_test.py index 2e654c9d..b13971b0 100644 --- a/tests_gui_local/onionshare_share_mode_timer_test.py +++ b/tests_gui/local_onionshare_share_mode_timer_test.py @@ -4,14 +4,14 @@ import unittest from .GuiShareTest import GuiShareTest -class ShareModeTimerTest(unittest.TestCase, GuiShareTest): +class LocalShareModeTimerTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiShareTest.set_up(test_settings, 'ShareModeTimerTest') + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTimerTest') @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): diff --git a/tests_gui/onionshare_receive_mode_upload_public_mode_test.py b/tests_gui/onionshare_receive_mode_upload_public_mode_test.py new file mode 100644 index 00000000..8561cbce --- /dev/null +++ b/tests_gui/onionshare_receive_mode_upload_public_mode_test.py @@ -0,0 +1,27 @@ +#!/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, 'ReceiveModeTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_all_receive_mode_tests(self): + self.run_all_receive_mode_tests(True, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_receive_mode_upload_test.py b/tests_gui/onionshare_receive_mode_upload_test.py new file mode 100644 index 00000000..6dac4bc8 --- /dev/null +++ b/tests_gui/onionshare_receive_mode_upload_test.py @@ -0,0 +1,26 @@ +#!/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, 'ReceiveModeTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_all_receive_mode_tests(self): + self.run_all_receive_mode_tests(False, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_share_mode_download_public_mode_test.py b/tests_gui/onionshare_share_mode_download_public_mode_test.py new file mode 100644 index 00000000..3a17b47e --- /dev/null +++ b/tests_gui/onionshare_share_mode_download_public_mode_test.py @@ -0,0 +1,26 @@ +#!/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, 'ShareModePublicModeTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_all_share_mode_tests(self): + self.run_all_share_mode_tests(True, False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_share_mode_download_stay_open_test.py b/tests_gui/onionshare_share_mode_download_stay_open_test.py new file mode 100644 index 00000000..ddb513dd --- /dev/null +++ b/tests_gui/onionshare_share_mode_download_stay_open_test.py @@ -0,0 +1,26 @@ +#!/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, 'ShareModeStayOpenTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_all_share_mode_tests(self): + self.run_all_share_mode_tests(False, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_share_mode_download_test.py b/tests_gui/onionshare_share_mode_download_test.py new file mode 100644 index 00000000..17c94215 --- /dev/null +++ b/tests_gui/onionshare_share_mode_download_test.py @@ -0,0 +1,25 @@ +#!/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, 'ShareModeTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_all_share_mode_tests(self): + self.run_all_share_mode_tests(False, False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_share_mode_persistent_test.py b/tests_gui/onionshare_share_mode_persistent_test.py new file mode 100644 index 00000000..415ce42e --- /dev/null +++ b/tests_gui/onionshare_share_mode_persistent_test.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +import pytest +import unittest + +from .TorGuiShareTest import TorGuiShareTest + +class LocalShareModePersistentSlugTest(unittest.TestCase, TorGuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + "use_legacy_v2_onions": True, + "public_mode": False, + "slug": "", + "save_private_key": True, + "close_after_first_download": False, + } + cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_all_share_mode_tests(self): + self.run_all_share_mode_persistent_tests(False, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_share_mode_stealth_test.py b/tests_gui/onionshare_share_mode_stealth_test.py new file mode 100644 index 00000000..56303226 --- /dev/null +++ b/tests_gui/onionshare_share_mode_stealth_test.py @@ -0,0 +1,34 @@ +#!/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, 'ShareModeStealthTest') + + @pytest.mark.run(order=1) + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + def test_run_share_mode_setup_tests(self): + self.run_all_share_mode_setup_tests() + self.run_all_share_mode_started_tests(False) + + @pytest.mark.run(order=3) + def test_copy_have_hidserv_auth_button(self): + self.copy_have_hidserv_auth_button(self.gui.share_mode) + + @pytest.mark.run(order=4) + def test_hidserv_auth_string(self): + self.hidserv_auth_string() + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_share_mode_tor_connection_killed_test.py b/tests_gui/onionshare_share_mode_tor_connection_killed_test.py new file mode 100644 index 00000000..6ebdec97 --- /dev/null +++ b/tests_gui/onionshare_share_mode_tor_connection_killed_test.py @@ -0,0 +1,42 @@ +#!/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, 'ShareModeTorConnectionKilledTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_share_mode_setup_tests(self): + self.run_all_share_mode_setup_tests() + self.run_all_share_mode_started_tests(False) + + @pytest.mark.run(order=3) + @pytest.mark.tor + def test_tor_killed_statusbar_message_shown(self): + self.tor_killed_statusbar_message_shown(self.gui.share_mode) + + @pytest.mark.run(order=4) + @pytest.mark.tor + def test_server_is_stopped(self): + self.server_is_stopped(self.gui.share_mode, False) + + @pytest.mark.run(order=5) + @pytest.mark.tor + def test_web_service_is_stopped(self): + self.web_service_is_stopped() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui_tor/__init__.py b/tests_gui_tor/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests_gui_tor/commontests.py b/tests_gui_tor/commontests.py deleted file mode 100644 index 89ebf669..00000000 --- a/tests_gui_tor/commontests.py +++ /dev/null @@ -1,61 +0,0 @@ -import os -import requests -import socket -import socks -import zipfile - -from PyQt5 import QtCore, QtTest -from onionshare import strings - -from tests_gui_local import CommonTests as LocalCommonTests - -class CommonTests(LocalCommonTests): - def test_a_server_is_started(self, mode): - '''Test that the server has started (overriding from local tests to wait for longer)''' - QtTest.QTest.qWait(45000) - # Should now be in SERVER_STARTED state - if mode == 'receive': - self.assertEqual(self.gui.receive_mode.server_status.status, 2) - if mode == 'share': - self.assertEqual(self.gui.share_mode.server_status.status, 2) - - def test_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 test_cancel_the_share(self, mode): - '''Test that we can cancel this share before it's started up ''' - if mode == 'share': - QtTest.QTest.mousePress(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - QtTest.QTest.qWait(1000) - QtTest.QTest.mouseRelease(self.gui.share_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.share_mode.server_status.status, 0) - - if mode == 'receive': - QtTest.QTest.mousePress(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - QtTest.QTest.qWait(1000) - QtTest.QTest.mouseRelease(self.gui.receive_mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.receive_mode.server_status.status, 0) - - # Stealth tests - def test_copy_have_hidserv_auth_button(self, mode): - '''Test that the Copy HidservAuth button is shown''' - if mode == 'share': - self.assertTrue(self.gui.share_mode.server_status.copy_hidservauth_button.isVisible()) - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.server_status.copy_hidservauth_button.isVisible()) - - def test_hidserv_auth_string(self): - '''Test the validity of the HidservAuth string''' - self.assertRegex(self.gui.app.auth_string, r'HidServAuth %s [a-zA-Z1-9]' % self.gui.app.onion_host) - - - # Miscellaneous tests - def test_tor_killed_statusbar_message_shown(self, mode): - '''Test that the status bar message shows Tor was disconnected''' - self.gui.app.onion.cleanup(stop_tor=True) - QtTest.QTest.qWait(2500) - if mode == 'share': - self.assertTrue(self.gui.share_mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost')) - if mode == 'receive': - self.assertTrue(self.gui.receive_mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost')) diff --git a/tests_gui_tor/conftest.py b/tests_gui_tor/conftest.py deleted file mode 100644 index 3ae6fd52..00000000 --- a/tests_gui_tor/conftest.py +++ /dev/null @@ -1,163 +0,0 @@ -import sys -# Force tests to look for resources in the source code tree -sys.onionshare_dev_mode = True - -import os -import shutil -import tempfile - -import pytest - -from onionshare import common, web, settings, strings - -@pytest.fixture -def temp_dir_1024(): - """ Create a temporary directory that has a single file of a - particular size (1024 bytes). - """ - - tmp_dir = tempfile.mkdtemp() - tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) - with open(tmp_file, 'wb') as f: - f.write(b'*' * 1024) - return tmp_dir - - -# pytest > 2.9 only needs @pytest.fixture -@pytest.yield_fixture -def temp_dir_1024_delete(): - """ Create a temporary directory that has a single file of a - particular size (1024 bytes). The temporary directory (including - the file inside) will be deleted after fixture usage. - """ - - with tempfile.TemporaryDirectory() as tmp_dir: - tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) - with open(tmp_file, 'wb') as f: - f.write(b'*' * 1024) - yield tmp_dir - - -@pytest.fixture -def temp_file_1024(): - """ Create a temporary file of a particular size (1024 bytes). """ - - with tempfile.NamedTemporaryFile(delete=False) 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(): - """ - Create a temporary file of a particular size (1024 bytes). - The temporary file will be deleted after fixture usage. - """ - - with tempfile.NamedTemporaryFile() as tmp_file: - 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) - shutil.rmtree(tmp_dir) - - -@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(): - _common = common.Common() - _common.settings = settings.Settings(_common) - strings.load_strings(_common) - return _common - -@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) diff --git a/tests_gui_tor/onionshare_receive_mode_upload_test.py b/tests_gui_tor/onionshare_receive_mode_upload_test.py deleted file mode 100644 index 7c340037..00000000 --- a/tests_gui_tor/onionshare_receive_mode_upload_test.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - os.remove('/tmp/OnionShare/test.txt') - os.remove('/tmp/OnionShare/test-2.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=6) - def test_click_mode(self): - CommonTests.test_click_mode(self, 'receive') - - @pytest.mark.run(order=6) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'receive') - - @pytest.mark.run(order=7) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'receive') - - @pytest.mark.run(order=8) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'receive') - - @pytest.mark.run(order=8) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'receive') - - @pytest.mark.run(order=9) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'receive') - - @pytest.mark.run(order=10) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=11) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'receive') - - @pytest.mark.run(order=12) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=14) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'receive', False) - - @pytest.mark.run(order=15) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=20) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'receive') - - @pytest.mark.run(order=21) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'receive') - - @pytest.mark.run(order=22) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'receive') - - @pytest.mark.run(order=23) - def test_web_page(self): - CommonTests.test_web_page(self, 'receive', 'Select the files you want to send, then click', False) - - @pytest.mark.run(order=24) - def test_upload_file(self): - CommonTests.test_upload_file(self, False, '/tmp/OnionShare/test.txt') - - @pytest.mark.run(order=25) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'receive') - - @pytest.mark.run(order=26) - def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, 'receive', 1) - - @pytest.mark.run(order=27) - def test_upload_same_file_is_renamed(self): - CommonTests.test_upload_file(self, False, '/tmp/OnionShare/test-2.txt') - - @pytest.mark.run(order=28) - def test_upload_count_incremented_again(self): - CommonTests.test_counter_incremented(self, 'receive', 2) - - @pytest.mark.run(order=29) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'receive', False) - - @pytest.mark.run(order=30) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=31) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py b/tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py deleted file mode 100644 index 65bf5c89..00000000 --- a/tests_gui_tor/onionshare_receive_mode_upload_test_public_mode.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": True, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - os.remove('/tmp/OnionShare/test.txt') - os.remove('/tmp/OnionShare/test-2.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_click_mode(self): - CommonTests.test_click_mode(self, 'receive') - - @pytest.mark.run(order=6) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'receive') - - @pytest.mark.run(order=7) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'receive') - - @pytest.mark.run(order=8) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'receive') - - @pytest.mark.run(order=9) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'receive') - - @pytest.mark.run(order=10) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'receive') - - @pytest.mark.run(order=11) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=12) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'receive') - - @pytest.mark.run(order=13) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=14) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'receive', True) - - @pytest.mark.run(order=15) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=20) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'receive') - - @pytest.mark.run(order=21) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'receive') - - @pytest.mark.run(order=22) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'receive') - - @pytest.mark.run(order=23) - def test_web_page(self): - CommonTests.test_web_page(self, 'receive', 'Select the files you want to send, then click', True) - - @pytest.mark.run(order=24) - def test_upload_file(self): - CommonTests.test_upload_file(self, True, '/tmp/OnionShare/test.txt') - - @pytest.mark.run(order=25) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'receive') - - @pytest.mark.run(order=26) - def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, 'receive', 1) - - @pytest.mark.run(order=27) - def test_upload_same_file_is_renamed(self): - CommonTests.test_upload_file(self, True, '/tmp/OnionShare/test-2.txt') - - @pytest.mark.run(order=28) - def test_upload_count_incremented_again(self): - CommonTests.test_counter_incremented(self, 'receive', 2) - - @pytest.mark.run(order=29) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'receive', False) - - @pytest.mark.run(order=30) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=31) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'receive', False) - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_share_mode_download_test.py b/tests_gui_tor/onionshare_share_mode_download_test.py deleted file mode 100644 index 2bf26690..00000000 --- a/tests_gui_tor/onionshare_share_mode_download_test.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=11) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=12) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=13) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=14) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=15) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=16) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=17) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) - - @pytest.mark.run(order=18) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=19) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') - - @pytest.mark.run(order=20) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') - - @pytest.mark.run(order=21) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=22) - def test_web_page(self): - CommonTests.test_web_page(self, 'share', 'Total size', False) - - @pytest.mark.run(order=23) - def test_download_share(self): - CommonTests.test_download_share(self, False) - - @pytest.mark.run(order=24) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'share') - - @pytest.mark.run(order=25) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', False) - - @pytest.mark.run(order=26) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=27) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', False) - - @pytest.mark.run(order=28) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_share_mode_download_test_public_mode.py b/tests_gui_tor/onionshare_share_mode_download_test_public_mode.py deleted file mode 100644 index 4792994d..00000000 --- a/tests_gui_tor/onionshare_share_mode_download_test_public_mode.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": True, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', True) - - @pytest.mark.run(order=20) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=21) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') - - @pytest.mark.run(order=22) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') - - @pytest.mark.run(order=23) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=24) - def test_web_page(self): - CommonTests.test_web_page(self, 'share', 'Total size', True) - - @pytest.mark.run(order=25) - def test_download_share(self): - CommonTests.test_download_share(self, True) - - @pytest.mark.run(order=26) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'share') - - @pytest.mark.run(order=27) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', False) - - @pytest.mark.run(order=28) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=29) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', False) - - @pytest.mark.run(order=30) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_share_mode_download_test_stay_open.py b/tests_gui_tor/onionshare_share_mode_download_test_stay_open.py deleted file mode 100644 index 92d52169..00000000 --- a/tests_gui_tor/onionshare_share_mode_download_test_stay_open.py +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": False, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": True, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', True) - - @pytest.mark.run(order=20) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=21) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') - - @pytest.mark.run(order=22) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') - - @pytest.mark.run(order=23) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=24) - def test_web_page(self): - CommonTests.test_web_page(self, 'share', 'Total size', True) - - @pytest.mark.run(order=25) - def test_download_share(self): - CommonTests.test_download_share(self, True) - - @pytest.mark.run(order=26) - def test_history_widgets_present(self): - CommonTests.test_history_widgets_present(self, 'share') - - @pytest.mark.run(order=27) - def test_counter_incremented(self): - CommonTests.test_counter_incremented(self, 'share', 1) - - @pytest.mark.run(order=28) - def test_download_share_again(self): - CommonTests.test_download_share(self, True) - - @pytest.mark.run(order=29) - def test_counter_incremented_again(self): - CommonTests.test_counter_incremented(self, 'share', 2) - - @pytest.mark.run(order=30) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', True) - - @pytest.mark.run(order=31) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=32) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', True) - - @pytest.mark.run(order=33) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_share_mode_persistent_test.py b/tests_gui_tor/onionshare_share_mode_persistent_test.py deleted file mode 100644 index 6b9fbe16..00000000 --- a/tests_gui_tor/onionshare_share_mode_persistent_test.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - slug = '' - onion_host = '' - - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": True, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=11) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=12) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=13) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=14) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=15) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) - global slug - slug = self.gui.share_mode.server_status.web.slug - - @pytest.mark.run(order=16) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - global onion_host - onion_host = self.gui.app.onion_host - - @pytest.mark.run(order=17) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=18) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', True) - - @pytest.mark.run(order=19) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=20) - def test_server_status_indicator_says_closed(self): - CommonTests.test_server_status_indicator_says_closed(self, 'share', True) - - @pytest.mark.run(order=21) - def test_server_started_again(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - CommonTests.test_server_status_indicator_says_starting(self, 'share') - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=22) - def test_have_same_slug(self): - '''Test that we have the same slug''' - self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) - - @pytest.mark.run(order=23) - def test_have_same_onion(self): - '''Test that we have the same onion''' - self.assertEqual(self.gui.app.onion_host, onion_host) - - @pytest.mark.run(order=24) - def test_server_is_stopped_again(self): - CommonTests.test_server_is_stopped(self, 'share', True) - CommonTests.test_web_service_is_stopped(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_share_mode_stealth_test.py b/tests_gui_tor/onionshare_share_mode_stealth_test.py deleted file mode 100644 index 876efde2..00000000 --- a/tests_gui_tor/onionshare_share_mode_stealth_test.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": True, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) - - @pytest.mark.run(order=20) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=21) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') - - @pytest.mark.run(order=22) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') - - @pytest.mark.run(order=23) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=24) - def test_copy_have_hidserv_auth_button(self): - CommonTests.test_copy_have_hidserv_auth_button(self, 'share') - - @pytest.mark.run(order=25) - def test_hidserv_auth_string(self): - CommonTests.test_hidserv_auth_string(self) - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py b/tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py deleted file mode 100644 index 37abc825..00000000 --- a/tests_gui_tor/onionshare_share_mode_tor_connection_killed_test.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) - - @pytest.mark.run(order=20) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=21) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') - - @pytest.mark.run(order=22) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') - - @pytest.mark.run(order=23) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=24) - def test_tor_killed_statusbar_message_shown(self): - CommonTests.test_tor_killed_statusbar_message_shown(self, 'share') - - @pytest.mark.run(order=25) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', False) - - @pytest.mark.run(order=26) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_tor_connection_killed_test.py b/tests_gui_tor/onionshare_tor_connection_killed_test.py deleted file mode 100644 index 37abc825..00000000 --- a/tests_gui_tor/onionshare_tor_connection_killed_test.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=11) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=12) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=13) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=14) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=15) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=16) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=17) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=18) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=19) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) - - @pytest.mark.run(order=20) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=21) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') - - @pytest.mark.run(order=22) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') - - @pytest.mark.run(order=23) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=24) - def test_tor_killed_statusbar_message_shown(self): - CommonTests.test_tor_killed_statusbar_message_shown(self, 'share') - - @pytest.mark.run(order=25) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', False) - - @pytest.mark.run(order=26) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/run_unit_tests.sh b/tests_gui_tor/run_unit_tests.sh deleted file mode 100755 index 7d207a57..00000000 --- a/tests_gui_tor/run_unit_tests.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -for test in `ls -1 | egrep ^onionshare_`; do - pytest $test -vvv || exit 1 -done From 5a4222517961c1d2f06e421e40b61d035d4b8d39 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 18:56:30 +1100 Subject: [PATCH 079/142] add tor marker on the stealth test --- tests_gui/onionshare_share_mode_stealth_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests_gui/onionshare_share_mode_stealth_test.py b/tests_gui/onionshare_share_mode_stealth_test.py index 56303226..9e4ffa1f 100644 --- a/tests_gui/onionshare_share_mode_stealth_test.py +++ b/tests_gui/onionshare_share_mode_stealth_test.py @@ -14,19 +14,23 @@ class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStealthTest') @pytest.mark.run(order=1) + @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() @pytest.mark.run(order=2) + @pytest.mark.tor def test_run_share_mode_setup_tests(self): self.run_all_share_mode_setup_tests() self.run_all_share_mode_started_tests(False) @pytest.mark.run(order=3) + @pytest.mark.tor def test_copy_have_hidserv_auth_button(self): self.copy_have_hidserv_auth_button(self.gui.share_mode) @pytest.mark.run(order=4) + @pytest.mark.tor def test_hidserv_auth_string(self): self.hidserv_auth_string() From bea0aaf6fcff0f3bfb4432f3495fbb9ea6da6cb4 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 19:01:50 +1100 Subject: [PATCH 080/142] cancel share test in Tor --- ...onionshare_share_mode_cancel_share_test.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests_gui/onionshare_share_mode_cancel_share_test.py diff --git a/tests_gui/onionshare_share_mode_cancel_share_test.py b/tests_gui/onionshare_share_mode_cancel_share_test.py new file mode 100644 index 00000000..62dbc8ad --- /dev/null +++ b/tests_gui/onionshare_share_mode_cancel_share_test.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +import pytest +import unittest + +from .TorGuiShareTest import TorGuiShareTest + +class ShareModeCancelTest(unittest.TestCase, TorGuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + } + cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_share_mode_setup_tests(self): + self.run_all_share_mode_setup_tests() + + @pytest.mark.run(order=3) + @pytest.mark.tor + def test_cancel_the_share(self): + self.cancel_the_share(self.gui.share_mode) + +if __name__ == "__main__": + unittest.main() From 37e77b832489913bcc3d0e4c527c33cd5acd9335 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 12 Oct 2018 20:44:10 +1100 Subject: [PATCH 081/142] Commit missing test changes for canceling a share --- tests_gui/TorGuiBaseTest.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests_gui/TorGuiBaseTest.py b/tests_gui/TorGuiBaseTest.py index 1c313726..b182b1d4 100644 --- a/tests_gui/TorGuiBaseTest.py +++ b/tests_gui/TorGuiBaseTest.py @@ -132,10 +132,17 @@ class TorGuiBaseTest(GuiBaseTest): def cancel_the_share(self, mode): '''Test that we can cancel this share before it's started up ''' - QtTest.QTest.mousePress(self.gui.mode.server_status.server_button, QtCore.Qt.LeftButton) + 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() + QtTest.QTest.mousePress(mode.server_status.server_button, QtCore.Qt.LeftButton) QtTest.QTest.qWait(1000) - QtTest.QTest.mouseRelease(self.gui.mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEqual(self.gui.mode.server_status.status, 0) + QtTest.QTest.mouseRelease(mode.server_status.server_button, QtCore.Qt.LeftButton) + self.assertEqual(mode.server_status.status, 0) + self.server_is_stopped(self.gui.share_mode, False) + self.web_service_is_stopped() + # Stealth tests def copy_have_hidserv_auth_button(self, mode): From 966ade5dda3dfc33a46e1862c87b9162a8210fb0 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sat, 13 Oct 2018 09:49:05 +1100 Subject: [PATCH 082/142] add the other Tor tests into tests_gui and refactor them. Reinstate the shell script for the sake of Travis --- .travis.yml | 2 +- tests_gui/TorGuiShareTest.py | 4 +- ...onshare_790_cancel_on_second_share_test.py | 49 +++++ tests_gui/onionshare_share_mode_timer_test.py | 27 +++ tests_gui/run_unit_tests.sh | 5 + ...onshare_790_cancel_on_second_share_test.py | 197 ------------------ ...onionshare_share_mode_cancel_share_test.py | 149 ------------- tests_gui_tor/onionshare_timer_test.py | 148 ------------- 8 files changed, 84 insertions(+), 497 deletions(-) create mode 100644 tests_gui/onionshare_790_cancel_on_second_share_test.py create mode 100644 tests_gui/onionshare_share_mode_timer_test.py create mode 100755 tests_gui/run_unit_tests.sh delete mode 100644 tests_gui_tor/onionshare_790_cancel_on_second_share_test.py delete mode 100644 tests_gui_tor/onionshare_share_mode_cancel_share_test.py delete mode 100644 tests_gui_tor/onionshare_timer_test.py diff --git a/.travis.yml b/.travis.yml index c54c205d..c9bc90ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,4 @@ before_script: # run CLI tests and local GUI tests script: - pytest --cov=onionshare tests/ - - xvfb-run pytest tests_gui/ -vvv + - cd tests_gui && xvfb-run ./run_unit_tests.sh diff --git a/tests_gui/TorGuiShareTest.py b/tests_gui/TorGuiShareTest.py index 8d6358c3..8e17abad 100644 --- a/tests_gui/TorGuiShareTest.py +++ b/tests_gui/TorGuiShareTest.py @@ -62,9 +62,9 @@ class TorGuiShareTest(TorGuiBaseTest, GuiShareTest): 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.set_timeout(self.gui.share_mode, 120) self.run_all_share_mode_started_tests(public_mode) self.timeout_widget_hidden(self.gui.share_mode) - self.server_timed_out(self.gui.share_mode, 10000) + self.server_timed_out(self.gui.share_mode, 125000) self.web_service_is_stopped() diff --git a/tests_gui/onionshare_790_cancel_on_second_share_test.py b/tests_gui/onionshare_790_cancel_on_second_share_test.py new file mode 100644 index 00000000..d3a1e797 --- /dev/null +++ b/tests_gui/onionshare_790_cancel_on_second_share_test.py @@ -0,0 +1,49 @@ +#!/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, 'ShareModeCancelSecondShareTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_share_mode_tests(self): + self.run_all_share_mode_tests(False, False) + + # Stop the share in order to test canceling the next share + #@pytest.mark.run(order=3) + #@pytest.mark.tor + #def test_stop_share(self): + # self.server_is_stopped(self.gui.share_mode, True) + # self.web_service_is_stopped() + + @pytest.mark.run(order=4) + @pytest.mark.tor + def test_cancel_the_share(self): + self.cancel_the_share(self.gui.share_mode) + + @pytest.mark.run(order=5) + @pytest.mark.tor + def test_server_is_stopped_round2(self): + self.server_is_stopped(self.gui.share_mode, False) + + @pytest.mark.run(order=6) + @pytest.mark.tor + def test_web_service_is_stopped_round2(self): + self.web_service_is_stopped() + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/onionshare_share_mode_timer_test.py b/tests_gui/onionshare_share_mode_timer_test.py new file mode 100644 index 00000000..d0b4f4cd --- /dev/null +++ b/tests_gui/onionshare_share_mode_timer_test.py @@ -0,0 +1,27 @@ +#!/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, + "shutdown_timeout": True, + } + cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTimerTest') + + @pytest.mark.run(order=1) + @pytest.mark.tor + def test_run_all_common_setup_tests(self): + self.run_all_common_setup_tests() + + @pytest.mark.run(order=2) + @pytest.mark.tor + def test_run_all_share_mode_timer_tests(self): + self.run_all_share_mode_timer_tests(False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests_gui/run_unit_tests.sh b/tests_gui/run_unit_tests.sh new file mode 100755 index 00000000..81542749 --- /dev/null +++ b/tests_gui/run_unit_tests.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +for test in `ls -1 | egrep ^local_`; do + pytest $test -vvv || exit 1 +done diff --git a/tests_gui_tor/onionshare_790_cancel_on_second_share_test.py b/tests_gui_tor/onionshare_790_cancel_on_second_share_test.py deleted file mode 100644 index 731de4fd..00000000 --- a/tests_gui_tor/onionshare_790_cancel_on_second_share_test.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_is_visible(self): - CommonTests.test_info_widget_is_visible(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=9) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=10) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=11) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=12) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=13) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=14) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=15) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=16) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=17) - def test_have_a_slug(self): - CommonTests.test_have_a_slug(self, 'share', False) - - @pytest.mark.run(order=18) - def test_have_an_onion(self): - CommonTests.test_have_an_onion_service(self) - - @pytest.mark.run(order=19) - def test_url_description_shown(self): - CommonTests.test_url_description_shown(self, 'share') - - @pytest.mark.run(order=20) - def test_have_copy_url_button(self): - CommonTests.test_have_copy_url_button(self, 'share') - - @pytest.mark.run(order=21) - def test_server_status_indicator_says_started(self): - CommonTests.test_server_status_indicator_says_started(self, 'share') - - @pytest.mark.run(order=22) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', True) - - @pytest.mark.run(order=23) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=24) - def test_server_working_on_start_button_pressed_round2(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=25) - def test_server_status_indicator_says_starting_round2(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=26) - def test_cancel_the_share(self): - CommonTests.test_cancel_the_share(self, 'share') - - @pytest.mark.run(order=27) - def test_server_is_stopped_round2(self): - CommonTests.test_server_is_stopped(self, 'share', False) - - @pytest.mark.run(order=28) - def test_web_service_is_stopped_round2(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=29) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_share_mode_cancel_share_test.py b/tests_gui_tor/onionshare_share_mode_cancel_share_test.py deleted file mode 100644 index cdab8f85..00000000 --- a/tests_gui_tor/onionshare_share_mode_cancel_share_test.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": False, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=8) - def test_deleting_only_file_hides_delete_button(self): - CommonTests.test_deleting_only_file_hides_delete_button(self) - - @pytest.mark.run(order=9) - def test_add_a_file_and_delete_using_its_delete_widget(self): - CommonTests.test_add_a_file_and_delete_using_its_delete_widget(self) - - @pytest.mark.run(order=10) - def test_file_selection_widget_readd_files(self): - CommonTests.test_file_selection_widget_readd_files(self) - - @pytest.mark.run(order=11) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=12) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=13) - def test_add_delete_buttons_hidden(self): - CommonTests.test_add_delete_buttons_hidden(self) - - @pytest.mark.run(order=14) - def test_settings_button_is_hidden(self): - CommonTests.test_settings_button_is_hidden(self) - - @pytest.mark.run(order=16) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=17) - def test_cancel_the_share(self): - CommonTests.test_cancel_the_share(self, 'share') - - @pytest.mark.run(order=18) - def test_server_is_stopped(self): - CommonTests.test_server_is_stopped(self, 'share', False) - - @pytest.mark.run(order=19) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - - @pytest.mark.run(order=20) - def test_add_button_visible(self): - CommonTests.test_add_button_visible(self) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests_gui_tor/onionshare_timer_test.py b/tests_gui_tor/onionshare_timer_test.py deleted file mode 100644 index 2b64b998..00000000 --- a/tests_gui_tor/onionshare_timer_test.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys -import unittest -import pytest -import json - -from PyQt5 import QtWidgets - -from onionshare.common import Common -from onionshare.web import Web -from onionshare import onion, strings -from onionshare_gui import * - -from .commontests import CommonTests - -class OnionShareGuiTest(unittest.TestCase): - '''Test the OnionShare GUI''' - @classmethod - def setUpClass(cls): - '''Create the GUI''' - # Create our test file - testfile = open('/tmp/test.txt', 'w') - testfile.write('onionshare') - testfile.close() - common = Common() - common.define_css() - - # Start the Onion - strings.load_strings(common) - - testonion = onion.Onion(common) - global qtapp - qtapp = Application(common) - app = OnionShare(common, testonion, False, 0) - - web = Web(common, False, True) - - test_settings = { - "auth_password": "", - "auth_type": "no_auth", - "autoupdate_timestamp": "", - "close_after_first_download": True, - "connection_type": "bundled", - "control_port_address": "127.0.0.1", - "control_port_port": 9051, - "downloads_dir": "/tmp/OnionShare", - "hidservauth_string": "", - "no_bridges": True, - "private_key": "", - "public_mode": False, - "receive_allow_receiver_shutdown": True, - "save_private_key": False, - "shutdown_timeout": True, - "slug": "", - "socks_address": "127.0.0.1", - "socks_port": 9050, - "socket_file_path": "/var/run/tor/control", - "systray_notifications": True, - "tor_bridges_use_meek_lite_azure": False, - "tor_bridges_use_meek_lite_amazon": False, - "tor_bridges_use_custom_bridges": "", - "tor_bridges_use_obfs4": False, - "use_stealth": False, - "use_legacy_v2_onions": False, - "use_autoupdate": True, - "version": "1.3.1" - } - testsettings = '/tmp/testsettings.json' - open(testsettings, 'w').write(json.dumps(test_settings)) - - cls.gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], testsettings, False) - - @classmethod - def tearDownClass(cls): - '''Clean up after tests''' - os.remove('/tmp/test.txt') - - @pytest.mark.run(order=1) - def test_gui_loaded(self): - CommonTests.test_gui_loaded(self) - - @pytest.mark.run(order=2) - def test_windowTitle_seen(self): - CommonTests.test_windowTitle_seen(self) - - @pytest.mark.run(order=3) - def test_settings_button_is_visible(self): - CommonTests.test_settings_button_is_visible(self) - - @pytest.mark.run(order=4) - def test_server_status_bar_is_visible(self): - CommonTests.test_server_status_bar_is_visible(self) - - @pytest.mark.run(order=5) - def test_file_selection_widget_has_a_file(self): - CommonTests.test_file_selection_widget_has_a_file(self) - - @pytest.mark.run(order=6) - def test_info_widget_shows_less(self): - CommonTests.test_info_widget_shows_less(self, 'share') - - @pytest.mark.run(order=7) - def test_history_is_not_visible(self): - CommonTests.test_history_is_not_visible(self, 'share') - - @pytest.mark.run(order=8) - def test_click_toggle_history(self): - CommonTests.test_click_toggle_history(self, 'share') - - @pytest.mark.run(order=9) - def test_history_is_visible(self): - CommonTests.test_history_is_visible(self, 'share') - - @pytest.mark.run(order=10) - def test_set_timeout(self): - CommonTests.test_set_timeout(self, 'share', 120) - - @pytest.mark.run(order=11) - def test_server_working_on_start_button_pressed(self): - CommonTests.test_server_working_on_start_button_pressed(self, 'share') - - @pytest.mark.run(order=12) - def test_server_status_indicator_says_starting(self): - CommonTests.test_server_status_indicator_says_starting(self, 'share') - - @pytest.mark.run(order=13) - def test_a_server_is_started(self): - CommonTests.test_a_server_is_started(self, 'share') - - @pytest.mark.run(order=14) - def test_a_web_server_is_running(self): - CommonTests.test_a_web_server_is_running(self) - - @pytest.mark.run(order=15) - def test_timeout_widget_hidden(self): - CommonTests.test_timeout_widget_hidden(self, 'share') - - @pytest.mark.run(order=16) - def test_timeout(self): - CommonTests.test_server_timed_out(self, 'share', 125000) - - @pytest.mark.run(order=17) - def test_web_service_is_stopped(self): - CommonTests.test_web_service_is_stopped(self) - -if __name__ == "__main__": - unittest.main() From 2a00656fd6d46be750888e50c802fd086bee4544 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sat, 13 Oct 2018 10:03:15 +1100 Subject: [PATCH 083/142] Another attempt at changing pytest ordering so that pytest can run without shell script --- .travis.yml | 2 +- ...share_receive_mode_upload_public_mode_test.py | 3 +-- .../local_onionshare_receive_mode_upload_test.py | 3 +-- ...share_share_mode_download_public_mode_test.py | 3 +-- ...onshare_share_mode_download_stay_open_test.py | 3 +-- .../local_onionshare_share_mode_download_test.py | 3 +-- ...onionshare_share_mode_slug_persistent_test.py | 3 +-- .../local_onionshare_share_mode_timer_test.py | 3 +-- ...onionshare_790_cancel_on_second_share_test.py | 16 ++++------------ ...share_receive_mode_upload_public_mode_test.py | 3 +-- tests_gui/onionshare_receive_mode_upload_test.py | 3 +-- .../onionshare_share_mode_cancel_share_test.py | 5 ++--- ...share_share_mode_download_public_mode_test.py | 3 +-- ...onshare_share_mode_download_stay_open_test.py | 3 +-- tests_gui/onionshare_share_mode_download_test.py | 3 +-- .../onionshare_share_mode_persistent_test.py | 3 +-- tests_gui/onionshare_share_mode_stealth_test.py | 7 +++---- tests_gui/onionshare_share_mode_timer_test.py | 3 +-- ...hare_share_mode_tor_connection_killed_test.py | 9 ++++----- 19 files changed, 28 insertions(+), 53 deletions(-) diff --git a/.travis.yml b/.travis.yml index c9bc90ae..118aa147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,4 +20,4 @@ before_script: # run CLI tests and local GUI tests script: - pytest --cov=onionshare tests/ - - cd tests_gui && xvfb-run ./run_unit_tests.sh + - xvfb-run pytest tests_gui/ diff --git a/tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py b/tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py index 1b5722c7..27bf9b2c 100644 --- a/tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py +++ b/tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py @@ -13,11 +13,10 @@ class LocalReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModePublicModeTest') - @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(True, True) diff --git a/tests_gui/local_onionshare_receive_mode_upload_test.py b/tests_gui/local_onionshare_receive_mode_upload_test.py index 14a0377d..f6594105 100644 --- a/tests_gui/local_onionshare_receive_mode_upload_test.py +++ b/tests_gui/local_onionshare_receive_mode_upload_test.py @@ -12,11 +12,10 @@ class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') - @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(False, True) diff --git a/tests_gui/local_onionshare_share_mode_download_public_mode_test.py b/tests_gui/local_onionshare_share_mode_download_public_mode_test.py index 6dcb94df..2a3f9584 100644 --- a/tests_gui/local_onionshare_share_mode_download_public_mode_test.py +++ b/tests_gui/local_onionshare_share_mode_download_public_mode_test.py @@ -12,11 +12,10 @@ class LocalShareModePublicModeTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePublicModeTest') - @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(True, False) diff --git a/tests_gui/local_onionshare_share_mode_download_stay_open_test.py b/tests_gui/local_onionshare_share_mode_download_stay_open_test.py index 62eafff7..1f734ae7 100644 --- a/tests_gui/local_onionshare_share_mode_download_stay_open_test.py +++ b/tests_gui/local_onionshare_share_mode_download_stay_open_test.py @@ -12,11 +12,10 @@ class LocalShareModeStayOpenTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeStayOpenTest') - @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, True) diff --git a/tests_gui/local_onionshare_share_mode_download_test.py b/tests_gui/local_onionshare_share_mode_download_test.py index 98270523..274cc311 100644 --- a/tests_gui/local_onionshare_share_mode_download_test.py +++ b/tests_gui/local_onionshare_share_mode_download_test.py @@ -11,11 +11,10 @@ class LocalShareModeTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') - @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, False) diff --git a/tests_gui/local_onionshare_share_mode_slug_persistent_test.py b/tests_gui/local_onionshare_share_mode_slug_persistent_test.py index 9e171ba4..3450ec3f 100644 --- a/tests_gui/local_onionshare_share_mode_slug_persistent_test.py +++ b/tests_gui/local_onionshare_share_mode_slug_persistent_test.py @@ -15,11 +15,10 @@ class LocalShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePersistentSlugTest') - @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') def test_run_all_share_mode_tests(self): self.run_all_share_mode_persistent_tests(False, True) diff --git a/tests_gui/local_onionshare_share_mode_timer_test.py b/tests_gui/local_onionshare_share_mode_timer_test.py index b13971b0..f9f36c48 100644 --- a/tests_gui/local_onionshare_share_mode_timer_test.py +++ b/tests_gui/local_onionshare_share_mode_timer_test.py @@ -13,11 +13,10 @@ class LocalShareModeTimerTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTimerTest') - @pytest.mark.run(order=1) def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') def test_run_all_share_mode_timer_tests(self): self.run_all_share_mode_timer_tests(False) diff --git a/tests_gui/onionshare_790_cancel_on_second_share_test.py b/tests_gui/onionshare_790_cancel_on_second_share_test.py index d3a1e797..36725fb0 100644 --- a/tests_gui/onionshare_790_cancel_on_second_share_test.py +++ b/tests_gui/onionshare_790_cancel_on_second_share_test.py @@ -13,34 +13,26 @@ class ShareModeCancelSecondShareTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelSecondShareTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_share_mode_tests(self): self.run_all_share_mode_tests(False, False) - # Stop the share in order to test canceling the next share - #@pytest.mark.run(order=3) - #@pytest.mark.tor - #def test_stop_share(self): - # self.server_is_stopped(self.gui.share_mode, True) - # self.web_service_is_stopped() - - @pytest.mark.run(order=4) + @pytest.mark.run(after='test_run_share_mode_tests') @pytest.mark.tor def test_cancel_the_share(self): self.cancel_the_share(self.gui.share_mode) - @pytest.mark.run(order=5) + @pytest.mark.run(after='test_cancel_the_share') @pytest.mark.tor def test_server_is_stopped_round2(self): self.server_is_stopped(self.gui.share_mode, False) - @pytest.mark.run(order=6) + @pytest.mark.run(after='test_server_is_stopped_round2') @pytest.mark.tor def test_web_service_is_stopped_round2(self): self.web_service_is_stopped() diff --git a/tests_gui/onionshare_receive_mode_upload_public_mode_test.py b/tests_gui/onionshare_receive_mode_upload_public_mode_test.py index 8561cbce..ee0c5c34 100644 --- a/tests_gui/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests_gui/onionshare_receive_mode_upload_public_mode_test.py @@ -13,12 +13,11 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): } cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(True, True) diff --git a/tests_gui/onionshare_receive_mode_upload_test.py b/tests_gui/onionshare_receive_mode_upload_test.py index 6dac4bc8..f1f683cc 100644 --- a/tests_gui/onionshare_receive_mode_upload_test.py +++ b/tests_gui/onionshare_receive_mode_upload_test.py @@ -12,12 +12,11 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): } cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(False, True) diff --git a/tests_gui/onionshare_share_mode_cancel_share_test.py b/tests_gui/onionshare_share_mode_cancel_share_test.py index 62dbc8ad..97adf9ce 100644 --- a/tests_gui/onionshare_share_mode_cancel_share_test.py +++ b/tests_gui/onionshare_share_mode_cancel_share_test.py @@ -11,17 +11,16 @@ class ShareModeCancelTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_share_mode_setup_tests(self): self.run_all_share_mode_setup_tests() - @pytest.mark.run(order=3) + @pytest.mark.run(after='test_run_share_mode_setup_tests') @pytest.mark.tor def test_cancel_the_share(self): self.cancel_the_share(self.gui.share_mode) diff --git a/tests_gui/onionshare_share_mode_download_public_mode_test.py b/tests_gui/onionshare_share_mode_download_public_mode_test.py index 3a17b47e..a4a3bfb1 100644 --- a/tests_gui/onionshare_share_mode_download_public_mode_test.py +++ b/tests_gui/onionshare_share_mode_download_public_mode_test.py @@ -12,12 +12,11 @@ class ShareModePublicModeTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(True, False) diff --git a/tests_gui/onionshare_share_mode_download_stay_open_test.py b/tests_gui/onionshare_share_mode_download_stay_open_test.py index ddb513dd..33544217 100644 --- a/tests_gui/onionshare_share_mode_download_stay_open_test.py +++ b/tests_gui/onionshare_share_mode_download_stay_open_test.py @@ -12,12 +12,11 @@ class ShareModeStayOpenTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, True) diff --git a/tests_gui/onionshare_share_mode_download_test.py b/tests_gui/onionshare_share_mode_download_test.py index 17c94215..8d6d9655 100644 --- a/tests_gui/onionshare_share_mode_download_test.py +++ b/tests_gui/onionshare_share_mode_download_test.py @@ -11,12 +11,11 @@ class ShareModeTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, False) diff --git a/tests_gui/onionshare_share_mode_persistent_test.py b/tests_gui/onionshare_share_mode_persistent_test.py index 415ce42e..665aecd5 100644 --- a/tests_gui/onionshare_share_mode_persistent_test.py +++ b/tests_gui/onionshare_share_mode_persistent_test.py @@ -16,12 +16,11 @@ class LocalShareModePersistentSlugTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_all_share_mode_tests(self): self.run_all_share_mode_persistent_tests(False, True) diff --git a/tests_gui/onionshare_share_mode_stealth_test.py b/tests_gui/onionshare_share_mode_stealth_test.py index 9e4ffa1f..a6bbe08e 100644 --- a/tests_gui/onionshare_share_mode_stealth_test.py +++ b/tests_gui/onionshare_share_mode_stealth_test.py @@ -13,23 +13,22 @@ class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStealthTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_share_mode_setup_tests(self): self.run_all_share_mode_setup_tests() self.run_all_share_mode_started_tests(False) - @pytest.mark.run(order=3) + @pytest.mark.run(after='test_run_share_mode_setup_tests') @pytest.mark.tor def test_copy_have_hidserv_auth_button(self): self.copy_have_hidserv_auth_button(self.gui.share_mode) - @pytest.mark.run(order=4) + @pytest.mark.run(after='test_run_share_mode_setup_tests') @pytest.mark.tor def test_hidserv_auth_string(self): self.hidserv_auth_string() diff --git a/tests_gui/onionshare_share_mode_timer_test.py b/tests_gui/onionshare_share_mode_timer_test.py index d0b4f4cd..32e28c00 100644 --- a/tests_gui/onionshare_share_mode_timer_test.py +++ b/tests_gui/onionshare_share_mode_timer_test.py @@ -13,12 +13,11 @@ class ShareModeTimerTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTimerTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_all_share_mode_timer_tests(self): self.run_all_share_mode_timer_tests(False) diff --git a/tests_gui/onionshare_share_mode_tor_connection_killed_test.py b/tests_gui/onionshare_share_mode_tor_connection_killed_test.py index 6ebdec97..9112aedd 100644 --- a/tests_gui/onionshare_share_mode_tor_connection_killed_test.py +++ b/tests_gui/onionshare_share_mode_tor_connection_killed_test.py @@ -11,28 +11,27 @@ class ShareModeTorConnectionKilledTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTorConnectionKilledTest') - @pytest.mark.run(order=1) @pytest.mark.tor def test_run_all_common_setup_tests(self): self.run_all_common_setup_tests() - @pytest.mark.run(order=2) + @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor def test_run_share_mode_setup_tests(self): self.run_all_share_mode_setup_tests() self.run_all_share_mode_started_tests(False) - @pytest.mark.run(order=3) + @pytest.mark.run(after='test_run_share_mode_setup_tests') @pytest.mark.tor def test_tor_killed_statusbar_message_shown(self): self.tor_killed_statusbar_message_shown(self.gui.share_mode) - @pytest.mark.run(order=4) + @pytest.mark.run(after='test_tor_killed_statusbar_message_shown') @pytest.mark.tor def test_server_is_stopped(self): self.server_is_stopped(self.gui.share_mode, False) - @pytest.mark.run(order=5) + @pytest.mark.run(after='test_tor_killed_statusbar_message_shown') @pytest.mark.tor def test_web_service_is_stopped(self): self.web_service_is_stopped() From e3459a5136098b12a13fa522228e41dd0787dec9 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sat, 13 Oct 2018 10:35:09 +1100 Subject: [PATCH 084/142] Move GUI tests into tests/ dir and fix conftest related stuff so everything loads what it needs and passes --- .travis.yml | 3 +- {tests_gui => tests}/GuiBaseTest.py | 0 {tests_gui => tests}/GuiReceiveTest.py | 0 {tests_gui => tests}/GuiShareTest.py | 0 {tests_gui => tests}/TorGuiBaseTest.py | 0 {tests_gui => tests}/TorGuiReceiveTest.py | 0 {tests_gui => tests}/TorGuiShareTest.py | 0 tests/conftest.py | 22 ++- ...re_receive_mode_upload_public_mode_test.py | 0 ...cal_onionshare_receive_mode_upload_test.py | 0 ...re_share_mode_download_public_mode_test.py | 0 ...hare_share_mode_download_stay_open_test.py | 0 ...cal_onionshare_share_mode_download_test.py | 0 ...onshare_share_mode_slug_persistent_test.py | 0 .../local_onionshare_share_mode_timer_test.py | 0 ...onshare_790_cancel_on_second_share_test.py | 0 ...re_receive_mode_upload_public_mode_test.py | 0 .../onionshare_receive_mode_upload_test.py | 0 ...onionshare_share_mode_cancel_share_test.py | 0 ...re_share_mode_download_public_mode_test.py | 0 ...hare_share_mode_download_stay_open_test.py | 0 .../onionshare_share_mode_download_test.py | 0 .../onionshare_share_mode_persistent_test.py | 0 .../onionshare_share_mode_stealth_test.py | 0 .../onionshare_share_mode_timer_test.py | 0 ...e_share_mode_tor_connection_killed_test.py | 0 tests/test_onionshare_strings.py | 5 +- tests/test_onionshare_web.py | 3 +- tests_gui/__init__.py | 0 tests_gui/conftest.py | 176 ------------------ tests_gui/run_unit_tests.sh | 5 - 31 files changed, 25 insertions(+), 189 deletions(-) rename {tests_gui => tests}/GuiBaseTest.py (100%) rename {tests_gui => tests}/GuiReceiveTest.py (100%) rename {tests_gui => tests}/GuiShareTest.py (100%) rename {tests_gui => tests}/TorGuiBaseTest.py (100%) rename {tests_gui => tests}/TorGuiReceiveTest.py (100%) rename {tests_gui => tests}/TorGuiShareTest.py (100%) rename {tests_gui => tests}/local_onionshare_receive_mode_upload_public_mode_test.py (100%) rename {tests_gui => tests}/local_onionshare_receive_mode_upload_test.py (100%) rename {tests_gui => tests}/local_onionshare_share_mode_download_public_mode_test.py (100%) rename {tests_gui => tests}/local_onionshare_share_mode_download_stay_open_test.py (100%) rename {tests_gui => tests}/local_onionshare_share_mode_download_test.py (100%) rename {tests_gui => tests}/local_onionshare_share_mode_slug_persistent_test.py (100%) rename {tests_gui => tests}/local_onionshare_share_mode_timer_test.py (100%) rename {tests_gui => tests}/onionshare_790_cancel_on_second_share_test.py (100%) rename {tests_gui => tests}/onionshare_receive_mode_upload_public_mode_test.py (100%) rename {tests_gui => tests}/onionshare_receive_mode_upload_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_cancel_share_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_download_public_mode_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_download_stay_open_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_download_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_persistent_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_stealth_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_timer_test.py (100%) rename {tests_gui => tests}/onionshare_share_mode_tor_connection_killed_test.py (100%) delete mode 100644 tests_gui/__init__.py delete mode 100644 tests_gui/conftest.py delete mode 100755 tests_gui/run_unit_tests.sh diff --git a/.travis.yml b/.travis.yml index 118aa147..ec7ba912 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,5 +19,4 @@ before_script: - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics # run CLI tests and local GUI tests script: - - pytest --cov=onionshare tests/ - - xvfb-run pytest tests_gui/ + - xvfb-run pytest --cov=onionshare --cov=onionshare_gui -vvv tests/ diff --git a/tests_gui/GuiBaseTest.py b/tests/GuiBaseTest.py similarity index 100% rename from tests_gui/GuiBaseTest.py rename to tests/GuiBaseTest.py diff --git a/tests_gui/GuiReceiveTest.py b/tests/GuiReceiveTest.py similarity index 100% rename from tests_gui/GuiReceiveTest.py rename to tests/GuiReceiveTest.py diff --git a/tests_gui/GuiShareTest.py b/tests/GuiShareTest.py similarity index 100% rename from tests_gui/GuiShareTest.py rename to tests/GuiShareTest.py diff --git a/tests_gui/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py similarity index 100% rename from tests_gui/TorGuiBaseTest.py rename to tests/TorGuiBaseTest.py diff --git a/tests_gui/TorGuiReceiveTest.py b/tests/TorGuiReceiveTest.py similarity index 100% rename from tests_gui/TorGuiReceiveTest.py rename to tests/TorGuiReceiveTest.py diff --git a/tests_gui/TorGuiShareTest.py b/tests/TorGuiShareTest.py similarity index 100% rename from tests_gui/TorGuiShareTest.py rename to tests/TorGuiShareTest.py diff --git a/tests/conftest.py b/tests/conftest.py index 3ae6fd52..688b22d8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,6 +10,22 @@ import pytest from onionshare import common, web, settings, strings +def pytest_addoption(parser): + parser.addoption( + "--runtor", action="store_true", default=False, help="run tor tests" + ) + + +def pytest_collection_modifyitems(config, items): + if config.getoption("--runtor"): + # --runtor given in cli: do not skip tor tests + return + 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) + + @pytest.fixture def temp_dir_1024(): """ Create a temporary directory that has a single file of a @@ -151,13 +167,11 @@ def time_strftime(monkeypatch): @pytest.fixture def common_obj(): - _common = common.Common() - _common.settings = settings.Settings(_common) - strings.load_strings(_common) - return _common + 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) diff --git a/tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_test.py similarity index 100% rename from tests_gui/local_onionshare_receive_mode_upload_public_mode_test.py rename to tests/local_onionshare_receive_mode_upload_public_mode_test.py diff --git a/tests_gui/local_onionshare_receive_mode_upload_test.py b/tests/local_onionshare_receive_mode_upload_test.py similarity index 100% rename from tests_gui/local_onionshare_receive_mode_upload_test.py rename to tests/local_onionshare_receive_mode_upload_test.py diff --git a/tests_gui/local_onionshare_share_mode_download_public_mode_test.py b/tests/local_onionshare_share_mode_download_public_mode_test.py similarity index 100% rename from tests_gui/local_onionshare_share_mode_download_public_mode_test.py rename to tests/local_onionshare_share_mode_download_public_mode_test.py diff --git a/tests_gui/local_onionshare_share_mode_download_stay_open_test.py b/tests/local_onionshare_share_mode_download_stay_open_test.py similarity index 100% rename from tests_gui/local_onionshare_share_mode_download_stay_open_test.py rename to tests/local_onionshare_share_mode_download_stay_open_test.py diff --git a/tests_gui/local_onionshare_share_mode_download_test.py b/tests/local_onionshare_share_mode_download_test.py similarity index 100% rename from tests_gui/local_onionshare_share_mode_download_test.py rename to tests/local_onionshare_share_mode_download_test.py diff --git a/tests_gui/local_onionshare_share_mode_slug_persistent_test.py b/tests/local_onionshare_share_mode_slug_persistent_test.py similarity index 100% rename from tests_gui/local_onionshare_share_mode_slug_persistent_test.py rename to tests/local_onionshare_share_mode_slug_persistent_test.py diff --git a/tests_gui/local_onionshare_share_mode_timer_test.py b/tests/local_onionshare_share_mode_timer_test.py similarity index 100% rename from tests_gui/local_onionshare_share_mode_timer_test.py rename to tests/local_onionshare_share_mode_timer_test.py diff --git a/tests_gui/onionshare_790_cancel_on_second_share_test.py b/tests/onionshare_790_cancel_on_second_share_test.py similarity index 100% rename from tests_gui/onionshare_790_cancel_on_second_share_test.py rename to tests/onionshare_790_cancel_on_second_share_test.py diff --git a/tests_gui/onionshare_receive_mode_upload_public_mode_test.py b/tests/onionshare_receive_mode_upload_public_mode_test.py similarity index 100% rename from tests_gui/onionshare_receive_mode_upload_public_mode_test.py rename to tests/onionshare_receive_mode_upload_public_mode_test.py diff --git a/tests_gui/onionshare_receive_mode_upload_test.py b/tests/onionshare_receive_mode_upload_test.py similarity index 100% rename from tests_gui/onionshare_receive_mode_upload_test.py rename to tests/onionshare_receive_mode_upload_test.py diff --git a/tests_gui/onionshare_share_mode_cancel_share_test.py b/tests/onionshare_share_mode_cancel_share_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_cancel_share_test.py rename to tests/onionshare_share_mode_cancel_share_test.py diff --git a/tests_gui/onionshare_share_mode_download_public_mode_test.py b/tests/onionshare_share_mode_download_public_mode_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_download_public_mode_test.py rename to tests/onionshare_share_mode_download_public_mode_test.py diff --git a/tests_gui/onionshare_share_mode_download_stay_open_test.py b/tests/onionshare_share_mode_download_stay_open_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_download_stay_open_test.py rename to tests/onionshare_share_mode_download_stay_open_test.py diff --git a/tests_gui/onionshare_share_mode_download_test.py b/tests/onionshare_share_mode_download_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_download_test.py rename to tests/onionshare_share_mode_download_test.py diff --git a/tests_gui/onionshare_share_mode_persistent_test.py b/tests/onionshare_share_mode_persistent_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_persistent_test.py rename to tests/onionshare_share_mode_persistent_test.py diff --git a/tests_gui/onionshare_share_mode_stealth_test.py b/tests/onionshare_share_mode_stealth_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_stealth_test.py rename to tests/onionshare_share_mode_stealth_test.py diff --git a/tests_gui/onionshare_share_mode_timer_test.py b/tests/onionshare_share_mode_timer_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_timer_test.py rename to tests/onionshare_share_mode_timer_test.py diff --git a/tests_gui/onionshare_share_mode_tor_connection_killed_test.py b/tests/onionshare_share_mode_tor_connection_killed_test.py similarity index 100% rename from tests_gui/onionshare_share_mode_tor_connection_killed_test.py rename to tests/onionshare_share_mode_tor_connection_killed_test.py diff --git a/tests/test_onionshare_strings.py b/tests/test_onionshare_strings.py index 6d39598c..ea57e3a9 100644 --- a/tests/test_onionshare_strings.py +++ b/tests/test_onionshare_strings.py @@ -23,7 +23,7 @@ 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): @@ -40,6 +40,7 @@ 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." @@ -47,6 +48,7 @@ class TestLoadStrings: 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') == "Préparation des fichiers à partager." @@ -55,5 +57,6 @@ class TestLoadStrings: 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) diff --git a/tests/test_onionshare_web.py b/tests/test_onionshare_web.py index 24a0e163..d42adde4 100644 --- a/tests/test_onionshare_web.py +++ b/tests/test_onionshare_web.py @@ -31,6 +31,7 @@ import tempfile import pytest from onionshare.common import Common +from onionshare import strings from onionshare.web import Web from onionshare.settings import Settings @@ -41,7 +42,7 @@ 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.load_settings() - + strings.load_strings(common_obj) web = Web(common_obj, False, mode) web.generate_slug() web.stay_open = True diff --git a/tests_gui/__init__.py b/tests_gui/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests_gui/conftest.py b/tests_gui/conftest.py deleted file mode 100644 index 62108e05..00000000 --- a/tests_gui/conftest.py +++ /dev/null @@ -1,176 +0,0 @@ -import sys -# Force tests to look for resources in the source code tree -sys.onionshare_dev_mode = True - -import os -import shutil -import tempfile - -import pytest - -from onionshare import common, web, settings - -def pytest_addoption(parser): - parser.addoption( - "--runtor", action="store_true", default=False, help="run tor tests" - ) - - -def pytest_collection_modifyitems(config, items): - if config.getoption("--runtor"): - # --runtor given in cli: do not skip tor tests - return - 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) - - -@pytest.fixture -def temp_dir_1024(): - """ Create a temporary directory that has a single file of a - particular size (1024 bytes). - """ - - tmp_dir = tempfile.mkdtemp() - tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) - with open(tmp_file, 'wb') as f: - f.write(b'*' * 1024) - return tmp_dir - - -# pytest > 2.9 only needs @pytest.fixture -@pytest.yield_fixture -def temp_dir_1024_delete(): - """ Create a temporary directory that has a single file of a - particular size (1024 bytes). The temporary directory (including - the file inside) will be deleted after fixture usage. - """ - - with tempfile.TemporaryDirectory() as tmp_dir: - tmp_file, tmp_file_path = tempfile.mkstemp(dir=tmp_dir) - with open(tmp_file, 'wb') as f: - f.write(b'*' * 1024) - yield tmp_dir - - -@pytest.fixture -def temp_file_1024(): - """ Create a temporary file of a particular size (1024 bytes). """ - - with tempfile.NamedTemporaryFile(delete=False) 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(): - """ - Create a temporary file of a particular size (1024 bytes). - The temporary file will be deleted after fixture usage. - """ - - with tempfile.NamedTemporaryFile() as tmp_file: - 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) - shutil.rmtree(tmp_dir) - - -@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' - return settings.Settings(_common) diff --git a/tests_gui/run_unit_tests.sh b/tests_gui/run_unit_tests.sh deleted file mode 100755 index 81542749..00000000 --- a/tests_gui/run_unit_tests.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -for test in `ls -1 | egrep ^local_`; do - pytest $test -vvv || exit 1 -done From 0698f8ca6d93a161c586711e7b62d6ba5a2d123b Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sat, 13 Oct 2018 10:39:26 +1100 Subject: [PATCH 085/142] Update test documentation --- BUILD.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/BUILD.md b/BUILD.md index 00d24cd2..b92f4110 100644 --- a/BUILD.md +++ b/BUILD.md @@ -143,24 +143,16 @@ OnionShare includes PyTest unit tests. To run the tests, first install some depe pip3 install -r install/requirements-tests.txt ``` -If you'd like to run the CLI-based tests that Travis runs: +Then you can run `pytest` against the `tests/` directory. ```sh pytest tests/ ``` -If you would like to run the GUI unit tests in 'local only mode': +If you would like to also run the GUI unit tests in 'tor' mode, start Tor Browser in the background, then run: ```sh -cd tests_gui_local/ -./run_unit_tests.sh -``` - -If you would like to run the GUI unit tests in 'tor' (bundled) mode: - -```sh -cd tests_gui_tor/ -./run_unit_tests.sh +pytest --runtor tests/ ``` Keep in mind that the Tor tests take a lot longer to run than local mode, but they are also more comprehensive. From 5df43ed232545c5a94d925f59ff33967afc4badd Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sun, 14 Oct 2018 09:22:09 +1100 Subject: [PATCH 086/142] Remove unnecessary dependencies --- tests/TorGuiBaseTest.py | 3 --- tests/TorGuiShareTest.py | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py index b182b1d4..82ecc1b4 100644 --- a/tests/TorGuiBaseTest.py +++ b/tests/TorGuiBaseTest.py @@ -1,8 +1,5 @@ import json -import os import requests -import shutil -import socket import socks from PyQt5 import QtCore, QtTest diff --git a/tests/TorGuiShareTest.py b/tests/TorGuiShareTest.py index 8e17abad..aa622b4f 100644 --- a/tests/TorGuiShareTest.py +++ b/tests/TorGuiShareTest.py @@ -1,7 +1,6 @@ import requests -import socks import zipfile -from PyQt5 import QtCore, QtTest +from PyQt5 import QtTest from .TorGuiBaseTest import TorGuiBaseTest from .GuiShareTest import GuiShareTest From 7329cd0fa5599ca0a684c7ce8873ec68a8563d84 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sun, 14 Oct 2018 14:26:22 +1100 Subject: [PATCH 087/142] Fix class name of Tor persistent mode test --- tests/onionshare_share_mode_persistent_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/onionshare_share_mode_persistent_test.py b/tests/onionshare_share_mode_persistent_test.py index 665aecd5..9a813e5d 100644 --- a/tests/onionshare_share_mode_persistent_test.py +++ b/tests/onionshare_share_mode_persistent_test.py @@ -4,7 +4,7 @@ import unittest from .TorGuiShareTest import TorGuiShareTest -class LocalShareModePersistentSlugTest(unittest.TestCase, TorGuiShareTest): +class ShareModePersistentSlugTest(unittest.TestCase, TorGuiShareTest): @classmethod def setUpClass(cls): test_settings = { From 1a1d3d9c8aa2c0cfb2bc8f92798def5b96b14132 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sun, 14 Oct 2018 15:11:57 +1100 Subject: [PATCH 088/142] fix stealth test. Remove tor connection killed test, because it doesn't work like this in 'automatic' connection mode which we need for Mac/Windows testing --- tests/TorGuiBaseTest.py | 7 ---- tests/onionshare_share_mode_stealth_test.py | 10 +---- ...e_share_mode_tor_connection_killed_test.py | 41 ------------------- 3 files changed, 1 insertion(+), 57 deletions(-) delete mode 100644 tests/onionshare_share_mode_tor_connection_killed_test.py diff --git a/tests/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py index 82ecc1b4..2fadfab7 100644 --- a/tests/TorGuiBaseTest.py +++ b/tests/TorGuiBaseTest.py @@ -149,10 +149,3 @@ class TorGuiBaseTest(GuiBaseTest): def hidserv_auth_string(self): '''Test the validity of the HidservAuth string''' self.assertRegex(self.gui.app.auth_string, r'HidServAuth %s [a-zA-Z1-9]' % 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.cleanup(stop_tor=True) - QtTest.QTest.qWait(2500) - self.assertTrue(mode.status_bar.currentMessage(), strings._('gui_tor_connection_lost')) diff --git a/tests/onionshare_share_mode_stealth_test.py b/tests/onionshare_share_mode_stealth_test.py index a6bbe08e..d7e13540 100644 --- a/tests/onionshare_share_mode_stealth_test.py +++ b/tests/onionshare_share_mode_stealth_test.py @@ -19,18 +19,10 @@ class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest): @pytest.mark.run(after='test_run_all_common_setup_tests') @pytest.mark.tor - def test_run_share_mode_setup_tests(self): + def test_run_stealth_mode_tests(self): self.run_all_share_mode_setup_tests() self.run_all_share_mode_started_tests(False) - - @pytest.mark.run(after='test_run_share_mode_setup_tests') - @pytest.mark.tor - def test_copy_have_hidserv_auth_button(self): self.copy_have_hidserv_auth_button(self.gui.share_mode) - - @pytest.mark.run(after='test_run_share_mode_setup_tests') - @pytest.mark.tor - def test_hidserv_auth_string(self): self.hidserv_auth_string() if __name__ == "__main__": diff --git a/tests/onionshare_share_mode_tor_connection_killed_test.py b/tests/onionshare_share_mode_tor_connection_killed_test.py deleted file mode 100644 index 9112aedd..00000000 --- a/tests/onionshare_share_mode_tor_connection_killed_test.py +++ /dev/null @@ -1,41 +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, 'ShareModeTorConnectionKilledTest') - - @pytest.mark.tor - def test_run_all_common_setup_tests(self): - self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_share_mode_setup_tests(self): - self.run_all_share_mode_setup_tests() - self.run_all_share_mode_started_tests(False) - - @pytest.mark.run(after='test_run_share_mode_setup_tests') - @pytest.mark.tor - def test_tor_killed_statusbar_message_shown(self): - self.tor_killed_statusbar_message_shown(self.gui.share_mode) - - @pytest.mark.run(after='test_tor_killed_statusbar_message_shown') - @pytest.mark.tor - def test_server_is_stopped(self): - self.server_is_stopped(self.gui.share_mode, False) - - @pytest.mark.run(after='test_tor_killed_statusbar_message_shown') - @pytest.mark.tor - def test_web_service_is_stopped(self): - self.web_service_is_stopped() - - -if __name__ == "__main__": - unittest.main() From 668aa66323d2009f5c18ce62b3b084f6a55366ae Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 15 Oct 2018 11:15:32 +1100 Subject: [PATCH 089/142] Move GUI tests into a single function each, which solves ordering bugs, and also means we don't need to depend on pytest-ordering --- install/requirements-tests.txt | 1 - ...are_receive_mode_upload_public_mode_test.py | 5 +---- ...ocal_onionshare_receive_mode_upload_test.py | 5 +---- ...are_share_mode_download_public_mode_test.py | 5 +---- ...share_share_mode_download_stay_open_test.py | 5 +---- ...ocal_onionshare_share_mode_download_test.py | 5 +---- ...ionshare_share_mode_slug_persistent_test.py | 5 +---- .../local_onionshare_share_mode_timer_test.py | 5 +---- ...ionshare_790_cancel_on_second_share_test.py | 18 +----------------- ...are_receive_mode_upload_public_mode_test.py | 6 +----- tests/onionshare_receive_mode_upload_test.py | 6 +----- .../onionshare_share_mode_cancel_share_test.py | 10 +--------- ...are_share_mode_download_public_mode_test.py | 6 +----- ...share_share_mode_download_stay_open_test.py | 6 +----- tests/onionshare_share_mode_download_test.py | 6 +----- tests/onionshare_share_mode_persistent_test.py | 6 +----- tests/onionshare_share_mode_stealth_test.py | 6 +----- tests/onionshare_share_mode_timer_test.py | 6 +----- 18 files changed, 17 insertions(+), 95 deletions(-) diff --git a/install/requirements-tests.txt b/install/requirements-tests.txt index 0d9c1581..b931afd1 100644 --- a/install/requirements-tests.txt +++ b/install/requirements-tests.txt @@ -5,7 +5,6 @@ pluggy==0.6.0 py==1.6.0 pytest==3.4.2 pytest-faulthandler==1.5.0 -pytest-ordering==0.5 pytest-qt==3.1.0 six==1.11.0 urllib3==1.23 diff --git a/tests/local_onionshare_receive_mode_upload_public_mode_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_test.py index 27bf9b2c..c99fae52 100644 --- a/tests/local_onionshare_receive_mode_upload_public_mode_test.py +++ b/tests/local_onionshare_receive_mode_upload_public_mode_test.py @@ -13,11 +13,8 @@ class LocalReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModePublicModeTest') - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(True, True) if __name__ == "__main__": diff --git a/tests/local_onionshare_receive_mode_upload_test.py b/tests/local_onionshare_receive_mode_upload_test.py index f6594105..dc6c1f06 100644 --- a/tests/local_onionshare_receive_mode_upload_test.py +++ b/tests/local_onionshare_receive_mode_upload_test.py @@ -12,11 +12,8 @@ class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(False, True) if __name__ == "__main__": diff --git a/tests/local_onionshare_share_mode_download_public_mode_test.py b/tests/local_onionshare_share_mode_download_public_mode_test.py index 2a3f9584..bfed9443 100644 --- a/tests/local_onionshare_share_mode_download_public_mode_test.py +++ b/tests/local_onionshare_share_mode_download_public_mode_test.py @@ -12,11 +12,8 @@ class LocalShareModePublicModeTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePublicModeTest') - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(True, False) if __name__ == "__main__": diff --git a/tests/local_onionshare_share_mode_download_stay_open_test.py b/tests/local_onionshare_share_mode_download_stay_open_test.py index 1f734ae7..b68516a2 100644 --- a/tests/local_onionshare_share_mode_download_stay_open_test.py +++ b/tests/local_onionshare_share_mode_download_stay_open_test.py @@ -12,11 +12,8 @@ class LocalShareModeStayOpenTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeStayOpenTest') - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, True) if __name__ == "__main__": diff --git a/tests/local_onionshare_share_mode_download_test.py b/tests/local_onionshare_share_mode_download_test.py index 274cc311..a2a16c96 100644 --- a/tests/local_onionshare_share_mode_download_test.py +++ b/tests/local_onionshare_share_mode_download_test.py @@ -11,11 +11,8 @@ class LocalShareModeTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, False) if __name__ == "__main__": diff --git a/tests/local_onionshare_share_mode_slug_persistent_test.py b/tests/local_onionshare_share_mode_slug_persistent_test.py index 3450ec3f..03285fa1 100644 --- a/tests/local_onionshare_share_mode_slug_persistent_test.py +++ b/tests/local_onionshare_share_mode_slug_persistent_test.py @@ -15,11 +15,8 @@ class LocalShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePersistentSlugTest') - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - def test_run_all_share_mode_tests(self): self.run_all_share_mode_persistent_tests(False, True) if __name__ == "__main__": diff --git a/tests/local_onionshare_share_mode_timer_test.py b/tests/local_onionshare_share_mode_timer_test.py index f9f36c48..3d20efc4 100644 --- a/tests/local_onionshare_share_mode_timer_test.py +++ b/tests/local_onionshare_share_mode_timer_test.py @@ -13,11 +13,8 @@ class LocalShareModeTimerTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTimerTest') - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - def test_run_all_share_mode_timer_tests(self): self.run_all_share_mode_timer_tests(False) if __name__ == "__main__": diff --git a/tests/onionshare_790_cancel_on_second_share_test.py b/tests/onionshare_790_cancel_on_second_share_test.py index 36725fb0..21747d4c 100644 --- a/tests/onionshare_790_cancel_on_second_share_test.py +++ b/tests/onionshare_790_cancel_on_second_share_test.py @@ -14,27 +14,11 @@ class ShareModeCancelSecondShareTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelSecondShareTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_share_mode_tests(self): self.run_all_share_mode_tests(False, False) - - @pytest.mark.run(after='test_run_share_mode_tests') - @pytest.mark.tor - def test_cancel_the_share(self): self.cancel_the_share(self.gui.share_mode) - - @pytest.mark.run(after='test_cancel_the_share') - @pytest.mark.tor - def test_server_is_stopped_round2(self): self.server_is_stopped(self.gui.share_mode, False) - - @pytest.mark.run(after='test_server_is_stopped_round2') - @pytest.mark.tor - def test_web_service_is_stopped_round2(self): self.web_service_is_stopped() if __name__ == "__main__": diff --git a/tests/onionshare_receive_mode_upload_public_mode_test.py b/tests/onionshare_receive_mode_upload_public_mode_test.py index ee0c5c34..56b49c81 100644 --- a/tests/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests/onionshare_receive_mode_upload_public_mode_test.py @@ -14,12 +14,8 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(True, True) if __name__ == "__main__": diff --git a/tests/onionshare_receive_mode_upload_test.py b/tests/onionshare_receive_mode_upload_test.py index f1f683cc..0fd8d5ed 100644 --- a/tests/onionshare_receive_mode_upload_test.py +++ b/tests/onionshare_receive_mode_upload_test.py @@ -13,12 +13,8 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_all_receive_mode_tests(self): self.run_all_receive_mode_tests(False, True) if __name__ == "__main__": diff --git a/tests/onionshare_share_mode_cancel_share_test.py b/tests/onionshare_share_mode_cancel_share_test.py index 97adf9ce..9770cc35 100644 --- a/tests/onionshare_share_mode_cancel_share_test.py +++ b/tests/onionshare_share_mode_cancel_share_test.py @@ -12,17 +12,9 @@ class ShareModeCancelTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_share_mode_setup_tests(self): self.run_all_share_mode_setup_tests() - - @pytest.mark.run(after='test_run_share_mode_setup_tests') - @pytest.mark.tor - def test_cancel_the_share(self): self.cancel_the_share(self.gui.share_mode) if __name__ == "__main__": diff --git a/tests/onionshare_share_mode_download_public_mode_test.py b/tests/onionshare_share_mode_download_public_mode_test.py index a4a3bfb1..8409720a 100644 --- a/tests/onionshare_share_mode_download_public_mode_test.py +++ b/tests/onionshare_share_mode_download_public_mode_test.py @@ -13,12 +13,8 @@ class ShareModePublicModeTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(True, False) if __name__ == "__main__": diff --git a/tests/onionshare_share_mode_download_stay_open_test.py b/tests/onionshare_share_mode_download_stay_open_test.py index 33544217..c16f91e9 100644 --- a/tests/onionshare_share_mode_download_stay_open_test.py +++ b/tests/onionshare_share_mode_download_stay_open_test.py @@ -13,12 +13,8 @@ class ShareModeStayOpenTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, True) if __name__ == "__main__": diff --git a/tests/onionshare_share_mode_download_test.py b/tests/onionshare_share_mode_download_test.py index 8d6d9655..194328d9 100644 --- a/tests/onionshare_share_mode_download_test.py +++ b/tests/onionshare_share_mode_download_test.py @@ -12,12 +12,8 @@ class ShareModeTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_all_share_mode_tests(self): self.run_all_share_mode_tests(False, False) if __name__ == "__main__": diff --git a/tests/onionshare_share_mode_persistent_test.py b/tests/onionshare_share_mode_persistent_test.py index 9a813e5d..3c283943 100644 --- a/tests/onionshare_share_mode_persistent_test.py +++ b/tests/onionshare_share_mode_persistent_test.py @@ -17,12 +17,8 @@ class ShareModePersistentSlugTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_all_share_mode_tests(self): self.run_all_share_mode_persistent_tests(False, True) if __name__ == "__main__": diff --git a/tests/onionshare_share_mode_stealth_test.py b/tests/onionshare_share_mode_stealth_test.py index d7e13540..b414de1f 100644 --- a/tests/onionshare_share_mode_stealth_test.py +++ b/tests/onionshare_share_mode_stealth_test.py @@ -14,12 +14,8 @@ class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStealthTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_stealth_mode_tests(self): self.run_all_share_mode_setup_tests() self.run_all_share_mode_started_tests(False) self.copy_have_hidserv_auth_button(self.gui.share_mode) diff --git a/tests/onionshare_share_mode_timer_test.py b/tests/onionshare_share_mode_timer_test.py index 32e28c00..b53905d0 100644 --- a/tests/onionshare_share_mode_timer_test.py +++ b/tests/onionshare_share_mode_timer_test.py @@ -14,12 +14,8 @@ class ShareModeTimerTest(unittest.TestCase, TorGuiShareTest): cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTimerTest') @pytest.mark.tor - def test_run_all_common_setup_tests(self): + def test_gui(self): self.run_all_common_setup_tests() - - @pytest.mark.run(after='test_run_all_common_setup_tests') - @pytest.mark.tor - def test_run_all_share_mode_timer_tests(self): self.run_all_share_mode_timer_tests(False) if __name__ == "__main__": From 57b105b631275217f1254843fcd6f2d0c59e4f5e Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Mon, 15 Oct 2018 17:33:21 +1100 Subject: [PATCH 090/142] Remove second arg from two calls to strings() --- onionshare_gui/mode/share_mode/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py index 62c5d8a7..436d42f7 100644 --- a/onionshare_gui/mode/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -284,7 +284,7 @@ class ShareMode(Mode): # Update in progress count self.history.in_progress_count -= 1 self.history.update_in_progress() - self.system_tray.showMessage(strings._('systray_download_canceled_title', True), strings._('systray_download_canceled_message', True)) + self.system_tray.showMessage(strings._('systray_download_canceled_title'), strings._('systray_download_canceled_message')) def on_reload_settings(self): """ From b2a7b0c929f4f142a4f8b2c4ca541b2a88d2815d Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Tue, 16 Oct 2018 13:01:44 +1100 Subject: [PATCH 091/142] More coverage such as 404 ratelimit, large file tests. Standardise some method naming conventions and other fixes/cleanup --- tests/GuiBaseTest.py | 80 +++++++++++---- tests/GuiReceiveTest.py | 65 ++++++++++-- tests/GuiShareTest.py | 99 ++++++++++++------- tests/TorGuiBaseTest.py | 31 ++++-- tests/TorGuiReceiveTest.py | 14 ++- tests/TorGuiShareTest.py | 31 +++++- ...re_404_public_mode_skips_ratelimit_test.py | 21 ++++ ..._onionshare_404_triggers_ratelimit_test.py | 20 ++++ ...onshare_receive_mode_sender_closed_test.py | 20 ++++ ...ocal_onionshare_receive_mode_timer_test.py | 20 ++++ ...ceive_mode_upload_non_writable_dir_test.py | 19 ++++ ...re_receive_mode_upload_public_mode_test.py | 1 - ...cal_onionshare_receive_mode_upload_test.py | 1 - ...re_share_mode_download_public_mode_test.py | 1 - ...hare_share_mode_download_stay_open_test.py | 1 - ...cal_onionshare_share_mode_download_test.py | 1 - ...ionshare_share_mode_large_download_test.py | 18 ++++ ...onshare_share_mode_slug_persistent_test.py | 1 - .../local_onionshare_share_mode_timer_test.py | 1 - ...onshare_790_cancel_on_second_share_test.py | 2 +- 20 files changed, 360 insertions(+), 87 deletions(-) create mode 100644 tests/local_onionshare_404_public_mode_skips_ratelimit_test.py create mode 100644 tests/local_onionshare_404_triggers_ratelimit_test.py create mode 100644 tests/local_onionshare_receive_mode_sender_closed_test.py create mode 100644 tests/local_onionshare_receive_mode_timer_test.py create mode 100644 tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py create mode 100644 tests/local_onionshare_share_mode_large_download_test.py diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py index 79543468..e2f194db 100644 --- a/tests/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -26,6 +26,13 @@ class GuiBaseTest(object): 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() @@ -46,14 +53,17 @@ class GuiBaseTest(object): web = Web(common, False, True) open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) - gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], '/tmp/{}.json'.format(settings_filename), True) + gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt', '/tmp/testdir'], '/tmp/{}.json'.format(settings_filename), True) return gui @staticmethod def tear_down(): + '''Clean up after tests''' try: os.remove('/tmp/test.txt') + os.remove('/tmp/largefile') shutil.rmtree('/tmp/OnionShare') + shutil.rmtree('/tmp/testdir') except: pass @@ -72,6 +82,11 @@ class GuiBaseTest(object): '''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''' @@ -152,22 +167,17 @@ class GuiBaseTest(object): def server_status_indicator_says_starting(self, mode): '''Test that the Server Status indicator shows we are Starting''' - self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_share_working')) + self.assertEqual(mode.server_status_label.text(), strings._('gui_status_indicator_share_working')) - 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 a_server_is_started(self, mode): + def server_is_started(self, mode, startup_time=2000): '''Test that the server has started''' - QtTest.QTest.qWait(2000) + QtTest.QTest.qWait(startup_time) # Should now be in SERVER_STARTED state self.assertEqual(mode.server_status.status, 2) - def a_web_server_is_running(self): + def web_server_is_running(self): '''Test that the web server has started''' sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -187,17 +197,24 @@ class GuiBaseTest(object): self.assertTrue(mode.server_status.url_description.isVisible()) - def have_copy_url_button(self, mode): - '''Test that the Copy URL button is shown''' + 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(), 'http://127.0.0.1:{}'.format(self.gui.app.port)) + else: + self.assertEqual(clipboard.text(), 'http://127.0.0.1:{}/{}'.format(self.gui.app.port, mode.server_status.web.slug)) + def server_status_indicator_says_started(self, mode): '''Test that the Server Status indicator shows we are started''' if type(mode) == ReceiveMode: - self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_receive_started')) + self.assertEqual(mode.server_status_label.text(), strings._('gui_status_indicator_receive_started')) if type(mode) == ShareMode: - self.assertEquals(mode.server_status_label.text(), strings._('gui_status_indicator_share_started')) + self.assertEqual(mode.server_status_label.text(), strings._('gui_status_indicator_share_started')) def web_page(self, mode, string, public_mode): @@ -237,17 +254,17 @@ class GuiBaseTest(object): def counter_incremented(self, mode, count): '''Test that the counter has incremented''' - self.assertEquals(mode.history.completed_count, count) + 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): QtTest.QTest.mouseClick(mode.server_status.server_button, QtCore.Qt.LeftButton) - self.assertEquals(mode.server_status.status, 0) + self.assertEqual(mode.server_status.status, 0) - def web_service_is_stopped(self): + def web_server_is_stopped(self): '''Test that the web server also stopped''' QtTest.QTest.qWait(2000) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -259,12 +276,35 @@ class GuiBaseTest(object): def server_status_indicator_says_closed(self, mode, stay_open): '''Test that the Server Status indicator shows we closed''' if type(mode) == ReceiveMode: - self.assertEquals(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped')) + self.assertEqual(self.gui.receive_mode.server_status_label.text(), strings._('gui_status_indicator_receive_stopped')) if type(mode) == ShareMode: if stay_open: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped')) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('gui_status_indicator_share_stopped')) else: - self.assertEquals(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically')) + self.assertEqual(self.gui.share_mode.server_status_label.text(), strings._('closing_automatically')) + + + # 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.shutdown_timeout.setDateTime(timer) + self.assertTrue(mode.server_status.shutdown_timeout.dateTime(), timer) + + + def timeout_widget_hidden(self, mode): + '''Test that the timeout widget is hidden when share has started''' + self.assertFalse(mode.server_status.shutdown_timeout_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) + + + # 'Grouped' tests follow from here def run_all_common_setup_tests(self): self.gui_loaded() diff --git a/tests/GuiReceiveTest.py b/tests/GuiReceiveTest.py index 1fa5c4dc..84d6a55a 100644 --- a/tests/GuiReceiveTest.py +++ b/tests/GuiReceiveTest.py @@ -15,7 +15,39 @@ class GuiReceiveTest(GuiBaseTest): QtTest.QTest.qWait(2000) self.assertTrue(os.path.isfile(expected_file)) - def run_all_receive_mode_tests(self, public_mode, receive_allow_receiver_shutdown): + def upload_file_should_fail(self, public_mode, expected_file): + '''Test that we can't upload the file when permissions are wrong, and expected content is shown''' + files = {'file[]': open('/tmp/test.txt', 'rb')} + if not public_mode: + path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, self.gui.receive_mode.web.slug) + else: + path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) + response = requests.post(path, files=files) + + # A nasty hack to avoid the Alert dialog that blocks the rest of the test + self.gui.qtapp.exit() + self.assertTrue('Error uploading, please inform the OnionShare user' in response.text) + + def upload_dir_permissions(self, mode=0o755): + '''Manipulate the permissions on the upload dir in between tests''' + os.chmod('/tmp/OnionShare', mode) + + def run_receive_mode_sender_closed_tests(self, public_mode): + '''Test that the share can be stopped by the sender in receive mode''' + if not public_mode: + path = 'http://127.0.0.1:{}/{}/close'.format(self.gui.app.port, self.gui.receive_mode.web.slug) + else: + path = 'http://127.0.0.1:{}/close'.format(self.gui.app.port) + response = requests.post(path) + 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) + + + # '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) @@ -23,13 +55,17 @@ class GuiReceiveTest(GuiBaseTest): 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.a_server_is_started(self.gui.receive_mode) - self.a_web_server_is_running() + self.server_is_started(self.gui.receive_mode) + self.web_server_is_running() self.have_a_slug(self.gui.receive_mode, public_mode) self.url_description_shown(self.gui.receive_mode) - self.have_copy_url_button(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, receive_allow_receiver_shutdown): + '''Upload files in receive mode and stop the share''' + self.run_all_receive_mode_setup_tests(public_mode) self.upload_file(public_mode, '/tmp/OnionShare/test.txt') self.history_widgets_present(self.gui.receive_mode) self.counter_incremented(self.gui.receive_mode, 1) @@ -37,9 +73,26 @@ class GuiReceiveTest(GuiBaseTest): self.counter_incremented(self.gui.receive_mode, 2) self.history_indicator(self.gui.receive_mode, public_mode) self.server_is_stopped(self.gui.receive_mode, False) - self.web_service_is_stopped() + 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.a_server_is_started(self.gui.receive_mode) + self.server_is_started(self.gui.receive_mode) self.history_indicator(self.gui.receive_mode, public_mode) + def run_all_receive_mode_unwritable_dir_tests(self, public_mode, receive_allow_receiver_shutdown): + '''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, '/tmp/OnionShare/test.txt') + 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.timeout_widget_hidden(self.gui.receive_mode) + self.server_timed_out(self.gui.receive_mode, 15000) + self.web_server_is_stopped() diff --git a/tests/GuiShareTest.py b/tests/GuiShareTest.py index 34149dec..4f2f58e7 100644 --- a/tests/GuiShareTest.py +++ b/tests/GuiShareTest.py @@ -1,29 +1,11 @@ +import os +import requests import socks import zipfile from PyQt5 import QtCore, QtTest from .GuiBaseTest import GuiBaseTest class GuiShareTest(GuiBaseTest): - # 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.shutdown_timeout.setDateTime(timer) - self.assertTrue(mode.server_status.shutdown_timeout.dateTime(), timer) - - - def timeout_widget_hidden(self, mode): - '''Test that the timeout widget is hidden when share has started''' - self.assertFalse(mode.server_status.shutdown_timeout_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) - # Persistence tests def have_same_slug(self, slug): '''Test that we have the same slug''' @@ -31,19 +13,26 @@ class GuiShareTest(GuiBaseTest): # Share-specific tests - def file_selection_widget_has_a_file(self): - '''Test that the number of files in the list is 1''' - self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 1) + def file_selection_widget_has_files(self): + '''Test that the number of items in the list is 2''' + self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 2) - def deleting_only_file_hides_delete_button(self): + 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, and since there's no more files, the delete button should be hidden + # 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()) @@ -60,7 +49,15 @@ class GuiShareTest(GuiBaseTest): self.gui.share_mode.server_status.file_selection.file_list.add_file('/tmp/test.txt') self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_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()) @@ -95,35 +92,56 @@ class GuiShareTest(GuiBaseTest): QtTest.QTest.qWait(2000) self.assertEqual('onionshare', zip.read('test.txt').decode('utf-8')) - + def hit_404(self, public_mode): + '''Test that the server stops after too many 404s, or doesn't when in public_mode''' + bogus_path = '/gimme' + url = "http://127.0.0.1:{}/{}".format(self.gui.app.port, bogus_path) + + for _ in range(20): + r = requests.get(url) + + # A nasty hack to avoid the Alert dialog that blocks the rest of the test + if not public_mode: + self.gui.qtapp.exit() + + # 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() + + 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): """Tests in share mode prior to starting a share""" self.click_mode(self.gui.share_mode) - self.file_selection_widget_has_a_file() + 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_only_file_hides_delete_button() + self.deleting_all_files_hides_delete_button() self.add_a_file_and_delete_using_its_delete_widget() self.file_selection_widget_readd_files() - def run_all_share_mode_started_tests(self, public_mode): + 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.a_server_is_started(self.gui.share_mode) - self.a_web_server_is_running() + self.server_is_started(self.gui.share_mode, startup_time) + self.web_server_is_running() self.have_a_slug(self.gui.share_mode, public_mode) self.url_description_shown(self.gui.share_mode) - self.have_copy_url_button(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) @@ -133,11 +151,11 @@ class GuiShareTest(GuiBaseTest): 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_service_is_stopped() + self.web_server_is_stopped() self.server_status_indicator_says_closed(self.gui.share_mode, stay_open) self.add_button_visible() self.server_working_on_start_button_pressed(self.gui.share_mode) - self.a_server_is_started(self.gui.share_mode) + self.server_is_started(self.gui.share_mode) self.history_indicator(self.gui.share_mode, public_mode) @@ -148,6 +166,17 @@ class GuiShareTest(GuiBaseTest): self.run_all_share_mode_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 slug is the same on multiple shared""" self.run_all_share_mode_setup_tests() @@ -164,5 +193,5 @@ class GuiShareTest(GuiBaseTest): self.run_all_share_mode_started_tests(public_mode) self.timeout_widget_hidden(self.gui.share_mode) self.server_timed_out(self.gui.share_mode, 10000) - self.web_service_is_stopped() + self.web_server_is_stopped() diff --git a/tests/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py index 2fadfab7..aee05096 100644 --- a/tests/TorGuiBaseTest.py +++ b/tests/TorGuiBaseTest.py @@ -1,4 +1,5 @@ import json +import os import requests import socks @@ -24,6 +25,13 @@ class TorGuiBaseTest(GuiBaseTest): 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() @@ -45,7 +53,7 @@ class TorGuiBaseTest(GuiBaseTest): web = Web(common, False, False) open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) - gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt'], '/tmp/{}.json'.format(settings_filename), False) + gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt', '/tmp/testdir'], '/tmp/{}.json'.format(settings_filename), False) return gui def history_indicator(self, mode, public_mode): @@ -91,12 +99,6 @@ class TorGuiBaseTest(GuiBaseTest): QtTest.QTest.mouseClick(mode.toggle_history, QtCore.Qt.LeftButton) self.assertFalse(mode.toggle_history.indicator_label.isVisible()) - def a_server_is_started(self, mode): - '''Test that the server has started (overriding from local tests to wait for longer)''' - QtTest.QTest.qWait(45000) - # Should now be in SERVER_STARTED state - self.assertEqual(mode.server_status.status, 2) - 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') @@ -127,6 +129,17 @@ class TorGuiBaseTest(GuiBaseTest): 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(), 'http://{}'.format(self.gui.app.onion_host)) + else: + self.assertEqual(clipboard.text(), 'http://{}/{}'.format(self.gui.app.onion_host, mode.server_status.web.slug)) + def cancel_the_share(self, mode): '''Test that we can cancel this share before it's started up ''' self.server_working_on_start_button_pressed(self.gui.share_mode) @@ -138,13 +151,15 @@ class TorGuiBaseTest(GuiBaseTest): QtTest.QTest.mouseRelease(mode.server_status.server_button, QtCore.Qt.LeftButton) self.assertEqual(mode.server_status.status, 0) self.server_is_stopped(self.gui.share_mode, False) - self.web_service_is_stopped() + self.web_server_is_stopped() # 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()) + clipboard = self.gui.qtapp.clipboard() + self.assertRegex(clipboard.text(), r'HidServAuth %s [a-zA-Z1-9]' % self.gui.app.onion_host) def hidserv_auth_string(self): '''Test the validity of the HidservAuth string''' diff --git a/tests/TorGuiReceiveTest.py b/tests/TorGuiReceiveTest.py index 67b6a811..3c380b8a 100644 --- a/tests/TorGuiReceiveTest.py +++ b/tests/TorGuiReceiveTest.py @@ -20,7 +20,11 @@ class TorGuiReceiveTest(TorGuiBaseTest): 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) @@ -28,12 +32,12 @@ class TorGuiReceiveTest(TorGuiBaseTest): 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.a_server_is_started(self.gui.receive_mode) - self.a_web_server_is_running() + self.server_is_started(self.gui.receive_mode, startup_time=45000) + self.web_server_is_running() self.have_an_onion_service() self.have_a_slug(self.gui.receive_mode, public_mode) self.url_description_shown(self.gui.receive_mode) - self.have_copy_url_button(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/OnionShare/test.txt') @@ -43,9 +47,9 @@ class TorGuiReceiveTest(TorGuiBaseTest): self.counter_incremented(self.gui.receive_mode, 2) self.history_indicator(self.gui.receive_mode, public_mode) self.server_is_stopped(self.gui.receive_mode, False) - self.web_service_is_stopped() + 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.a_server_is_started(self.gui.receive_mode) + self.server_is_started(self.gui.receive_mode, startup_time=45000) self.history_indicator(self.gui.receive_mode, public_mode) diff --git a/tests/TorGuiShareTest.py b/tests/TorGuiShareTest.py index aa622b4f..ff8d0bb7 100644 --- a/tests/TorGuiShareTest.py +++ b/tests/TorGuiShareTest.py @@ -6,6 +6,7 @@ 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() @@ -27,27 +28,46 @@ class TorGuiShareTest(TorGuiBaseTest, GuiShareTest): file_to_write.close() zip = zipfile.ZipFile('/tmp/download.zip') QtTest.QTest.qWait(4000) - self.assertEquals('onionshare', zip.read('test.txt').decode('utf-8')) + 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) + + # '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.a_server_is_started(self.gui.share_mode) - self.a_web_server_is_running() + self.server_is_started(self.gui.share_mode, startup_time=45000) + self.web_server_is_running() self.have_an_onion_service() self.have_a_slug(self.gui.share_mode, public_mode) self.url_description_shown(self.gui.share_mode) - self.have_copy_url_button(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.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 slug is the same on multiple shared""" self.run_all_share_mode_setup_tests() @@ -57,6 +77,7 @@ class TorGuiShareTest(TorGuiBaseTest, GuiShareTest): self.run_all_share_mode_download_tests(public_mode, stay_open) self.have_same_onion(onion) self.have_same_slug(slug) + def run_all_share_mode_timer_tests(self, public_mode): """Auto-stop timer tests in share mode""" @@ -65,5 +86,5 @@ class TorGuiShareTest(TorGuiBaseTest, GuiShareTest): self.run_all_share_mode_started_tests(public_mode) self.timeout_widget_hidden(self.gui.share_mode) self.server_timed_out(self.gui.share_mode, 125000) - self.web_service_is_stopped() + self.web_server_is_stopped() diff --git a/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py b/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py new file mode 100644 index 00000000..e4e0a03f --- /dev/null +++ b/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +import unittest + +from .GuiShareTest import GuiShareTest + +class Local404PublicModeRateLimitTest(unittest.TestCase, GuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + "close_after_first_download": False, + "public_mode": True + } + cls.gui = GuiShareTest.set_up(test_settings, 'Local404PublicModeRateLimitTest') + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_share_mode_tests(True, True) + self.hit_404(True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_404_triggers_ratelimit_test.py b/tests/local_onionshare_404_triggers_ratelimit_test.py new file mode 100644 index 00000000..ce26eae1 --- /dev/null +++ b/tests/local_onionshare_404_triggers_ratelimit_test.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +import unittest + +from .GuiShareTest import GuiShareTest + +class Local404RateLimitTest(unittest.TestCase, GuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + "close_after_first_download": False + } + cls.gui = GuiShareTest.set_up(test_settings, 'Local404RateLimitTest') + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_share_mode_tests(False, True) + self.hit_404(False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_receive_mode_sender_closed_test.py b/tests/local_onionshare_receive_mode_sender_closed_test.py new file mode 100644 index 00000000..6960301a --- /dev/null +++ b/tests/local_onionshare_receive_mode_sender_closed_test.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +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, 'LocalReceiveModeTest') + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_receive_mode_tests(False, True) + self.run_receive_mode_sender_closed_tests(False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_receive_mode_timer_test.py b/tests/local_onionshare_receive_mode_timer_test.py new file mode 100644 index 00000000..1784ba94 --- /dev/null +++ b/tests/local_onionshare_receive_mode_timer_test.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +import unittest + +from .GuiReceiveTest import GuiReceiveTest + +class LocalReceiveModeTimerTest(unittest.TestCase, GuiReceiveTest): + @classmethod + def setUpClass(cls): + test_settings = { + "public_mode": False, + "shutdown_timeout": True, + } + cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTimerTest') + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_receive_mode_timer_tests(False) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py new file mode 100644 index 00000000..e33a6461 --- /dev/null +++ b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +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, 'LocalReceiveModeTest') + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_receive_mode_unwritable_dir_tests(False, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_receive_mode_upload_public_mode_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_test.py index c99fae52..2c7cbd5e 100644 --- a/tests/local_onionshare_receive_mode_upload_public_mode_test.py +++ b/tests/local_onionshare_receive_mode_upload_public_mode_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from .GuiReceiveTest import GuiReceiveTest diff --git a/tests/local_onionshare_receive_mode_upload_test.py b/tests/local_onionshare_receive_mode_upload_test.py index dc6c1f06..fb5d36a7 100644 --- a/tests/local_onionshare_receive_mode_upload_test.py +++ b/tests/local_onionshare_receive_mode_upload_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from .GuiReceiveTest import GuiReceiveTest diff --git a/tests/local_onionshare_share_mode_download_public_mode_test.py b/tests/local_onionshare_share_mode_download_public_mode_test.py index bfed9443..3b4ad0e8 100644 --- a/tests/local_onionshare_share_mode_download_public_mode_test.py +++ b/tests/local_onionshare_share_mode_download_public_mode_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from .GuiShareTest import GuiShareTest diff --git a/tests/local_onionshare_share_mode_download_stay_open_test.py b/tests/local_onionshare_share_mode_download_stay_open_test.py index b68516a2..dfe7f56c 100644 --- a/tests/local_onionshare_share_mode_download_stay_open_test.py +++ b/tests/local_onionshare_share_mode_download_stay_open_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from .GuiShareTest import GuiShareTest diff --git a/tests/local_onionshare_share_mode_download_test.py b/tests/local_onionshare_share_mode_download_test.py index a2a16c96..6b6b0bcc 100644 --- a/tests/local_onionshare_share_mode_download_test.py +++ b/tests/local_onionshare_share_mode_download_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from .GuiShareTest import GuiShareTest diff --git a/tests/local_onionshare_share_mode_large_download_test.py b/tests/local_onionshare_share_mode_large_download_test.py new file mode 100644 index 00000000..6fe77752 --- /dev/null +++ b/tests/local_onionshare_share_mode_large_download_test.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +import unittest + +from .GuiShareTest import GuiShareTest + +class LocalShareModeTest(unittest.TestCase, GuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + } + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_large_file_tests(False, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_share_mode_slug_persistent_test.py b/tests/local_onionshare_share_mode_slug_persistent_test.py index 03285fa1..a28f5a23 100644 --- a/tests/local_onionshare_share_mode_slug_persistent_test.py +++ b/tests/local_onionshare_share_mode_slug_persistent_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from .GuiShareTest import GuiShareTest diff --git a/tests/local_onionshare_share_mode_timer_test.py b/tests/local_onionshare_share_mode_timer_test.py index 3d20efc4..9e3b0b5e 100644 --- a/tests/local_onionshare_share_mode_timer_test.py +++ b/tests/local_onionshare_share_mode_timer_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from .GuiShareTest import GuiShareTest diff --git a/tests/onionshare_790_cancel_on_second_share_test.py b/tests/onionshare_790_cancel_on_second_share_test.py index 21747d4c..327a8456 100644 --- a/tests/onionshare_790_cancel_on_second_share_test.py +++ b/tests/onionshare_790_cancel_on_second_share_test.py @@ -19,7 +19,7 @@ class ShareModeCancelSecondShareTest(unittest.TestCase, TorGuiShareTest): 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_service_is_stopped() + self.web_server_is_stopped() if __name__ == "__main__": unittest.main() From 1a6356870c4c7c1ee249c519a5c756d74f43b673 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Tue, 16 Oct 2018 15:53:35 +1100 Subject: [PATCH 092/142] Add Settings GUI test --- tests/SettingsGuiBaseTest.py | 49 +++++ ...re_404_public_mode_skips_ratelimit_test.py | 4 + ..._onionshare_404_triggers_ratelimit_test.py | 4 + ...onshare_receive_mode_sender_closed_test.py | 4 + ...ocal_onionshare_receive_mode_timer_test.py | 4 + ...ceive_mode_upload_non_writable_dir_test.py | 4 + ...re_receive_mode_upload_public_mode_test.py | 4 + ...cal_onionshare_receive_mode_upload_test.py | 4 + .../local_onionshare_settings_dialog_test.py | 173 ++++++++++++++++++ ...re_share_mode_download_public_mode_test.py | 4 + ...hare_share_mode_download_stay_open_test.py | 4 + ...cal_onionshare_share_mode_download_test.py | 4 + ...ionshare_share_mode_large_download_test.py | 4 + ...onshare_share_mode_slug_persistent_test.py | 4 + .../local_onionshare_share_mode_timer_test.py | 4 + ...onshare_790_cancel_on_second_share_test.py | 4 + ...re_receive_mode_upload_public_mode_test.py | 4 + tests/onionshare_receive_mode_upload_test.py | 4 + ...onionshare_share_mode_cancel_share_test.py | 4 + ...re_share_mode_download_public_mode_test.py | 4 + ...hare_share_mode_download_stay_open_test.py | 4 + tests/onionshare_share_mode_download_test.py | 4 + .../onionshare_share_mode_persistent_test.py | 4 + tests/onionshare_share_mode_stealth_test.py | 4 + tests/onionshare_share_mode_timer_test.py | 4 + 25 files changed, 314 insertions(+) create mode 100644 tests/SettingsGuiBaseTest.py create mode 100644 tests/local_onionshare_settings_dialog_test.py diff --git a/tests/SettingsGuiBaseTest.py b/tests/SettingsGuiBaseTest.py new file mode 100644 index 00000000..dac074fc --- /dev/null +++ b/tests/SettingsGuiBaseTest.py @@ -0,0 +1,49 @@ +import json +import os +import sys +from PyQt5 import QtWidgets + +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 +from onionshare_gui.settings_dialog import SettingsDialog + +class SettingsGuiBaseTest(object): + @staticmethod + def set_up(test_settings, settings_filename): + '''Create the GUI''' + # 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) + + web = Web(common, False, True) + + for key, val in common.settings.default_settings.items(): + if key not in test_settings: + test_settings[key] = val + + open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) + + gui = SettingsDialog(common, testonion, qtapp, '/tmp/{}.json'.format(settings_filename), True) + return gui + + + @staticmethod + def tear_down(): + '''Clean up after tests''' + os.remove('/tmp/settings.json') diff --git a/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py b/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py index e4e0a03f..c4c271b8 100644 --- a/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py +++ b/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py @@ -12,6 +12,10 @@ class Local404PublicModeRateLimitTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'Local404PublicModeRateLimitTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_share_mode_tests(True, True) diff --git a/tests/local_onionshare_404_triggers_ratelimit_test.py b/tests/local_onionshare_404_triggers_ratelimit_test.py index ce26eae1..8f9caa7c 100644 --- a/tests/local_onionshare_404_triggers_ratelimit_test.py +++ b/tests/local_onionshare_404_triggers_ratelimit_test.py @@ -11,6 +11,10 @@ class Local404RateLimitTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'Local404RateLimitTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_share_mode_tests(False, True) diff --git a/tests/local_onionshare_receive_mode_sender_closed_test.py b/tests/local_onionshare_receive_mode_sender_closed_test.py index 6960301a..1f16b5fb 100644 --- a/tests/local_onionshare_receive_mode_sender_closed_test.py +++ b/tests/local_onionshare_receive_mode_sender_closed_test.py @@ -11,6 +11,10 @@ class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') + @classmethod + def tearDownClass(cls): + GuiReceiveTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_receive_mode_tests(False, True) diff --git a/tests/local_onionshare_receive_mode_timer_test.py b/tests/local_onionshare_receive_mode_timer_test.py index 1784ba94..039acff4 100644 --- a/tests/local_onionshare_receive_mode_timer_test.py +++ b/tests/local_onionshare_receive_mode_timer_test.py @@ -12,6 +12,10 @@ class LocalReceiveModeTimerTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTimerTest') + @classmethod + def tearDownClass(cls): + GuiReceiveTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_receive_mode_timer_tests(False) diff --git a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py index e33a6461..ee3a7215 100644 --- a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py +++ b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py @@ -11,6 +11,10 @@ class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') + @classmethod + def tearDownClass(cls): + GuiReceiveTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_receive_mode_unwritable_dir_tests(False, True) diff --git a/tests/local_onionshare_receive_mode_upload_public_mode_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_test.py index 2c7cbd5e..654895ca 100644 --- a/tests/local_onionshare_receive_mode_upload_public_mode_test.py +++ b/tests/local_onionshare_receive_mode_upload_public_mode_test.py @@ -12,6 +12,10 @@ class LocalReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModePublicModeTest') + @classmethod + def tearDownClass(cls): + GuiReceiveTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_receive_mode_tests(True, True) diff --git a/tests/local_onionshare_receive_mode_upload_test.py b/tests/local_onionshare_receive_mode_upload_test.py index fb5d36a7..c06d30cd 100644 --- a/tests/local_onionshare_receive_mode_upload_test.py +++ b/tests/local_onionshare_receive_mode_upload_test.py @@ -11,6 +11,10 @@ class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): } cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') + @classmethod + def tearDownClass(cls): + GuiReceiveTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_receive_mode_tests(False, True) diff --git a/tests/local_onionshare_settings_dialog_test.py b/tests/local_onionshare_settings_dialog_test.py new file mode 100644 index 00000000..64840d7d --- /dev/null +++ b/tests/local_onionshare_settings_dialog_test.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 +import json +import unittest +from PyQt5 import QtCore, QtTest + +from onionshare import strings +from .SettingsGuiBaseTest import SettingsGuiBaseTest + +class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest): + @classmethod + def setUpClass(cls): + test_settings = { + "no_bridges": False, + "tor_bridges_use_obfs4": True, + } + cls.gui = SettingsGuiBaseTest.set_up(test_settings, 'settings') + + @classmethod + def tearDownClass(cls): + SettingsGuiBaseTest.tear_down() + + def test_gui(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()) + + # shutdown timer is off + self.assertFalse(self.gui.shutdown_timeout_checkbox.isChecked()) + # enable shutdown timer + QtTest.QTest.mouseClick(self.gui.shutdown_timeout_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.shutdown_timeout_checkbox.height()/2)) + self.assertTrue(self.gui.shutdown_timeout_checkbox.isChecked()) + + # legacy mode checkbox and related widgets + # legacy mode is off + self.assertFalse(self.gui.use_legacy_v2_onions_checkbox.isChecked()) + # persistence, stealth is hidden and disabled + 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()) + + # 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, persistence are 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.assertFalse(self.gui.save_private_key_widget.isVisible()) + self.assertFalse(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.use_legacy_v2_onions_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.use_legacy_v2_onions_checkbox.height()/2)) + 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)) + + + # 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.downloads_dir_lineedit.setText('/tmp/OnionShareSettingsTest') + # allow receiver shutdown is on + self.assertTrue(self.gui.receive_allow_receiver_shutdown_checkbox.isChecked()) + # disable receiver shutdown + QtTest.QTest.mouseClick(self.gui.receive_allow_receiver_shutdown_checkbox, QtCore.Qt.LeftButton, pos=QtCore.QPoint(2,self.gui.receive_allow_receiver_shutdown_checkbox.height()/2)) + self.assertFalse(self.gui.receive_allow_receiver_shutdown_checkbox.isChecked()) + + + # 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 obfs4 + self.assertFalse(self.gui.tor_bridges_no_bridges_radio.isChecked()) + 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)) + # set some 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.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["shutdown_timeout"]) + self.assertTrue(data["use_legacy_v2_onions"]) + self.assertTrue(data["save_private_key"]) + self.assertTrue(data["use_stealth"]) + self.assertEqual(data["downloads_dir"], "/tmp/OnionShareSettingsTest") + self.assertFalse(data["receive_allow_receiver_shutdown"]) + 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") + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_share_mode_download_public_mode_test.py b/tests/local_onionshare_share_mode_download_public_mode_test.py index 3b4ad0e8..f1c29990 100644 --- a/tests/local_onionshare_share_mode_download_public_mode_test.py +++ b/tests/local_onionshare_share_mode_download_public_mode_test.py @@ -11,6 +11,10 @@ class LocalShareModePublicModeTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePublicModeTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_share_mode_tests(True, False) diff --git a/tests/local_onionshare_share_mode_download_stay_open_test.py b/tests/local_onionshare_share_mode_download_stay_open_test.py index dfe7f56c..af02e841 100644 --- a/tests/local_onionshare_share_mode_download_stay_open_test.py +++ b/tests/local_onionshare_share_mode_download_stay_open_test.py @@ -11,6 +11,10 @@ class LocalShareModeStayOpenTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeStayOpenTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_share_mode_tests(False, True) diff --git a/tests/local_onionshare_share_mode_download_test.py b/tests/local_onionshare_share_mode_download_test.py index 6b6b0bcc..53db0296 100644 --- a/tests/local_onionshare_share_mode_download_test.py +++ b/tests/local_onionshare_share_mode_download_test.py @@ -10,6 +10,10 @@ class LocalShareModeTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_share_mode_tests(False, False) diff --git a/tests/local_onionshare_share_mode_large_download_test.py b/tests/local_onionshare_share_mode_large_download_test.py index 6fe77752..b8017b77 100644 --- a/tests/local_onionshare_share_mode_large_download_test.py +++ b/tests/local_onionshare_share_mode_large_download_test.py @@ -10,6 +10,10 @@ class LocalShareModeTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_large_file_tests(False, True) diff --git a/tests/local_onionshare_share_mode_slug_persistent_test.py b/tests/local_onionshare_share_mode_slug_persistent_test.py index a28f5a23..c273fbda 100644 --- a/tests/local_onionshare_share_mode_slug_persistent_test.py +++ b/tests/local_onionshare_share_mode_slug_persistent_test.py @@ -14,6 +14,10 @@ class LocalShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePersistentSlugTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_share_mode_persistent_tests(False, True) diff --git a/tests/local_onionshare_share_mode_timer_test.py b/tests/local_onionshare_share_mode_timer_test.py index 9e3b0b5e..394dec21 100644 --- a/tests/local_onionshare_share_mode_timer_test.py +++ b/tests/local_onionshare_share_mode_timer_test.py @@ -12,6 +12,10 @@ class LocalShareModeTimerTest(unittest.TestCase, GuiShareTest): } cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTimerTest') + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + def test_gui(self): self.run_all_common_setup_tests() self.run_all_share_mode_timer_tests(False) diff --git a/tests/onionshare_790_cancel_on_second_share_test.py b/tests/onionshare_790_cancel_on_second_share_test.py index 327a8456..dce84f62 100644 --- a/tests/onionshare_790_cancel_on_second_share_test.py +++ b/tests/onionshare_790_cancel_on_second_share_test.py @@ -13,6 +13,10 @@ class ShareModeCancelSecondShareTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelSecondShareTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_receive_mode_upload_public_mode_test.py b/tests/onionshare_receive_mode_upload_public_mode_test.py index 56b49c81..048186c3 100644 --- a/tests/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests/onionshare_receive_mode_upload_public_mode_test.py @@ -13,6 +13,10 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): } cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') + @classmethod + def tearDownClass(cls): + TorGuiReceiveTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_receive_mode_upload_test.py b/tests/onionshare_receive_mode_upload_test.py index 0fd8d5ed..d3965d59 100644 --- a/tests/onionshare_receive_mode_upload_test.py +++ b/tests/onionshare_receive_mode_upload_test.py @@ -12,6 +12,10 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): } cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') + @classmethod + def tearDownClass(cls): + TorGuiReceiveTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_share_mode_cancel_share_test.py b/tests/onionshare_share_mode_cancel_share_test.py index 9770cc35..83a009a1 100644 --- a/tests/onionshare_share_mode_cancel_share_test.py +++ b/tests/onionshare_share_mode_cancel_share_test.py @@ -11,6 +11,10 @@ class ShareModeCancelTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_share_mode_download_public_mode_test.py b/tests/onionshare_share_mode_download_public_mode_test.py index 8409720a..8c5740c5 100644 --- a/tests/onionshare_share_mode_download_public_mode_test.py +++ b/tests/onionshare_share_mode_download_public_mode_test.py @@ -12,6 +12,10 @@ class ShareModePublicModeTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_share_mode_download_stay_open_test.py b/tests/onionshare_share_mode_download_stay_open_test.py index c16f91e9..56ac924d 100644 --- a/tests/onionshare_share_mode_download_stay_open_test.py +++ b/tests/onionshare_share_mode_download_stay_open_test.py @@ -12,6 +12,10 @@ class ShareModeStayOpenTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_share_mode_download_test.py b/tests/onionshare_share_mode_download_test.py index 194328d9..125909d0 100644 --- a/tests/onionshare_share_mode_download_test.py +++ b/tests/onionshare_share_mode_download_test.py @@ -11,6 +11,10 @@ class ShareModeTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_share_mode_persistent_test.py b/tests/onionshare_share_mode_persistent_test.py index 3c283943..3f103a1a 100644 --- a/tests/onionshare_share_mode_persistent_test.py +++ b/tests/onionshare_share_mode_persistent_test.py @@ -16,6 +16,10 @@ class ShareModePersistentSlugTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_share_mode_stealth_test.py b/tests/onionshare_share_mode_stealth_test.py index b414de1f..3096a8bc 100644 --- a/tests/onionshare_share_mode_stealth_test.py +++ b/tests/onionshare_share_mode_stealth_test.py @@ -13,6 +13,10 @@ class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStealthTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() diff --git a/tests/onionshare_share_mode_timer_test.py b/tests/onionshare_share_mode_timer_test.py index b53905d0..9e690ec7 100644 --- a/tests/onionshare_share_mode_timer_test.py +++ b/tests/onionshare_share_mode_timer_test.py @@ -13,6 +13,10 @@ class ShareModeTimerTest(unittest.TestCase, TorGuiShareTest): } cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTimerTest') + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + @pytest.mark.tor def test_gui(self): self.run_all_common_setup_tests() From 054e5c0aeee16129bb4cad73cd2a1faa86fee03b Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 09:23:07 +1100 Subject: [PATCH 093/142] Fix stealth test, add legacy v2 onion test --- tests/TorGuiBaseTest.py | 4 +-- tests/TorGuiShareTest.py | 7 +++++- tests/onionshare_share_mode_stealth_test.py | 2 +- tests/onionshare_share_mode_v2_onion_test.py | 26 ++++++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 tests/onionshare_share_mode_v2_onion_test.py diff --git a/tests/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py index aee05096..611cb202 100644 --- a/tests/TorGuiBaseTest.py +++ b/tests/TorGuiBaseTest.py @@ -158,9 +158,7 @@ class TorGuiBaseTest(GuiBaseTest): 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()) - clipboard = self.gui.qtapp.clipboard() - self.assertRegex(clipboard.text(), r'HidServAuth %s [a-zA-Z1-9]' % self.gui.app.onion_host) def hidserv_auth_string(self): '''Test the validity of the HidservAuth string''' - self.assertRegex(self.gui.app.auth_string, r'HidServAuth %s [a-zA-Z1-9]' % self.gui.app.onion_host) + self.assertRegex(self.gui.app.auth_string, r'HidServAuth {} [a-zA-Z1-9]'.format(self.gui.app.onion_host)) diff --git a/tests/TorGuiShareTest.py b/tests/TorGuiShareTest.py index ff8d0bb7..53641dce 100644 --- a/tests/TorGuiShareTest.py +++ b/tests/TorGuiShareTest.py @@ -36,11 +36,16 @@ class TorGuiShareTest(TorGuiBaseTest, GuiShareTest): '''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""" + '''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() diff --git a/tests/onionshare_share_mode_stealth_test.py b/tests/onionshare_share_mode_stealth_test.py index 3096a8bc..78e87e9e 100644 --- a/tests/onionshare_share_mode_stealth_test.py +++ b/tests/onionshare_share_mode_stealth_test.py @@ -22,8 +22,8 @@ class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest): self.run_all_common_setup_tests() self.run_all_share_mode_setup_tests() self.run_all_share_mode_started_tests(False) - self.copy_have_hidserv_auth_button(self.gui.share_mode) self.hidserv_auth_string() + self.copy_have_hidserv_auth_button(self.gui.share_mode) if __name__ == "__main__": unittest.main() diff --git a/tests/onionshare_share_mode_v2_onion_test.py b/tests/onionshare_share_mode_v2_onion_test.py new file mode 100644 index 00000000..f06f6631 --- /dev/null +++ b/tests/onionshare_share_mode_v2_onion_test.py @@ -0,0 +1,26 @@ +#!/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, 'ShareModeV2OnionTest') + + @classmethod + def tearDownClass(cls): + TorGuiShareTest.tear_down() + + @pytest.mark.tor + 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() From c9ce040e4b9ab55779ba54d909b5f470a4fac3ee Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 10:47:55 +1100 Subject: [PATCH 094/142] Fix call to Alert() when an autostop timer has run out before starting the share --- onionshare_gui/server_status.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index b86155f0..e34a3d16 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -269,7 +269,7 @@ class ServerStatus(QtWidgets.QWidget): self.timeout = self.shutdown_timeout.dateTime().toPyDateTime().replace(second=0, microsecond=0) # If the timeout has actually passed already before the user hit Start, refuse to start the server. if QtCore.QDateTime.currentDateTime().toPyDateTime() > self.timeout: - Alert(self.common, strings._('gui_server_timeout_expired', QtWidgets.QMessageBox.Warning)) + Alert(self.common, strings._('gui_server_timeout_expired'), QtWidgets.QMessageBox.Warning) else: self.start_server() else: From 63ae7c0d51b53357bcdcdcd558086a43bb09b217 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 11:57:21 +1100 Subject: [PATCH 095/142] Add better workaround for blocking QDialogs. Add unreadable file test and reinstate tor connection killed test --- tests/GuiBaseTest.py | 5 +++ tests/GuiReceiveTest.py | 5 ++- tests/GuiShareTest.py | 21 ++++++++----- tests/TorGuiBaseTest.py | 9 ++++++ ...onshare_share_mode_timer_too_short_test.py | 31 +++++++++++++++++++ ...onshare_share_mode_unreadable_file_test.py | 22 +++++++++++++ ...e_share_mode_tor_connection_killed_test.py | 25 +++++++++++++++ 7 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 tests/local_onionshare_share_mode_timer_too_short_test.py create mode 100644 tests/local_onionshare_share_mode_unreadable_file_test.py create mode 100644 tests/onionshare_share_mode_tor_connection_killed_test.py diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py index e2f194db..3b7ec4c4 100644 --- a/tests/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -303,6 +303,11 @@ class GuiBaseTest(object): # We should have timed out now self.assertEqual(mode.server_status.status, 0) + # 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 diff --git a/tests/GuiReceiveTest.py b/tests/GuiReceiveTest.py index 84d6a55a..0c0cb770 100644 --- a/tests/GuiReceiveTest.py +++ b/tests/GuiReceiveTest.py @@ -1,6 +1,6 @@ import os import requests -from PyQt5 import QtTest +from PyQt5 import QtCore, QtTest from .GuiBaseTest import GuiBaseTest class GuiReceiveTest(GuiBaseTest): @@ -24,8 +24,7 @@ class GuiReceiveTest(GuiBaseTest): path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) response = requests.post(path, files=files) - # A nasty hack to avoid the Alert dialog that blocks the rest of the test - self.gui.qtapp.exit() + QtCore.QTimer.singleShot(1000, self.accept_dialog) self.assertTrue('Error uploading, please inform the OnionShare user' in response.text) def upload_dir_permissions(self, mode=0o755): diff --git a/tests/GuiShareTest.py b/tests/GuiShareTest.py index 4f2f58e7..716bab73 100644 --- a/tests/GuiShareTest.py +++ b/tests/GuiShareTest.py @@ -12,10 +12,10 @@ class GuiShareTest(GuiBaseTest): self.assertEqual(self.gui.share_mode.server_status.web.slug, slug) # Share-specific tests - - def file_selection_widget_has_files(self): - '''Test that the number of items in the list is 2''' - self.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 2) + + 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): @@ -40,14 +40,14 @@ class GuiShareTest(GuiBaseTest): '''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.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 0) + self.file_selection_widget_has_files(0) def file_selection_widget_readd_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.assertEqual(self.gui.share_mode.server_status.file_selection.get_num_files(), 2) + self.file_selection_widget_has_files(2) def add_large_file(self): @@ -102,7 +102,7 @@ class GuiShareTest(GuiBaseTest): # A nasty hack to avoid the Alert dialog that blocks the rest of the test if not public_mode: - self.gui.qtapp.exit() + QtCore.QTimer.singleShot(1000, self.accept_dialog) # In public mode, we should still be running (no rate-limiting) if public_mode: @@ -195,3 +195,10 @@ class GuiShareTest(GuiBaseTest): self.server_timed_out(self.gui.share_mode, 10000) self.web_server_is_stopped() + + 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) diff --git a/tests/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py index 611cb202..2c88bb94 100644 --- a/tests/TorGuiBaseTest.py +++ b/tests/TorGuiBaseTest.py @@ -162,3 +162,12 @@ class TorGuiBaseTest(GuiBaseTest): 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')) diff --git a/tests/local_onionshare_share_mode_timer_too_short_test.py b/tests/local_onionshare_share_mode_timer_too_short_test.py new file mode 100644 index 00000000..16153c3e --- /dev/null +++ b/tests/local_onionshare_share_mode_timer_too_short_test.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +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, + "shutdown_timeout": True, + } + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTimerTooShortTest') + + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + + 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() diff --git a/tests/local_onionshare_share_mode_unreadable_file_test.py b/tests/local_onionshare_share_mode_unreadable_file_test.py new file mode 100644 index 00000000..0e0970ea --- /dev/null +++ b/tests/local_onionshare_share_mode_unreadable_file_test.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 +import unittest + +from .GuiShareTest import GuiShareTest + +class LocalShareModeUnReadableFileTest(unittest.TestCase, GuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + } + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeUnReadableFileTest') + + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_share_mode_unreadable_file_tests() + +if __name__ == "__main__": + unittest.main() diff --git a/tests/onionshare_share_mode_tor_connection_killed_test.py b/tests/onionshare_share_mode_tor_connection_killed_test.py new file mode 100644 index 00000000..382ed547 --- /dev/null +++ b/tests/onionshare_share_mode_tor_connection_killed_test.py @@ -0,0 +1,25 @@ +#!/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, 'ShareModeTorConnectionKilledTest') + + @pytest.mark.tor + 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() From c9a342f444449a21fafdd13ba5488b11661a77ca Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 13:48:13 +1100 Subject: [PATCH 096/142] Add simple test to ensure we can click the settings button --- ...al_onionshare_open_settings_dialog_test.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/local_onionshare_open_settings_dialog_test.py diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py new file mode 100644 index 00000000..2a4d1a01 --- /dev/null +++ b/tests/local_onionshare_open_settings_dialog_test.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +import pytest +import unittest +from PyQt5 import QtCore, QtTest + +from .GuiShareTest import GuiShareTest + +class LocalOpenSettingsDialogTest(unittest.TestCase, GuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + } + cls.gui = GuiShareTest.set_up(test_settings, 'LocalOpenSettingsDialogTest') + + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_share_mode_setup_tests() + # Make sure we can open the settings dialog via the settings button + QtCore.QTimer.singleShot(1000, self.accept_dialog) + QtTest.QTest.mouseClick(self.gui.settings_button, QtCore.Qt.LeftButton) + +if __name__ == "__main__": + unittest.main() From 042f89d31c853af30c1803eead333d06995ff9a4 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 14:33:31 +1100 Subject: [PATCH 097/142] Add a test for making sure quitting during a share prompts before shutting down share --- ...al_onionshare_open_settings_dialog_test.py | 1 - ...tting_during_share_prompts_warning_test.py | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/local_onionshare_quitting_during_share_prompts_warning_test.py diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py index 2a4d1a01..b012b6a2 100644 --- a/tests/local_onionshare_open_settings_dialog_test.py +++ b/tests/local_onionshare_open_settings_dialog_test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import pytest import unittest from PyQt5 import QtCore, QtTest diff --git a/tests/local_onionshare_quitting_during_share_prompts_warning_test.py b/tests/local_onionshare_quitting_during_share_prompts_warning_test.py new file mode 100644 index 00000000..f6425d1b --- /dev/null +++ b/tests/local_onionshare_quitting_during_share_prompts_warning_test.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +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, 'LocalQuittingDuringSharePromptsWarningTest') + + #@classmethod + #def tearDownClass(cls): + # TorGuiShareTest.tear_down() + + 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() From c60aeafc3f7efb8d711f405a81dbea354326aef0 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 14:34:29 +1100 Subject: [PATCH 098/142] Remove commented out teardownClass (even though the teardown isn't working atm :/) --- ...onionshare_quitting_during_share_prompts_warning_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/local_onionshare_quitting_during_share_prompts_warning_test.py b/tests/local_onionshare_quitting_during_share_prompts_warning_test.py index f6425d1b..b33b991c 100644 --- a/tests/local_onionshare_quitting_during_share_prompts_warning_test.py +++ b/tests/local_onionshare_quitting_during_share_prompts_warning_test.py @@ -12,9 +12,9 @@ class LocalQuittingDuringSharePromptsWarningTest(unittest.TestCase, GuiShareTest } cls.gui = GuiShareTest.set_up(test_settings, 'LocalQuittingDuringSharePromptsWarningTest') - #@classmethod - #def tearDownClass(cls): - # TorGuiShareTest.tear_down() + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() def test_gui(self): self.run_all_common_setup_tests() From e9cdf4f52d803f4dd4e8013608d1649036e0543b Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 15:21:04 +1100 Subject: [PATCH 099/142] More test coverage, particularly of Receive Mode --- tests/GuiBaseTest.py | 2 +- tests/GuiReceiveTest.py | 20 ++++++++++++---- tests/TorGuiReceiveTest.py | 12 ++++++---- ...ublic_mode_upload_non_writable_dir_test.py | 24 +++++++++++++++++++ ...onshare_receive_mode_sender_closed_test.py | 4 ++-- ...ceive_mode_upload_non_writable_dir_test.py | 4 ++-- .../local_onionshare_settings_dialog_test.py | 11 ++++++--- ...ionshare_share_mode_large_download_test.py | 4 ++-- 8 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 tests/local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py index 3b7ec4c4..0e570412 100644 --- a/tests/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -29,7 +29,7 @@ class GuiBaseTest(object): # 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 = open('/tmp/testdir/test', 'w') testfile.write('onionshare') testfile.close() diff --git a/tests/GuiReceiveTest.py b/tests/GuiReceiveTest.py index 0c0cb770..a659a79f 100644 --- a/tests/GuiReceiveTest.py +++ b/tests/GuiReceiveTest.py @@ -4,9 +4,9 @@ from PyQt5 import QtCore, QtTest from .GuiBaseTest import GuiBaseTest class GuiReceiveTest(GuiBaseTest): - def upload_file(self, public_mode, expected_file): + def upload_file(self, public_mode, file_to_upload, expected_file): '''Test that we can upload the file''' - files = {'file[]': open('/tmp/test.txt', 'rb')} + files = {'file[]': open(file_to_upload, 'rb')} if not public_mode: path = 'http://127.0.0.1:{}/{}/upload'.format(self.gui.app.port, self.gui.receive_mode.web.slug) else: @@ -31,6 +31,12 @@ class GuiReceiveTest(GuiBaseTest): '''Manipulate the permissions on the upload dir in between tests''' os.chmod('/tmp/OnionShare', mode) + def try_public_paths_in_non_public_mode(self): + response = requests.post('http://127.0.0.1:{}/upload'.format(self.gui.app.port)) + self.assertEqual(response.status_code, 404) + response = requests.get('http://127.0.0.1:{}/close'.format(self.gui.app.port)) + self.assertEqual(response.status_code, 404) + def run_receive_mode_sender_closed_tests(self, public_mode): '''Test that the share can be stopped by the sender in receive mode''' if not public_mode: @@ -65,11 +71,17 @@ class GuiReceiveTest(GuiBaseTest): def run_all_receive_mode_tests(self, public_mode, receive_allow_receiver_shutdown): '''Upload files in receive mode and stop the share''' self.run_all_receive_mode_setup_tests(public_mode) - self.upload_file(public_mode, '/tmp/OnionShare/test.txt') + if not public_mode: + self.try_public_paths_in_non_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/OnionShare/test-2.txt') + 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() diff --git a/tests/TorGuiReceiveTest.py b/tests/TorGuiReceiveTest.py index 3c380b8a..a21dd4fc 100644 --- a/tests/TorGuiReceiveTest.py +++ b/tests/TorGuiReceiveTest.py @@ -5,13 +5,13 @@ from .TorGuiBaseTest import TorGuiBaseTest class TorGuiReceiveTest(TorGuiBaseTest): - def upload_file(self, public_mode, expected_file): + 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'] = 'socks5h://{}:{}'.format(socks_address, socks_port) - files = {'file[]': open('/tmp/test.txt', 'rb')} + files = {'file[]': open(file_to_upload, 'rb')} if not public_mode: path = 'http://{}/{}/upload'.format(self.gui.app.onion_host, self.gui.receive_mode.web.slug) else: @@ -40,11 +40,15 @@ class TorGuiReceiveTest(TorGuiBaseTest): 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/OnionShare/test.txt') + 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/OnionShare/test-2.txt') + 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() diff --git a/tests/local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py new file mode 100644 index 00000000..2bffb4dd --- /dev/null +++ b/tests/local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +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, 'LocalReceivePublicModeUnwritableTest') + + @classmethod + def tearDownClass(cls): + GuiReceiveTest.tear_down() + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_receive_mode_unwritable_dir_tests(True, True) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/local_onionshare_receive_mode_sender_closed_test.py b/tests/local_onionshare_receive_mode_sender_closed_test.py index 1f16b5fb..3a0d8617 100644 --- a/tests/local_onionshare_receive_mode_sender_closed_test.py +++ b/tests/local_onionshare_receive_mode_sender_closed_test.py @@ -3,13 +3,13 @@ import unittest from .GuiReceiveTest import GuiReceiveTest -class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): +class LocalReceiveModeSenderClosedTest(unittest.TestCase, GuiReceiveTest): @classmethod def setUpClass(cls): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeSenderClosedTest') @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py index ee3a7215..b6f06b08 100644 --- a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py +++ b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py @@ -3,13 +3,13 @@ import unittest from .GuiReceiveTest import GuiReceiveTest -class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): +class LocalReceiveModeUnwritableTest(unittest.TestCase, GuiReceiveTest): @classmethod def setUpClass(cls): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeUnwritableTest') @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_settings_dialog_test.py b/tests/local_onionshare_settings_dialog_test.py index 64840d7d..a328f53b 100644 --- a/tests/local_onionshare_settings_dialog_test.py +++ b/tests/local_onionshare_settings_dialog_test.py @@ -11,7 +11,7 @@ class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest): def setUpClass(cls): test_settings = { "no_bridges": False, - "tor_bridges_use_obfs4": True, + "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", } cls.gui = SettingsGuiBaseTest.set_up(test_settings, 'settings') @@ -97,8 +97,12 @@ class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest): 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 obfs4 + # 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 @@ -143,10 +147,11 @@ class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest): # 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)) - # set some custom bridges + # 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 diff --git a/tests/local_onionshare_share_mode_large_download_test.py b/tests/local_onionshare_share_mode_large_download_test.py index b8017b77..5f5de888 100644 --- a/tests/local_onionshare_share_mode_large_download_test.py +++ b/tests/local_onionshare_share_mode_large_download_test.py @@ -3,12 +3,12 @@ import unittest from .GuiShareTest import GuiShareTest -class LocalShareModeTest(unittest.TestCase, GuiShareTest): +class LocalShareModeLargeDownloadTest(unittest.TestCase, GuiShareTest): @classmethod def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') + cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeLargeDownloadTest') @classmethod def tearDownClass(cls): From ef01da3fadf437aef3f153240ea937a3a6cd56dc Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 16:31:51 +1100 Subject: [PATCH 100/142] Remove unique settings file per test, because they don't run concurrently anymore --- tests/GuiBaseTest.py | 7 ++++--- tests/SettingsGuiBaseTest.py | 6 +++--- tests/TorGuiBaseTest.py | 6 +++--- ...ocal_onionshare_404_public_mode_skips_ratelimit_test.py | 2 +- tests/local_onionshare_404_triggers_ratelimit_test.py | 2 +- tests/local_onionshare_open_settings_dialog_test.py | 2 +- ...nionshare_quitting_during_share_prompts_warning_test.py | 2 +- tests/local_onionshare_receive_mode_sender_closed_test.py | 2 +- tests/local_onionshare_receive_mode_timer_test.py | 2 +- ...onionshare_receive_mode_upload_non_writable_dir_test.py | 2 +- ...ceive_mode_upload_public_mode_non_writable_dir_test.py} | 2 +- ...ocal_onionshare_receive_mode_upload_public_mode_test.py | 2 +- tests/local_onionshare_receive_mode_upload_test.py | 2 +- tests/local_onionshare_settings_dialog_test.py | 2 +- ...ocal_onionshare_share_mode_download_public_mode_test.py | 2 +- .../local_onionshare_share_mode_download_stay_open_test.py | 2 +- tests/local_onionshare_share_mode_download_test.py | 2 +- tests/local_onionshare_share_mode_large_download_test.py | 2 +- tests/local_onionshare_share_mode_slug_persistent_test.py | 2 +- tests/local_onionshare_share_mode_timer_test.py | 2 +- tests/local_onionshare_share_mode_timer_too_short_test.py | 2 +- tests/local_onionshare_share_mode_unreadable_file_test.py | 2 +- tests/onionshare_790_cancel_on_second_share_test.py | 2 +- tests/onionshare_receive_mode_upload_public_mode_test.py | 2 +- tests/onionshare_receive_mode_upload_test.py | 2 +- tests/onionshare_share_mode_cancel_share_test.py | 2 +- tests/onionshare_share_mode_download_public_mode_test.py | 2 +- tests/onionshare_share_mode_download_stay_open_test.py | 2 +- tests/onionshare_share_mode_download_test.py | 2 +- tests/onionshare_share_mode_persistent_test.py | 2 +- tests/onionshare_share_mode_stealth_test.py | 2 +- tests/onionshare_share_mode_timer_test.py | 2 +- tests/onionshare_share_mode_tor_connection_killed_test.py | 2 +- tests/onionshare_share_mode_v2_onion_test.py | 2 +- 34 files changed, 41 insertions(+), 40 deletions(-) rename tests/{local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py => local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py} (86%) diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py index 0e570412..af5f1944 100644 --- a/tests/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -19,7 +19,7 @@ from onionshare_gui.mode.receive_mode import ReceiveMode class GuiBaseTest(object): @staticmethod - def set_up(test_settings, settings_filename): + def set_up(test_settings): '''Create GUI with given settings''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -51,9 +51,9 @@ class GuiBaseTest(object): app = OnionShare(common, testonion, True, 0) web = Web(common, False, True) - open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) + open('/tmp/settings.json', 'w').write(json.dumps(test_settings)) - gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt', '/tmp/testdir'], '/tmp/{}.json'.format(settings_filename), True) + gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt', '/tmp/testdir'], '/tmp/settings.json', True) return gui @staticmethod @@ -61,6 +61,7 @@ class GuiBaseTest(object): '''Clean up after tests''' try: os.remove('/tmp/test.txt') + os.remove('/tmp/settings.json') os.remove('/tmp/largefile') shutil.rmtree('/tmp/OnionShare') shutil.rmtree('/tmp/testdir') diff --git a/tests/SettingsGuiBaseTest.py b/tests/SettingsGuiBaseTest.py index dac074fc..195e7933 100644 --- a/tests/SettingsGuiBaseTest.py +++ b/tests/SettingsGuiBaseTest.py @@ -13,7 +13,7 @@ from onionshare_gui.settings_dialog import SettingsDialog class SettingsGuiBaseTest(object): @staticmethod - def set_up(test_settings, settings_filename): + def set_up(test_settings): '''Create the GUI''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -37,9 +37,9 @@ class SettingsGuiBaseTest(object): if key not in test_settings: test_settings[key] = val - open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) + open('/tmp/settings.json', 'w').write(json.dumps(test_settings)) - gui = SettingsDialog(common, testonion, qtapp, '/tmp/{}.json'.format(settings_filename), True) + gui = SettingsDialog(common, testonion, qtapp, '/tmp/settings.json', True) return gui diff --git a/tests/TorGuiBaseTest.py b/tests/TorGuiBaseTest.py index 2c88bb94..9a0bda3e 100644 --- a/tests/TorGuiBaseTest.py +++ b/tests/TorGuiBaseTest.py @@ -18,7 +18,7 @@ from .GuiBaseTest import GuiBaseTest class TorGuiBaseTest(GuiBaseTest): @staticmethod - def set_up(test_settings, settings_filename): + def set_up(test_settings): '''Create GUI with given settings''' # Create our test file testfile = open('/tmp/test.txt', 'w') @@ -51,9 +51,9 @@ class TorGuiBaseTest(GuiBaseTest): app = OnionShare(common, testonion, False, 0) web = Web(common, False, False) - open('/tmp/{}.json'.format(settings_filename), 'w').write(json.dumps(test_settings)) + open('/tmp/settings.json', 'w').write(json.dumps(test_settings)) - gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt', '/tmp/testdir'], '/tmp/{}.json'.format(settings_filename), False) + gui = OnionShareGui(common, testonion, qtapp, app, ['/tmp/test.txt', '/tmp/testdir'], '/tmp/settings.json', False) return gui def history_indicator(self, mode, public_mode): diff --git a/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py b/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py index c4c271b8..11feb6f0 100644 --- a/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py +++ b/tests/local_onionshare_404_public_mode_skips_ratelimit_test.py @@ -10,7 +10,7 @@ class Local404PublicModeRateLimitTest(unittest.TestCase, GuiShareTest): "close_after_first_download": False, "public_mode": True } - cls.gui = GuiShareTest.set_up(test_settings, 'Local404PublicModeRateLimitTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_404_triggers_ratelimit_test.py b/tests/local_onionshare_404_triggers_ratelimit_test.py index 8f9caa7c..ad49c3f8 100644 --- a/tests/local_onionshare_404_triggers_ratelimit_test.py +++ b/tests/local_onionshare_404_triggers_ratelimit_test.py @@ -9,7 +9,7 @@ class Local404RateLimitTest(unittest.TestCase, GuiShareTest): test_settings = { "close_after_first_download": False } - cls.gui = GuiShareTest.set_up(test_settings, 'Local404RateLimitTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py index b012b6a2..61e66be2 100644 --- a/tests/local_onionshare_open_settings_dialog_test.py +++ b/tests/local_onionshare_open_settings_dialog_test.py @@ -9,7 +9,7 @@ class LocalOpenSettingsDialogTest(unittest.TestCase, GuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalOpenSettingsDialogTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_quitting_during_share_prompts_warning_test.py b/tests/local_onionshare_quitting_during_share_prompts_warning_test.py index b33b991c..d2fe4986 100644 --- a/tests/local_onionshare_quitting_during_share_prompts_warning_test.py +++ b/tests/local_onionshare_quitting_during_share_prompts_warning_test.py @@ -10,7 +10,7 @@ class LocalQuittingDuringSharePromptsWarningTest(unittest.TestCase, GuiShareTest test_settings = { "close_after_first_download": False } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalQuittingDuringSharePromptsWarningTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_receive_mode_sender_closed_test.py b/tests/local_onionshare_receive_mode_sender_closed_test.py index 3a0d8617..e177d2ef 100644 --- a/tests/local_onionshare_receive_mode_sender_closed_test.py +++ b/tests/local_onionshare_receive_mode_sender_closed_test.py @@ -9,7 +9,7 @@ class LocalReceiveModeSenderClosedTest(unittest.TestCase, GuiReceiveTest): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeSenderClosedTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_receive_mode_timer_test.py b/tests/local_onionshare_receive_mode_timer_test.py index 039acff4..88002f94 100644 --- a/tests/local_onionshare_receive_mode_timer_test.py +++ b/tests/local_onionshare_receive_mode_timer_test.py @@ -10,7 +10,7 @@ class LocalReceiveModeTimerTest(unittest.TestCase, GuiReceiveTest): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTimerTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py index b6f06b08..7d7b2780 100644 --- a/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py +++ b/tests/local_onionshare_receive_mode_upload_non_writable_dir_test.py @@ -9,7 +9,7 @@ class LocalReceiveModeUnwritableTest(unittest.TestCase, GuiReceiveTest): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeUnwritableTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py similarity index 86% rename from tests/local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py rename to tests/local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py index 2bffb4dd..cdc4e62a 100644 --- a/tests/local_onionshare_receive_mode_public_mode_upload_non_writable_dir_test.py +++ b/tests/local_onionshare_receive_mode_upload_public_mode_non_writable_dir_test.py @@ -10,7 +10,7 @@ class LocalReceivePublicModeUnwritableTest(unittest.TestCase, GuiReceiveTest): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceivePublicModeUnwritableTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_receive_mode_upload_public_mode_test.py b/tests/local_onionshare_receive_mode_upload_public_mode_test.py index 654895ca..bedb7ae2 100644 --- a/tests/local_onionshare_receive_mode_upload_public_mode_test.py +++ b/tests/local_onionshare_receive_mode_upload_public_mode_test.py @@ -10,7 +10,7 @@ class LocalReceiveModePublicModeTest(unittest.TestCase, GuiReceiveTest): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModePublicModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_receive_mode_upload_test.py b/tests/local_onionshare_receive_mode_upload_test.py index c06d30cd..82baf3fd 100644 --- a/tests/local_onionshare_receive_mode_upload_test.py +++ b/tests/local_onionshare_receive_mode_upload_test.py @@ -9,7 +9,7 @@ class LocalReceiveModeTest(unittest.TestCase, GuiReceiveTest): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = GuiReceiveTest.set_up(test_settings, 'LocalReceiveModeTest') + cls.gui = GuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_settings_dialog_test.py b/tests/local_onionshare_settings_dialog_test.py index a328f53b..6d8923b6 100644 --- a/tests/local_onionshare_settings_dialog_test.py +++ b/tests/local_onionshare_settings_dialog_test.py @@ -13,7 +13,7 @@ class SettingsGuiTest(unittest.TestCase, SettingsGuiBaseTest): "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", } - cls.gui = SettingsGuiBaseTest.set_up(test_settings, 'settings') + cls.gui = SettingsGuiBaseTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_download_public_mode_test.py b/tests/local_onionshare_share_mode_download_public_mode_test.py index f1c29990..d6dff13a 100644 --- a/tests/local_onionshare_share_mode_download_public_mode_test.py +++ b/tests/local_onionshare_share_mode_download_public_mode_test.py @@ -9,7 +9,7 @@ class LocalShareModePublicModeTest(unittest.TestCase, GuiShareTest): test_settings = { "public_mode": True, } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePublicModeTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_download_stay_open_test.py b/tests/local_onionshare_share_mode_download_stay_open_test.py index af02e841..54d6de51 100644 --- a/tests/local_onionshare_share_mode_download_stay_open_test.py +++ b/tests/local_onionshare_share_mode_download_stay_open_test.py @@ -9,7 +9,7 @@ class LocalShareModeStayOpenTest(unittest.TestCase, GuiShareTest): test_settings = { "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeStayOpenTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_download_test.py b/tests/local_onionshare_share_mode_download_test.py index 53db0296..ff182740 100644 --- a/tests/local_onionshare_share_mode_download_test.py +++ b/tests/local_onionshare_share_mode_download_test.py @@ -8,7 +8,7 @@ class LocalShareModeTest(unittest.TestCase, GuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_large_download_test.py b/tests/local_onionshare_share_mode_large_download_test.py index 5f5de888..46e6df28 100644 --- a/tests/local_onionshare_share_mode_large_download_test.py +++ b/tests/local_onionshare_share_mode_large_download_test.py @@ -8,7 +8,7 @@ class LocalShareModeLargeDownloadTest(unittest.TestCase, GuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeLargeDownloadTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_slug_persistent_test.py b/tests/local_onionshare_share_mode_slug_persistent_test.py index c273fbda..a1cc6972 100644 --- a/tests/local_onionshare_share_mode_slug_persistent_test.py +++ b/tests/local_onionshare_share_mode_slug_persistent_test.py @@ -12,7 +12,7 @@ class LocalShareModePersistentSlugTest(unittest.TestCase, GuiShareTest): "save_private_key": True, "close_after_first_download": False, } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModePersistentSlugTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_timer_test.py b/tests/local_onionshare_share_mode_timer_test.py index 394dec21..41a6268d 100644 --- a/tests/local_onionshare_share_mode_timer_test.py +++ b/tests/local_onionshare_share_mode_timer_test.py @@ -10,7 +10,7 @@ class LocalShareModeTimerTest(unittest.TestCase, GuiShareTest): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTimerTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_timer_too_short_test.py b/tests/local_onionshare_share_mode_timer_too_short_test.py index 16153c3e..41c30883 100644 --- a/tests/local_onionshare_share_mode_timer_too_short_test.py +++ b/tests/local_onionshare_share_mode_timer_too_short_test.py @@ -11,7 +11,7 @@ class LocalShareModeTimerTooShortTest(unittest.TestCase, GuiShareTest): "public_mode": False, "shutdown_timeout": True, } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeTimerTooShortTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/local_onionshare_share_mode_unreadable_file_test.py b/tests/local_onionshare_share_mode_unreadable_file_test.py index 0e0970ea..38a0e847 100644 --- a/tests/local_onionshare_share_mode_unreadable_file_test.py +++ b/tests/local_onionshare_share_mode_unreadable_file_test.py @@ -8,7 +8,7 @@ class LocalShareModeUnReadableFileTest(unittest.TestCase, GuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = GuiShareTest.set_up(test_settings, 'LocalShareModeUnReadableFileTest') + cls.gui = GuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_790_cancel_on_second_share_test.py b/tests/onionshare_790_cancel_on_second_share_test.py index dce84f62..b144edf3 100644 --- a/tests/onionshare_790_cancel_on_second_share_test.py +++ b/tests/onionshare_790_cancel_on_second_share_test.py @@ -11,7 +11,7 @@ class ShareModeCancelSecondShareTest(unittest.TestCase, TorGuiShareTest): test_settings = { "close_after_first_download": True } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelSecondShareTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_receive_mode_upload_public_mode_test.py b/tests/onionshare_receive_mode_upload_public_mode_test.py index 048186c3..275e5953 100644 --- a/tests/onionshare_receive_mode_upload_public_mode_test.py +++ b/tests/onionshare_receive_mode_upload_public_mode_test.py @@ -11,7 +11,7 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): "public_mode": True, "receive_allow_receiver_shutdown": True } - cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') + cls.gui = TorGuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_receive_mode_upload_test.py b/tests/onionshare_receive_mode_upload_test.py index d3965d59..f9914659 100644 --- a/tests/onionshare_receive_mode_upload_test.py +++ b/tests/onionshare_receive_mode_upload_test.py @@ -10,7 +10,7 @@ class ReceiveModeTest(unittest.TestCase, TorGuiReceiveTest): test_settings = { "receive_allow_receiver_shutdown": True } - cls.gui = TorGuiReceiveTest.set_up(test_settings, 'ReceiveModeTest') + cls.gui = TorGuiReceiveTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_cancel_share_test.py b/tests/onionshare_share_mode_cancel_share_test.py index 83a009a1..5f4d6fb3 100644 --- a/tests/onionshare_share_mode_cancel_share_test.py +++ b/tests/onionshare_share_mode_cancel_share_test.py @@ -9,7 +9,7 @@ class ShareModeCancelTest(unittest.TestCase, TorGuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeCancelTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_download_public_mode_test.py b/tests/onionshare_share_mode_download_public_mode_test.py index 8c5740c5..672603ce 100644 --- a/tests/onionshare_share_mode_download_public_mode_test.py +++ b/tests/onionshare_share_mode_download_public_mode_test.py @@ -10,7 +10,7 @@ class ShareModePublicModeTest(unittest.TestCase, TorGuiShareTest): test_settings = { "public_mode": True, } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePublicModeTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_download_stay_open_test.py b/tests/onionshare_share_mode_download_stay_open_test.py index 56ac924d..e7e64083 100644 --- a/tests/onionshare_share_mode_download_stay_open_test.py +++ b/tests/onionshare_share_mode_download_stay_open_test.py @@ -10,7 +10,7 @@ class ShareModeStayOpenTest(unittest.TestCase, TorGuiShareTest): test_settings = { "close_after_first_download": False, } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStayOpenTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_download_test.py b/tests/onionshare_share_mode_download_test.py index 125909d0..7d414e5d 100644 --- a/tests/onionshare_share_mode_download_test.py +++ b/tests/onionshare_share_mode_download_test.py @@ -9,7 +9,7 @@ class ShareModeTest(unittest.TestCase, TorGuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_persistent_test.py b/tests/onionshare_share_mode_persistent_test.py index 3f103a1a..86b61a81 100644 --- a/tests/onionshare_share_mode_persistent_test.py +++ b/tests/onionshare_share_mode_persistent_test.py @@ -14,7 +14,7 @@ class ShareModePersistentSlugTest(unittest.TestCase, TorGuiShareTest): "save_private_key": True, "close_after_first_download": False, } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModePersistentSlugTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_stealth_test.py b/tests/onionshare_share_mode_stealth_test.py index 78e87e9e..b16669e6 100644 --- a/tests/onionshare_share_mode_stealth_test.py +++ b/tests/onionshare_share_mode_stealth_test.py @@ -11,7 +11,7 @@ class ShareModeStealthTest(unittest.TestCase, TorGuiShareTest): "use_legacy_v2_onions": True, "use_stealth": True, } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeStealthTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_timer_test.py b/tests/onionshare_share_mode_timer_test.py index 9e690ec7..a13d2d80 100644 --- a/tests/onionshare_share_mode_timer_test.py +++ b/tests/onionshare_share_mode_timer_test.py @@ -11,7 +11,7 @@ class ShareModeTimerTest(unittest.TestCase, TorGuiShareTest): "public_mode": False, "shutdown_timeout": True, } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTimerTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): diff --git a/tests/onionshare_share_mode_tor_connection_killed_test.py b/tests/onionshare_share_mode_tor_connection_killed_test.py index 382ed547..62513a12 100644 --- a/tests/onionshare_share_mode_tor_connection_killed_test.py +++ b/tests/onionshare_share_mode_tor_connection_killed_test.py @@ -9,7 +9,7 @@ class ShareModeTorConnectionKilledTest(unittest.TestCase, TorGuiShareTest): def setUpClass(cls): test_settings = { } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeTorConnectionKilledTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @pytest.mark.tor def test_gui(self): diff --git a/tests/onionshare_share_mode_v2_onion_test.py b/tests/onionshare_share_mode_v2_onion_test.py index f06f6631..c932abf9 100644 --- a/tests/onionshare_share_mode_v2_onion_test.py +++ b/tests/onionshare_share_mode_v2_onion_test.py @@ -10,7 +10,7 @@ class ShareModeV2OnionTest(unittest.TestCase, TorGuiShareTest): test_settings = { "use_legacy_v2_onions": True, } - cls.gui = TorGuiShareTest.set_up(test_settings, 'ShareModeV2OnionTest') + cls.gui = TorGuiShareTest.set_up(test_settings) @classmethod def tearDownClass(cls): From ec6541dfbc321f421b64d4ece59284d38a250520 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 16:36:58 +1100 Subject: [PATCH 101/142] raise timer seuqnce on open settings dialog test (in case that's why it's segfaulting in Travis) --- tests/local_onionshare_open_settings_dialog_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py index 61e66be2..af20c73f 100644 --- a/tests/local_onionshare_open_settings_dialog_test.py +++ b/tests/local_onionshare_open_settings_dialog_test.py @@ -19,7 +19,7 @@ class LocalOpenSettingsDialogTest(unittest.TestCase, GuiShareTest): self.run_all_common_setup_tests() self.run_all_share_mode_setup_tests() # Make sure we can open the settings dialog via the settings button - QtCore.QTimer.singleShot(1000, self.accept_dialog) + QtCore.QTimer.singleShot(4000, self.accept_dialog) QtTest.QTest.mouseClick(self.gui.settings_button, QtCore.Qt.LeftButton) if __name__ == "__main__": From 2692e47d5468cd58b0d2248adf8b0a6043b28f13 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 16:45:52 +1100 Subject: [PATCH 102/142] Revert "raise timer seuqnce on open settings dialog test (in case that's why it's segfaulting in Travis)" This reverts commit ec6541dfbc321f421b64d4ece59284d38a250520. --- tests/local_onionshare_open_settings_dialog_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py index af20c73f..61e66be2 100644 --- a/tests/local_onionshare_open_settings_dialog_test.py +++ b/tests/local_onionshare_open_settings_dialog_test.py @@ -19,7 +19,7 @@ class LocalOpenSettingsDialogTest(unittest.TestCase, GuiShareTest): self.run_all_common_setup_tests() self.run_all_share_mode_setup_tests() # Make sure we can open the settings dialog via the settings button - QtCore.QTimer.singleShot(4000, self.accept_dialog) + QtCore.QTimer.singleShot(1000, self.accept_dialog) QtTest.QTest.mouseClick(self.gui.settings_button, QtCore.Qt.LeftButton) if __name__ == "__main__": From fddf65ec500ff1409664c86f1edce7164d7397a6 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 16:51:49 +1100 Subject: [PATCH 103/142] Add initial .circleci config --- .circleci/config.yml | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..17e8979c --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,43 @@ +# Python CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-python/ for more details +# +version: 2 +jobs: + build: + docker: + # specify the version you desire here + # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` + - image: circleci/python:3.6.1 + + working_directory: ~/repo + + steps: + - checkout + + # Download and cache dependencies + - restore_cache: + keys: + - v1-dependencies-{{ checksum "install/requirements-tests.txt" }} + # fallback to using the latest cache if no exact match is found + - v1-dependencies- + + - run: + name: install dependencies + command: | + python3 -m venv venv + . venv/bin/activate + pip install -r install/requirements-tests.txt + + - save_cache: + paths: + - ./venv + key: v1-dependencies-{{ checksum "install/requirements-tests.txt" }} + + # run tests! + - run: + name: run tests + command: | + . venv/bin/activate + xvfb-run pytest --cov=onionshare --cov=onionshare_gui --cov-report=term-missing -vvv tests/ + From 2dbc7d766aed541d8d6455e07c072846cb77a1f2 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 16:55:15 +1100 Subject: [PATCH 104/142] try to get circleci to build just this branch for now --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 17e8979c..79f902c5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,6 +5,9 @@ version: 2 jobs: build: + branches: + only: + - fix_tor_tests docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` From 8bf740d9ccc63362bd44b0ecfa7c87cf0dc50820 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 16:58:05 +1100 Subject: [PATCH 105/142] circleci tweaks --- .circleci/config.yml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 79f902c5..6adcdfa9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,27 +18,26 @@ jobs: steps: - checkout - # Download and cache dependencies - - restore_cache: - keys: - - v1-dependencies-{{ checksum "install/requirements-tests.txt" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - run: name: install dependencies command: | + sudo apt-get update && sudo apt-get install python3-pyqt5 python3 -m venv venv . venv/bin/activate + pip install -r install/requirements.txt + pip install -r install/requirements-tests.txt + pip install pytest-cov flake8 pip install -r install/requirements-tests.txt - - save_cache: - paths: - - ./venv - key: v1-dependencies-{{ checksum "install/requirements-tests.txt" }} - # run tests! - run: + name: run flask tests + command: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + name: run tests command: | . venv/bin/activate From d2c10558230c304005087364f54e04569841e8b9 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 16:59:13 +1100 Subject: [PATCH 106/142] circleci tweaks --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6adcdfa9..f50a98f7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,11 +33,13 @@ jobs: - run: name: run flask tests command: | + . venv/bin/activate # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - run: name: run tests command: | . venv/bin/activate From 6c5df1cffcc86436807d2fe37ff0f9bd53b90942 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:04:24 +1100 Subject: [PATCH 107/142] circleci tweaks --- .circleci/config.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f50a98f7..ff902d04 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,18 +22,14 @@ jobs: name: install dependencies command: | sudo apt-get update && sudo apt-get install python3-pyqt5 - python3 -m venv venv - . venv/bin/activate - pip install -r install/requirements.txt - pip install -r install/requirements-tests.txt - pip install pytest-cov flake8 - pip install -r install/requirements-tests.txt + pip3 install -r install/requirements.txt + pip3 install -r install/requirements-tests.txt + pip3 install pytest-cov flake8 # run tests! - run: name: run flask tests command: | - . venv/bin/activate # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide @@ -42,6 +38,5 @@ jobs: - run: name: run tests command: | - . venv/bin/activate xvfb-run pytest --cov=onionshare --cov=onionshare_gui --cov-report=term-missing -vvv tests/ From 3139aa9a57b9f70cc6fa4cd8f43b46bcb2b673dd Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:15:13 +1100 Subject: [PATCH 108/142] sudo --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ff902d04..ba6d4ab8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,9 +22,9 @@ jobs: name: install dependencies command: | sudo apt-get update && sudo apt-get install python3-pyqt5 - pip3 install -r install/requirements.txt - pip3 install -r install/requirements-tests.txt - pip3 install pytest-cov flake8 + sudo pip3 install -r install/requirements.txt + sudo pip3 install -r install/requirements-tests.txt + sudo pip3 install pytest-cov flake8 # run tests! - run: From 75dbf4f14b92d697d42280ada039cee41a60f2e8 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:15:34 +1100 Subject: [PATCH 109/142] remove branch specific config --- .circleci/config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ba6d4ab8..52576430 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,9 +5,6 @@ version: 2 jobs: build: - branches: - only: - - fix_tor_tests docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` From 0e95749e33a3d26731552798cbd70f1c810fa969 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:17:43 +1100 Subject: [PATCH 110/142] Travis and CircleCI hate this simple test --- ...al_onionshare_open_settings_dialog_test.py | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 tests/local_onionshare_open_settings_dialog_test.py diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py deleted file mode 100644 index 61e66be2..00000000 --- a/tests/local_onionshare_open_settings_dialog_test.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -import unittest -from PyQt5 import QtCore, QtTest - -from .GuiShareTest import GuiShareTest - -class LocalOpenSettingsDialogTest(unittest.TestCase, GuiShareTest): - @classmethod - def setUpClass(cls): - test_settings = { - } - cls.gui = GuiShareTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiShareTest.tear_down() - - def test_gui(self): - self.run_all_common_setup_tests() - self.run_all_share_mode_setup_tests() - # Make sure we can open the settings dialog via the settings button - QtCore.QTimer.singleShot(1000, self.accept_dialog) - QtTest.QTest.mouseClick(self.gui.settings_button, QtCore.Qt.LeftButton) - -if __name__ == "__main__": - unittest.main() From 8e4c70e7fb2e528f7273ffc7f4a512733f09b07b Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:23:25 +1100 Subject: [PATCH 111/142] Fix path to large_file in teardown class --- tests/GuiBaseTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py index af5f1944..68f18f72 100644 --- a/tests/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -62,7 +62,7 @@ class GuiBaseTest(object): try: os.remove('/tmp/test.txt') os.remove('/tmp/settings.json') - os.remove('/tmp/largefile') + os.remove('/tmp/large_file') shutil.rmtree('/tmp/OnionShare') shutil.rmtree('/tmp/testdir') except: From 4ae5c9bcd92e49b36138da548abd9c1a1b23ce1e Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:28:13 +1100 Subject: [PATCH 112/142] run on same version of python as me --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 52576430..23bf4806 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ jobs: docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` - - image: circleci/python:3.6.1 + - image: circleci/python:3.6.6 working_directory: ~/repo From 7a7d992cb7cedf36a2709092d3c9ad2ed07f47ea Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:29:44 +1100 Subject: [PATCH 113/142] more cleanup in teardown class --- tests/GuiBaseTest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/GuiBaseTest.py b/tests/GuiBaseTest.py index 68f18f72..c557fc15 100644 --- a/tests/GuiBaseTest.py +++ b/tests/GuiBaseTest.py @@ -63,8 +63,10 @@ class GuiBaseTest(object): os.remove('/tmp/test.txt') os.remove('/tmp/settings.json') os.remove('/tmp/large_file') - shutil.rmtree('/tmp/OnionShare') + os.remove('/tmp/download.zip') + os.remove('/tmp/webpage') shutil.rmtree('/tmp/testdir') + shutil.rmtree('/tmp/OnionShare') except: pass From 29f987a903ab96b4c741e809f00b83d47294910a Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:38:28 +1100 Subject: [PATCH 114/142] see if it's a version issue --- install/requirements-tests.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/requirements-tests.txt b/install/requirements-tests.txt index b931afd1..849e1166 100644 --- a/install/requirements-tests.txt +++ b/install/requirements-tests.txt @@ -1,9 +1,9 @@ atomicwrites==1.2.1 attrs==18.2.0 more-itertools==4.3.0 -pluggy==0.6.0 -py==1.6.0 -pytest==3.4.2 +pluggy==0.7.1 +py==1.7.0 +pytest==3.8.2 pytest-faulthandler==1.5.0 pytest-qt==3.1.0 six==1.11.0 From 95f30f9a4241feb7de17b6f20a082e531d63349a Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:50:16 +1100 Subject: [PATCH 115/142] The only other version difference I can find is PyQt itself --- .circleci/config.yml | 1 - install/requirements.txt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 23bf4806..3594e9f8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,6 @@ jobs: - run: name: install dependencies command: | - sudo apt-get update && sudo apt-get install python3-pyqt5 sudo pip3 install -r install/requirements.txt sudo pip3 install -r install/requirements-tests.txt sudo pip3 install pytest-cov flake8 diff --git a/install/requirements.txt b/install/requirements.txt index 32ec6887..f09d2e95 100644 --- a/install/requirements.txt +++ b/install/requirements.txt @@ -17,7 +17,7 @@ pycparser==2.18 pycryptodome==3.6.6 PyInstaller==3.4 PyNaCl==1.2.1 -PyQt5==5.11.2 +PyQt5==5.11.3 PyQt5-sip==4.19.12 PySocks==1.6.8 requests==2.19.1 From fab25aca114b0b578991cebd42eb002e5566ebd8 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:51:45 +1100 Subject: [PATCH 116/142] Revert "The only other version difference I can find is PyQt itself" This reverts commit 95f30f9a4241feb7de17b6f20a082e531d63349a. --- .circleci/config.yml | 1 + install/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3594e9f8..23bf4806 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,7 @@ jobs: - run: name: install dependencies command: | + sudo apt-get update && sudo apt-get install python3-pyqt5 sudo pip3 install -r install/requirements.txt sudo pip3 install -r install/requirements-tests.txt sudo pip3 install pytest-cov flake8 diff --git a/install/requirements.txt b/install/requirements.txt index f09d2e95..32ec6887 100644 --- a/install/requirements.txt +++ b/install/requirements.txt @@ -17,7 +17,7 @@ pycparser==2.18 pycryptodome==3.6.6 PyInstaller==3.4 PyNaCl==1.2.1 -PyQt5==5.11.3 +PyQt5==5.11.2 PyQt5-sip==4.19.12 PySocks==1.6.8 requests==2.19.1 From 8a9b6ac63383c348ca88f656ee3d9362f338f1a6 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 17:59:16 +1100 Subject: [PATCH 117/142] Tweaks to SettingsGuiBaseTest object --- tests/SettingsGuiBaseTest.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/SettingsGuiBaseTest.py b/tests/SettingsGuiBaseTest.py index 195e7933..e59a58a8 100644 --- a/tests/SettingsGuiBaseTest.py +++ b/tests/SettingsGuiBaseTest.py @@ -1,13 +1,10 @@ import json import os -import sys -from PyQt5 import QtWidgets 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 from onionshare_gui.settings_dialog import SettingsDialog @@ -31,8 +28,6 @@ class SettingsGuiBaseTest(object): qtapp = Application(common) app = OnionShare(common, testonion, True, 0) - web = Web(common, False, True) - for key, val in common.settings.default_settings.items(): if key not in test_settings: test_settings[key] = val From 7d9f2f1458f166b4860b5ea1a41c0b74ad98aff2 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Wed, 17 Oct 2018 18:04:38 +1100 Subject: [PATCH 118/142] pytest-qt is 3.2.1 on my machine --- install/requirements-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/requirements-tests.txt b/install/requirements-tests.txt index 849e1166..57e98ce1 100644 --- a/install/requirements-tests.txt +++ b/install/requirements-tests.txt @@ -5,6 +5,6 @@ pluggy==0.7.1 py==1.7.0 pytest==3.8.2 pytest-faulthandler==1.5.0 -pytest-qt==3.1.0 +pytest-qt==3.2.1 six==1.11.0 urllib3==1.23 From 3b3e79fdf0101dadce70084c9af85fc1d73b7cb4 Mon Sep 17 00:00:00 2001 From: Austin Jackson Date: Wed, 17 Oct 2018 13:19:35 -0500 Subject: [PATCH 119/142] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55487045..fbb9c914 100644 --- a/README.md +++ b/README.md @@ -18,5 +18,5 @@ You can set up your development environment to build OnionShare yourself by foll # Screenshots -![Server Screenshot](/screenshots/server.png) +![Server Screenshot](/screenshots/appdata-server.png) ![Client Screenshot](/screenshots/client.png) From 25d6bd12ead9c6dca927f025e69cf1ba3cd5f291 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 16:57:05 +1100 Subject: [PATCH 120/142] try and build off buster --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 23bf4806..4ad43577 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ jobs: docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` - - image: circleci/python:3.6.6 + - image: debian/buster working_directory: ~/repo @@ -18,7 +18,7 @@ jobs: - run: name: install dependencies command: | - sudo apt-get update && sudo apt-get install python3-pyqt5 + sudo apt-get update && sudo apt-get install python3-pyqt5 python3-pip sudo pip3 install -r install/requirements.txt sudo pip3 install -r install/requirements-tests.txt sudo pip3 install pytest-cov flake8 From fbc16f4d7b48f5aed0c4c1973da8827d9b9d2450 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 16:57:59 +1100 Subject: [PATCH 121/142] buster is a tag --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4ad43577..2585995a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ jobs: docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` - - image: debian/buster + - image: debian:buster working_directory: ~/repo From e4e42849d6746ed5aad91c491e808ba961d0531a Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 16:59:49 +1100 Subject: [PATCH 122/142] see if we can avoid sudo --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2585995a..14a4a8c7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,10 +18,10 @@ jobs: - run: name: install dependencies command: | - sudo apt-get update && sudo apt-get install python3-pyqt5 python3-pip - sudo pip3 install -r install/requirements.txt - sudo pip3 install -r install/requirements-tests.txt - sudo pip3 install pytest-cov flake8 + apt-get update && apt-get install python3-pyqt5 python3-pip + pip3 install -r install/requirements.txt + pip3 install -r install/requirements-tests.txt + pip3 install pytest-cov flake8 # run tests! - run: From 6afe7354c96e4b862b375ecb5369cfc9e99b1e74 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:00:46 +1100 Subject: [PATCH 123/142] avoid prompt --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 14a4a8c7..e6974459 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: - run: name: install dependencies command: | - apt-get update && apt-get install python3-pyqt5 python3-pip + apt-get update && apt-get install -y python3-pyqt5 python3-pip pip3 install -r install/requirements.txt pip3 install -r install/requirements-tests.txt pip3 install pytest-cov flake8 From 4b6b7f68fb99144bb61e41e5fd4bdf3a1c170496 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:01:33 +1100 Subject: [PATCH 124/142] xvfb should be installed --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e6974459..5c05cf13 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: - run: name: install dependencies command: | - apt-get update && apt-get install -y python3-pyqt5 python3-pip + apt-get update && apt-get install -y python3-pyqt5 python3-pip xvfb pip3 install -r install/requirements.txt pip3 install -r install/requirements-tests.txt pip3 install pytest-cov flake8 From 9d986e41e1b4539597cd973a03d5db6fa2e6dc0c Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:11:39 +1100 Subject: [PATCH 125/142] don't install main requirements.txt --- .circleci/config.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5c05cf13..1a985254 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,7 +19,6 @@ jobs: name: install dependencies command: | apt-get update && apt-get install -y python3-pyqt5 python3-pip xvfb - pip3 install -r install/requirements.txt pip3 install -r install/requirements-tests.txt pip3 install pytest-cov flake8 From 8095f0c9f888916baf929f53bdd310bba29aea52 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:15:00 +1100 Subject: [PATCH 126/142] Other dependencies --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1a985254..313016d7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: - run: name: install dependencies command: | - apt-get update && apt-get install -y python3-pyqt5 python3-pip xvfb + apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python-nautilus xvfb pip3 install -r install/requirements-tests.txt pip3 install pytest-cov flake8 From 45edb9b991e1e0c9f8d20460268b25325b10a872 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:17:57 +1100 Subject: [PATCH 127/142] Add the other python dependencies from the BUILD.md --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 313016d7..1ad43878 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: - run: name: install dependencies command: | - apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python-nautilus xvfb + apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb pip3 install -r install/requirements-tests.txt pip3 install pytest-cov flake8 From 59312bddbc72d1d39629d058eea2b756070c24cf Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:34:34 +1100 Subject: [PATCH 128/142] Back to python container --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1ad43878..46d1ab08 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ jobs: docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` - - image: debian:buster + - image: circleci/python:3.6.6 working_directory: ~/repo @@ -18,7 +18,7 @@ jobs: - run: name: install dependencies command: | - apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb + apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy pip3 install -r install/requirements-tests.txt pip3 install pytest-cov flake8 From fc7dd52c62dfcfb3478fcfcfde6ff99bbe71d9a7 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:35:30 +1100 Subject: [PATCH 129/142] Back to sudo --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 46d1ab08..c90a85be 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,9 +18,9 @@ jobs: - run: name: install dependencies command: | - apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy - pip3 install -r install/requirements-tests.txt - pip3 install pytest-cov flake8 + sudo apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy + sudo pip3 install -r install/requirements-tests.txt + sudo pip3 install pytest-cov flake8 # run tests! - run: From 5d4dc1b4f5a2fdc48951867c85ee7c1337cdf2b0 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:36:12 +1100 Subject: [PATCH 130/142] more sudo --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c90a85be..c2af3b1e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: - run: name: install dependencies command: | - sudo apt-get update && apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy + sudo apt-get update && sudo apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy sudo pip3 install -r install/requirements-tests.txt sudo pip3 install pytest-cov flake8 From be71b23399d5739f62742e681175fce4739b36b7 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:38:15 +1100 Subject: [PATCH 131/142] back to installing main requirements.txt --- .circleci/config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c2af3b1e..b8758353 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,12 +19,13 @@ jobs: name: install dependencies command: | sudo apt-get update && sudo apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy + sudo pip3 install -r install/requirements.txt sudo pip3 install -r install/requirements-tests.txt sudo pip3 install pytest-cov flake8 # run tests! - run: - name: run flask tests + name: run flake tests command: | # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics From 23b2f93f83c86012c5054d5179a2384769572af9 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:42:27 +1100 Subject: [PATCH 132/142] Tweak travis yml to run the same commands as circle just for curiosity --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ec7ba912..2ae3f704 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,10 +8,10 @@ python: - "nightly" # command to install dependencies install: - - sudo apt-get update && sudo apt-get install python3-pyqt5 - - pip install -r install/requirements.txt - - pip install -r install/requirements-tests.txt - - pip install pytest-cov flake8 + - sudo apt-get update && sudo apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy + - sudo pip3 install -r install/requirements.txt + - sudo pip3 install -r install/requirements-tests.txt + - sudo pip3 install pytest-cov flake8 before_script: # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics From 351f3f0d82ba2d746bb922f273cd298f7464ee76 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:42:57 +1100 Subject: [PATCH 133/142] Revert "Travis and CircleCI hate this simple test" This reverts commit 0e95749e33a3d26731552798cbd70f1c810fa969. --- ...al_onionshare_open_settings_dialog_test.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/local_onionshare_open_settings_dialog_test.py diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py new file mode 100644 index 00000000..61e66be2 --- /dev/null +++ b/tests/local_onionshare_open_settings_dialog_test.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +import unittest +from PyQt5 import QtCore, QtTest + +from .GuiShareTest import GuiShareTest + +class LocalOpenSettingsDialogTest(unittest.TestCase, GuiShareTest): + @classmethod + def setUpClass(cls): + test_settings = { + } + cls.gui = GuiShareTest.set_up(test_settings) + + @classmethod + def tearDownClass(cls): + GuiShareTest.tear_down() + + def test_gui(self): + self.run_all_common_setup_tests() + self.run_all_share_mode_setup_tests() + # Make sure we can open the settings dialog via the settings button + QtCore.QTimer.singleShot(1000, self.accept_dialog) + QtTest.QTest.mouseClick(self.gui.settings_button, QtCore.Qt.LeftButton) + +if __name__ == "__main__": + unittest.main() From a63f6bc019f530b7e4cdf0df3d7c99ab14243cc6 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:55:11 +1100 Subject: [PATCH 134/142] Remove problematic test again --- ...al_onionshare_open_settings_dialog_test.py | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 tests/local_onionshare_open_settings_dialog_test.py diff --git a/tests/local_onionshare_open_settings_dialog_test.py b/tests/local_onionshare_open_settings_dialog_test.py deleted file mode 100644 index 61e66be2..00000000 --- a/tests/local_onionshare_open_settings_dialog_test.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -import unittest -from PyQt5 import QtCore, QtTest - -from .GuiShareTest import GuiShareTest - -class LocalOpenSettingsDialogTest(unittest.TestCase, GuiShareTest): - @classmethod - def setUpClass(cls): - test_settings = { - } - cls.gui = GuiShareTest.set_up(test_settings) - - @classmethod - def tearDownClass(cls): - GuiShareTest.tear_down() - - def test_gui(self): - self.run_all_common_setup_tests() - self.run_all_share_mode_setup_tests() - # Make sure we can open the settings dialog via the settings button - QtCore.QTimer.singleShot(1000, self.accept_dialog) - QtTest.QTest.mouseClick(self.gui.settings_button, QtCore.Qt.LeftButton) - -if __name__ == "__main__": - unittest.main() From a19a4bc6cf8602794a7631304e5e77fc8e728443 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Thu, 18 Oct 2018 17:55:26 +1100 Subject: [PATCH 135/142] Revert "Tweak travis yml to run the same commands as circle just for curiosity" This reverts commit 23b2f93f83c86012c5054d5179a2384769572af9. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2ae3f704..ec7ba912 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,10 +8,10 @@ python: - "nightly" # command to install dependencies install: - - sudo apt-get update && sudo apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy - - sudo pip3 install -r install/requirements.txt - - sudo pip3 install -r install/requirements-tests.txt - - sudo pip3 install pytest-cov flake8 + - sudo apt-get update && sudo apt-get install python3-pyqt5 + - pip install -r install/requirements.txt + - pip install -r install/requirements-tests.txt + - pip install pytest-cov flake8 before_script: # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics From 6ee47cec6ff721a7f9c258f8d879ff2f2f563f3e Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 25 Oct 2018 11:01:09 -0700 Subject: [PATCH 136/142] Delete obsolete dev_scripts/run_all_tests.sh script, and add xvfb-run info to the build instructions --- BUILD.md | 6 ++++++ dev_scripts/run_all_tests.sh | 14 -------------- 2 files changed, 6 insertions(+), 14 deletions(-) delete mode 100755 dev_scripts/run_all_tests.sh diff --git a/BUILD.md b/BUILD.md index b92f4110..2a055d98 100644 --- a/BUILD.md +++ b/BUILD.md @@ -156,3 +156,9 @@ pytest --runtor tests/ ``` Keep in mind that the Tor tests take a lot longer to run than local mode, but they are also more comprehensive. + +You can also choose to wrap the tests in `xvfb-run` so that a ton of OnionShare windows don't pop up on your desktop (you may need to install the `xorg-x11-server-Xvfb` package), like this: + +```sh +xvfb-run pytest tests/ +``` diff --git a/dev_scripts/run_all_tests.sh b/dev_scripts/run_all_tests.sh deleted file mode 100755 index 90ef1dc0..00000000 --- a/dev_scripts/run_all_tests.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -ROOT="$( dirname $(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd ))" - -# CLI tests -cd $ROOT -pytest tests/ - -# Local GUI tests -cd $ROOT/tests_gui_local -./run_unit_tests.sh - -# Tor GUI tests -cd $ROOT/tests_gui_tor -./run_unit_tests.sh From 1b8821fc385c9ba4978776839125f413e2448f1f Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 25 Oct 2018 13:16:30 -0700 Subject: [PATCH 137/142] Remove .travis.yml because we're switching to CircleCI --- .travis.yml | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ec7ba912..00000000 --- a/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: python -dist: trusty -sudo: required -python: - - "3.6" - - "3.6-dev" - - "3.7-dev" - - "nightly" -# command to install dependencies -install: - - sudo apt-get update && sudo apt-get install python3-pyqt5 - - pip install -r install/requirements.txt - - pip install -r install/requirements-tests.txt - - pip install pytest-cov flake8 -before_script: - # stop the build if there are Python syntax errors or undefined names - - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics -# run CLI tests and local GUI tests -script: - - xvfb-run pytest --cov=onionshare --cov=onionshare_gui -vvv tests/ From 6067e60349b90c7f3716b5c1c5063b3e27b1dbf7 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 25 Oct 2018 13:20:46 -0700 Subject: [PATCH 138/142] Update CI build status image in readme to use CircleCI instead of Travis --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55487045..052aaf59 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # OnionShare -[![Build Status](https://travis-ci.org/micahflee/onionshare.png)](https://travis-ci.org/micahflee/onionshare) +[![CircleCI](https://circleci.com/gh/micahflee/onionshare.svg?style=svg)](https://circleci.com/gh/micahflee/onionshare) [OnionShare](https://onionshare.org) lets you securely and anonymously share files of any size. It works by starting a web server, making it accessible as a Tor Onion Service, and generating an unguessable URL to access and download the files. It does _not_ require setting up a separate server or using a third party file-sharing service. You host the files on your own computer and use a Tor Onion Service to make it temporarily accessible over the internet. The receiving user just needs to open the URL in Tor Browser to download the file. From 2c45f6851e032f60d109ef3b3d368a5f0050b476 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 25 Oct 2018 21:13:16 -0700 Subject: [PATCH 139/142] Receive mode puts files in a directory based on the timestamp of the upload --- onionshare/__init__.py | 2 +- onionshare/common.py | 27 --------------------------- onionshare/web/receive_mode.py | 27 ++++++++++++++------------- onionshare/web/web.py | 1 - onionshare_gui/onionshare_gui.py | 5 +---- share/locale/en.json | 1 - 6 files changed, 16 insertions(+), 47 deletions(-) diff --git a/onionshare/__init__.py b/onionshare/__init__.py index 069559c5..1e81333e 100644 --- a/onionshare/__init__.py +++ b/onionshare/__init__.py @@ -21,7 +21,7 @@ along with this program. If not, see . import os, sys, time, argparse, threading from . import strings -from .common import Common, DownloadsDirErrorCannotCreate, DownloadsDirErrorNotWritable +from .common import Common from .web import Web from .onion import * from .onionshare import OnionShare diff --git a/onionshare/common.py b/onionshare/common.py index cab1e747..ffa6529f 100644 --- a/onionshare/common.py +++ b/onionshare/common.py @@ -32,20 +32,6 @@ import time from .settings import Settings -class DownloadsDirErrorCannotCreate(Exception): - """ - Error creating the downloads dir (~/OnionShare by default). - """ - pass - - -class DownloadsDirErrorNotWritable(Exception): - """ - Downloads dir is not writable. - """ - pass - - class Common(object): """ The Common object is shared amongst all parts of OnionShare. @@ -390,19 +376,6 @@ class Common(object): }""" } - def validate_downloads_dir(self): - """ - Validate that downloads_dir exists, and create it if it doesn't - """ - if not os.path.isdir(self.settings.get('downloads_dir')): - try: - os.mkdir(self.settings.get('downloads_dir'), 0o700) - except: - raise DownloadsDirErrorCannotCreate - - if not os.access(self.settings.get('downloads_dir'), os.W_OK): - raise DownloadsDirErrorNotWritable - @staticmethod def random_string(num_bytes, output_len=None): """ diff --git a/onionshare/web/receive_mode.py b/onionshare/web/receive_mode.py index 4a6934a1..66e00240 100644 --- a/onionshare/web/receive_mode.py +++ b/onionshare/web/receive_mode.py @@ -4,7 +4,6 @@ from datetime import datetime from flask import Request, request, render_template, make_response, flash, redirect from werkzeug.utils import secure_filename -from ..common import DownloadsDirErrorCannotCreate, DownloadsDirErrorNotWritable from .. import strings @@ -59,17 +58,19 @@ class ReceiveModeWeb(object): """ Upload files. """ - # Make sure downloads_dir exists + # Make sure the receive mode dir exists + now = datetime.now() + date_dir = now.strftime("%Y-%m-%d") + time_dir = now.strftime("%H.%M:%S") + receive_mode_dir = os.path.join(self.common.settings.get('downloads_dir'), date_dir, time_dir) valid = True try: - self.common.validate_downloads_dir() - except DownloadsDirErrorCannotCreate: - self.web.add_request(self.web.REQUEST_ERROR_DOWNLOADS_DIR_CANNOT_CREATE, request.path) - print(strings._('error_cannot_create_downloads_dir').format(self.common.settings.get('downloads_dir'))) - valid = False - except DownloadsDirErrorNotWritable: - self.web.add_request(self.web.REQUEST_ERROR_DOWNLOADS_DIR_NOT_WRITABLE, request.path) - print(strings._('error_downloads_dir_not_writable').format(self.common.settings.get('downloads_dir'))) + os.makedirs(receive_mode_dir, 0o700) + except PermissionError: + self.web.add_request(self.web.REQUEST_ERROR_DOWNLOADS_DIR_CANNOT_CREATE, request.path, { + "receive_mode_dir": receive_mode_dir + }) + print(strings._('error_cannot_create_downloads_dir').format(receive_mode_dir)) valid = False if not valid: flash('Error uploading, please inform the OnionShare user', 'error') @@ -86,7 +87,7 @@ class ReceiveModeWeb(object): # Automatically rename the file, if a file of the same name already exists filename = secure_filename(f.filename) filenames.append(filename) - local_path = os.path.join(self.common.settings.get('downloads_dir'), filename) + local_path = os.path.join(receive_mode_dir, filename) if os.path.exists(local_path): if '.' in filename: # Add "-i", e.g. change "foo.txt" to "foo-2.txt" @@ -98,7 +99,7 @@ class ReceiveModeWeb(object): valid = False while not valid: new_filename = '{}-{}.{}'.format('.'.join(name), i, ext) - local_path = os.path.join(self.common.settings.get('downloads_dir'), new_filename) + local_path = os.path.join(receive_mode_dir, new_filename) if os.path.exists(local_path): i += 1 else: @@ -109,7 +110,7 @@ class ReceiveModeWeb(object): valid = False while not valid: new_filename = '{}-{}'.format(filename, i) - local_path = os.path.join(self.common.settings.get('downloads_dir'), new_filename) + local_path = os.path.join(receive_mode_dir, new_filename) if os.path.exists(local_path): i += 1 else: diff --git a/onionshare/web/web.py b/onionshare/web/web.py index 52c4da16..2ae011b7 100644 --- a/onionshare/web/web.py +++ b/onionshare/web/web.py @@ -39,7 +39,6 @@ class Web(object): REQUEST_UPLOAD_FILE_RENAMED = 7 REQUEST_UPLOAD_FINISHED = 8 REQUEST_ERROR_DOWNLOADS_DIR_CANNOT_CREATE = 9 - REQUEST_ERROR_DOWNLOADS_DIR_NOT_WRITABLE = 10 def __init__(self, common, is_gui, mode='share'): self.common = common diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 8c8e4e73..1e254f61 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -394,10 +394,7 @@ class OnionShareGui(QtWidgets.QMainWindow): mode.handle_request_upload_finished(event) if event["type"] == Web.REQUEST_ERROR_DOWNLOADS_DIR_CANNOT_CREATE: - Alert(self.common, strings._('error_cannot_create_downloads_dir').format(self.common.settings.get('downloads_dir'))) - - if event["type"] == Web.REQUEST_ERROR_DOWNLOADS_DIR_NOT_WRITABLE: - Alert(self.common, strings._('error_downloads_dir_not_writable').format(self.common.settings.get('downloads_dir'))) + Alert(self.common, strings._('error_cannot_create_downloads_dir').format(event["data"]["receive_mode_dir"])) if event["type"] == Web.REQUEST_OTHER: if event["path"] != '/favicon.ico' and event["path"] != "/{}/shutdown".format(mode.web.shutdown_slug): diff --git a/share/locale/en.json b/share/locale/en.json index db416c9b..d57ef3f3 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -155,7 +155,6 @@ "info_in_progress_uploads_tooltip": "{} upload(s) in progress", "info_completed_uploads_tooltip": "{} upload(s) completed", "error_cannot_create_downloads_dir": "Could not create receive mode folder: {}", - "error_downloads_dir_not_writable": "The receive mode folder is write protected: {}", "receive_mode_downloads_dir": "Files sent to you appear in this folder: {}", "receive_mode_warning": "Warning: Receive mode lets people upload files to your computer. Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing.", "gui_receive_mode_warning": "Receive mode lets people upload files to your computer.

Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing.", From 0bab7be4444936d4d025cc2cdafa24cacd50137e Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 25 Oct 2018 21:38:20 -0700 Subject: [PATCH 140/142] Communicate the receive mode dir to the GUI, so clicking the open folder button opens the file manager to the correct directory --- onionshare/web/receive_mode.py | 7 +++++++ onionshare/web/web.py | 5 +++-- onionshare_gui/mode/__init__.py | 6 ++++++ onionshare_gui/mode/history.py | 13 ++++++++++++- onionshare_gui/mode/receive_mode/__init__.py | 10 ++++++++++ onionshare_gui/onionshare_gui.py | 3 +++ onionshare_gui/receive_mode/uploads.py | 12 +++++++++++- 7 files changed, 52 insertions(+), 4 deletions(-) diff --git a/onionshare/web/receive_mode.py b/onionshare/web/receive_mode.py index 66e00240..edaf8bbc 100644 --- a/onionshare/web/receive_mode.py +++ b/onionshare/web/receive_mode.py @@ -125,6 +125,13 @@ class ReceiveModeWeb(object): 'new_filename': basename }) + # Tell the GUI the receive mode directory for this file + self.web.add_request(self.web.REQUEST_UPLOAD_SET_DIR, request.path, { + 'id': request.upload_id, + 'filename': basename, + 'dir': receive_mode_dir + }) + self.common.log('ReceiveModeWeb', 'define_routes', '/upload, uploaded {}, saving to {}'.format(f.filename, local_path)) print(strings._('receive_mode_received_file').format(local_path)) f.save(local_path) diff --git a/onionshare/web/web.py b/onionshare/web/web.py index 2ae011b7..a423b2e1 100644 --- a/onionshare/web/web.py +++ b/onionshare/web/web.py @@ -37,8 +37,9 @@ class Web(object): REQUEST_RATE_LIMIT = 5 REQUEST_CLOSE_SERVER = 6 REQUEST_UPLOAD_FILE_RENAMED = 7 - REQUEST_UPLOAD_FINISHED = 8 - REQUEST_ERROR_DOWNLOADS_DIR_CANNOT_CREATE = 9 + REQUEST_UPLOAD_SET_DIR = 8 + REQUEST_UPLOAD_FINISHED = 9 + REQUEST_ERROR_DOWNLOADS_DIR_CANNOT_CREATE = 10 def __init__(self, common, is_gui, mode='share'): self.common = common diff --git a/onionshare_gui/mode/__init__.py b/onionshare_gui/mode/__init__.py index 0971ff32..5110289f 100644 --- a/onionshare_gui/mode/__init__.py +++ b/onionshare_gui/mode/__init__.py @@ -324,6 +324,12 @@ class Mode(QtWidgets.QWidget): """ pass + def handle_request_upload_set_dir(self, event): + """ + Handle REQUEST_UPLOAD_SET_DIR event. + """ + pass + def handle_request_upload_finished(self, event): """ Handle REQUEST_UPLOAD_FINISHED event. diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index b446b9fb..38e0fed3 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -118,6 +118,7 @@ class UploadHistoryItemFile(QtWidgets.QWidget): self.common.log('UploadHistoryItemFile', '__init__', 'filename: {}'.format(filename)) self.filename = filename + self.dir = None self.started = datetime.now() # Filename label @@ -158,13 +159,20 @@ class UploadHistoryItemFile(QtWidgets.QWidget): self.filename = new_filename self.filename_label.setText(self.filename) + def set_dir(self, dir): + self.dir = dir + def open_folder(self): """ Open the downloads folder, with the file selected, in a cross-platform manner """ self.common.log('UploadHistoryItemFile', 'open_folder') - abs_filename = os.path.join(self.common.settings.get('downloads_dir'), self.filename) + if not self.dir: + self.common.log('UploadHistoryItemFile', 'open_folder', "dir has not been set yet, can't open folder") + return + + abs_filename = os.path.join(self.dir, self.filename) # Linux if self.common.platform == 'Linux' or self.common.platform == 'BSD': @@ -266,6 +274,9 @@ class UploadHistoryItem(HistoryItem): self.files[data['old_filename']].rename(data['new_filename']) self.files[data['new_filename']] = self.files.pop(data['old_filename']) + elif data['action'] == 'set_dir': + self.files[data['filename']].set_dir(data['dir']) + elif data['action'] == 'finished': # Hide the progress bar self.progress_bar.hide() diff --git a/onionshare_gui/mode/receive_mode/__init__.py b/onionshare_gui/mode/receive_mode/__init__.py index f070f963..d6c0c351 100644 --- a/onionshare_gui/mode/receive_mode/__init__.py +++ b/onionshare_gui/mode/receive_mode/__init__.py @@ -168,6 +168,16 @@ class ReceiveMode(Mode): 'new_filename': event["data"]["new_filename"] }) + def handle_request_upload_set_dir(self, event): + """ + Handle REQUEST_UPLOAD_SET_DIR event. + """ + self.history.update(event["data"]["id"], { + 'action': 'set_dir', + 'filename': event["data"]["filename"], + 'dir': event["data"]["dir"] + }) + def handle_request_upload_finished(self, event): """ Handle REQUEST_UPLOAD_FINISHED event. diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 1e254f61..eab3261e 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -390,6 +390,9 @@ class OnionShareGui(QtWidgets.QMainWindow): elif event["type"] == Web.REQUEST_UPLOAD_FILE_RENAMED: mode.handle_request_upload_file_renamed(event) + elif event["type"] == Web.REQUEST_UPLOAD_SET_DIR: + mode.handle_request_upload_set_dir(event) + elif event["type"] == Web.REQUEST_UPLOAD_FINISHED: mode.handle_request_upload_finished(event) diff --git a/onionshare_gui/receive_mode/uploads.py b/onionshare_gui/receive_mode/uploads.py index 33d993b3..68c94b1c 100644 --- a/onionshare_gui/receive_mode/uploads.py +++ b/onionshare_gui/receive_mode/uploads.py @@ -35,6 +35,7 @@ class File(QtWidgets.QWidget): self.common.log('File', '__init__', 'filename: {}'.format(filename)) self.filename = filename + self.dir = None self.started = datetime.now() # Filename label @@ -71,6 +72,9 @@ class File(QtWidgets.QWidget): if complete: self.folder_button.show() + def set_dir(self, dir): + self.dir = dir + def rename(self, new_filename): self.filename = new_filename self.filename_label.setText(self.filename) @@ -81,7 +85,10 @@ class File(QtWidgets.QWidget): """ self.common.log('File', 'open_folder') - abs_filename = os.path.join(self.common.settings.get('downloads_dir'), self.filename) + if not self.dir: + return + + abs_filename = os.path.join(self.dir, self.filename) # Linux if self.common.platform == 'Linux' or self.common.platform == 'BSD': @@ -182,6 +189,9 @@ class Upload(QtWidgets.QWidget): self.files[old_filename].rename(new_filename) self.files[new_filename] = self.files.pop(old_filename) + def set_dir(self, filename, dir): + self.files[filename].set_dir(dir) + def finished(self): # Hide the progress bar self.progress_bar.hide() From a8dae82ac3d903d1d23dc4c3109c88b816513ab6 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 26 Oct 2018 15:08:55 -0700 Subject: [PATCH 141/142] Fix tests so they recognize the new receive mode location --- onionshare/web/receive_mode.py | 2 +- tests/GuiReceiveTest.py | 31 +++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/onionshare/web/receive_mode.py b/onionshare/web/receive_mode.py index edaf8bbc..3149029f 100644 --- a/onionshare/web/receive_mode.py +++ b/onionshare/web/receive_mode.py @@ -61,7 +61,7 @@ class ReceiveModeWeb(object): # Make sure the receive mode dir exists now = datetime.now() date_dir = now.strftime("%Y-%m-%d") - time_dir = now.strftime("%H.%M:%S") + time_dir = now.strftime("%H.%M.%S") receive_mode_dir = os.path.join(self.common.settings.get('downloads_dir'), date_dir, time_dir) valid = True try: diff --git a/tests/GuiReceiveTest.py b/tests/GuiReceiveTest.py index a659a79f..eaed8343 100644 --- a/tests/GuiReceiveTest.py +++ b/tests/GuiReceiveTest.py @@ -1,10 +1,11 @@ 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_file): + def upload_file(self, public_mode, file_to_upload, expected_basename): '''Test that we can upload the file''' files = {'file[]': open(file_to_upload, 'rb')} if not public_mode: @@ -13,9 +14,23 @@ class GuiReceiveTest(GuiBaseTest): path = 'http://127.0.0.1:{}/upload'.format(self.gui.app.port) response = requests.post(path, files=files) QtTest.QTest.qWait(2000) - self.assertTrue(os.path.isfile(expected_file)) - def upload_file_should_fail(self, public_mode, expected_file): + # Make sure the file is within the last 10 seconds worth of filenames + exists = False + now = datetime.now() + for i in range(10): + date_dir = now.strftime("%Y-%m-%d") + time_dir = now.strftime("%H.%M.%S") + receive_mode_dir = os.path.join(self.gui.common.settings.get('downloads_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')} if not public_mode: @@ -73,14 +88,14 @@ class GuiReceiveTest(GuiBaseTest): self.run_all_receive_mode_setup_tests(public_mode) if not public_mode: self.try_public_paths_in_non_public_mode() - self.upload_file(public_mode, '/tmp/test.txt', '/tmp/OnionShare/test.txt') + 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', '/tmp/OnionShare/test-2.txt') + 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', '/tmp/OnionShare/test') + 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', '/tmp/OnionShare/test-2') + self.upload_file(public_mode, '/tmp/testdir/test', 'test') 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) @@ -94,7 +109,7 @@ class GuiReceiveTest(GuiBaseTest): '''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, '/tmp/OnionShare/test.txt') + 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) From 05aeaf02cb6c076008b37016edc6f7937b467352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Mon, 12 Nov 2018 01:35:18 +0100 Subject: [PATCH 142/142] Spelling: Recipient --- share/locale/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/locale/en.json b/share/locale/en.json index d57ef3f3..b02e522f 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -62,7 +62,7 @@ "gui_receive_quit_warning": "You're in the process of receiving files. Are you sure you want to quit OnionShare?", "gui_quit_warning_quit": "Quit", "gui_quit_warning_dont_quit": "Cancel", - "error_rate_limit": "Someone has made too many wrong attempts on your address, which means they could be trying to guess it, so OnionShare has stopped the server. Start sharing again and send the receipient a new address to share.", + "error_rate_limit": "Someone has made too many wrong attempts on your address, which means they could be trying to guess it, so OnionShare has stopped the server. Start sharing again and send the recipient a new address to share.", "zip_progress_bar_format": "Compressing: %p%", "error_stealth_not_supported": "To use client authorization, you need at least both Tor 0.2.9.1-alpha (or Tor Browser 6.5) and python3-stem 1.5.0.", "error_ephemeral_not_supported": "OnionShare requires at least both Tor 0.2.7.1 and python3-stem 1.4.0.",