def _create_main_window(): # Pass minimize_on_close to avoid having test blocked by the # closing confirmation prompt switch_language(client_config, "en") monkeypatch.setattr( "guardata.client.gui.main_window.list_available_devices", lambda *args, **kwargs: (["a"]), ) main_w = testing_main_window_cls(qt_thread_gateway._job_scheduler, event_bus, client_config, minimize_on_close=True) qtbot.add_widget(main_w) main_w.show_window() main_w.show_top() windows.append(main_w) main_w.add_instance(start_arg) def right_main_window(): assert guardataApp.get_main_window() is main_w qtbot.wait(200) # For some reasons, the main window from the previous test might # still be around. Simply wait for things to settle down until # our freshly created window is detected as the app main window. qtbot.wait_until(right_main_window) return main_w
async def test_workspace_button_shared_with(qtbot, workspace_fs, client_config, bob, alice_user_info, bob_user_info): switch_language(client_config, "en") roles = { bob.user_id: (WorkspaceRole.READER, bob_user_info), alice_user_info.user_id: (WorkspaceRole.OWNER, alice_user_info), } w = WorkspaceButton( workspace_name="Workspace", workspace_fs=workspace_fs, users_roles=roles, is_mounted=True, files=[], ) qtbot.addWidget(w) w.show() assert w.widget_empty.isVisible() is True assert w.label_owner.isVisible() is True assert w.label_shared.isVisible() is True assert w.name == "Workspace" assert w.label_title.text().startswith("Workspace") assert w.label_title.toolTip() == "Workspace (shared with Boby McBobFace)" assert w.label_role.text() == _("TEXT_WORKSPACE_ROLE_OWNER")
def test_password_text(client_config): switch_language(client_config, "en") assert get_password_strength_text(0) == "TOO SHORT" assert get_password_strength_text(1) == "VERY WEAK" assert get_password_strength_text(2) == "WEAK" assert get_password_strength_text(3) == "AVERAGE" assert get_password_strength_text(4) == "GOOD" assert get_password_strength_text(5) == "EXCELLENT"
def test_file_table_parent_workspace(qtbot, client_config): switch_language(client_config, "en") w = FileTable(parent=None) qtbot.addWidget(w) assert w.rowCount() == 0 assert w.columnCount() == 5 w.add_parent_workspace() assert w.rowCount() == 1 assert w.item(0, 1).text() == "Workspaces list"
async def _gui_factory(event_bus=None, client_config=client_config, start_arg=None): # First start popup blocks the test # Check version and mountpoint are useless for most tests client_config = client_config.evolve( gui_check_version_at_startup=False, gui_first_launch=False, gui_last_version=guardata_version, mountpoint_enabled=True, gui_language="en", gui_show_confined=False, ) event_bus = event_bus or event_bus_factory() # Language config rely on global var, must reset it for each test ! switch_language(client_config) guardataApp.connected_devices = set() def _create_main_window(): # Pass minimize_on_close to avoid having test blocked by the # closing confirmation prompt switch_language(client_config, "en") monkeypatch.setattr( "guardata.client.gui.main_window.list_available_devices", lambda *args, **kwargs: (["a"]), ) main_w = testing_main_window_cls(qt_thread_gateway._job_scheduler, event_bus, client_config, minimize_on_close=True) qtbot.add_widget(main_w) main_w.show_window() main_w.show_top() windows.append(main_w) main_w.add_instance(start_arg) def right_main_window(): assert guardataApp.get_main_window() is main_w qtbot.wait(200) # For some reasons, the main window from the previous test might # still be around. Simply wait for things to settle down until # our freshly created window is detected as the app main window. qtbot.wait_until(right_main_window) return main_w return await qt_thread_gateway.send_action(_create_main_window)
async def test_workspace_button_delete_clicked(qtbot, workspace_fs, client_config, alice_user_info): switch_language(client_config, "en") roles = {alice_user_info.user_id: (WorkspaceRole.OWNER, alice_user_info)} w = WorkspaceButton( workspace_name="Workspace", workspace_fs=workspace_fs, users_roles=roles, is_mounted=True, files=[], ) qtbot.addWidget(w) with qtbot.waitSignal(w.delete_clicked, timeout=500) as blocker: qtbot.mouseClick(w.button_delete, QtCore.Qt.LeftButton) assert blocker.args == [workspace_fs]
async def test_workspace_button_files(qtbot, workspace_fs, client_config, alice_user_info): switch_language(client_config, "en") roles = {alice_user_info.user_id: (WorkspaceRole.OWNER, alice_user_info)} w = WorkspaceButton( workspace_name="Workspace", workspace_fs=workspace_fs, users_roles=roles, is_mounted=True, files=[], ) qtbot.addWidget(w) w.show() assert w.widget_empty.isVisible() is True assert w.label_owner.isVisible() is True assert w.label_shared.isVisible() is False assert w.name == "Workspace"
def run_gui(config: ClientConfig, start_arg: str = None, diagnose: bool = False): logger.info("Starting UI") # Needed for High DPI usage of QIcons, otherwise only QImages are well scaled QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) QApplication.setHighDpiScaleFactorRoundingPolicy( Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) app = guardataApp() app.load_stylesheet() app.load_font() lang_key = lang.switch_language(config) event_bus = EventBus() with run_trio_thread() as jobs_ctx: win = MainWindow( jobs_ctx=jobs_ctx, event_bus=event_bus, config=config, minimize_on_close=config.gui_tray_enabled and systray_available(), ) result_queue = Queue(maxsize=1) class ThreadSafeNoQtSignal(ThreadSafeQtSignal): def __init__(self): self.qobj = None self.signal_name = "" self.args_types = () def emit(self, *args): pass jobs_ctx.submit_job( ThreadSafeNoQtSignal(), ThreadSafeNoQtSignal(), _start_ipc_server, config, win, start_arg, result_queue, ) if result_queue.get() == "already_running": # Another instance of guardata already started, nothing more to do return if systray_available(): systray = Systray(parent=win) win.systray_notification.connect(systray.on_systray_notification) systray.on_close.connect(win.close_app) systray.on_show.connect(win.show_top) app.aboutToQuit.connect(before_quit(systray)) if config.gui_tray_enabled: app.setQuitOnLastWindowClosed(False) if config.gui_check_version_at_startup and not diagnose: CheckNewVersion(jobs_ctx=jobs_ctx, event_bus=event_bus, config=config, parent=win) win.show_window(skip_dialogs=diagnose, invitation_link=start_arg) win.show_top() win.new_instance_needed.emit(start_arg) def kill_window(*args): win.close_app(force=True) QApplication.quit() signal.signal(signal.SIGINT, kill_window) # QTimer wakes up the event loop periodically which allows us to close # the window even when it is in background. timer = QTimer() timer.start(1000 if diagnose else 400) timer.timeout.connect(kill_window if diagnose else lambda: None) if diagnose: diagnose_timer = QTimer() diagnose_timer.start(1000) diagnose_timer.timeout.connect(kill_window) if lang_key: event_bus.send(ClientEvent.GUI_CONFIG_CHANGED, gui_language=lang_key) if diagnose: with fail_on_first_exception(kill_window): return app.exec_() else: with log_pyqt_exceptions(): return app.exec_()
def test_file_table_sort(qtbot, client_config): switch_language(client_config, "en") w = FileTable(parent=None) qtbot.addWidget(w) w.add_parent_workspace() w.add_folder("Dir1", uuid.uuid4(), True, False) w.add_file( "File1.txt", uuid.uuid4(), 100, pendulum.datetime(2000, 1, 15), pendulum.datetime(2000, 1, 20), True, False, ) w.add_file( "AnotherFile.txt", uuid.uuid4(), 80, pendulum.datetime(2000, 1, 10), pendulum.datetime(2000, 1, 25), True, False, ) assert w.rowCount() == 4 assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "Dir1" assert w.item(2, 1).text() == "File1.txt" assert w.item(3, 1).text() == "AnotherFile.txt" # Name w.sortByColumn(1, QtCore.Qt.AscendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "AnotherFile.txt" assert w.item(2, 1).text() == "Dir1" assert w.item(3, 1).text() == "File1.txt" w.sortByColumn(1, QtCore.Qt.DescendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "File1.txt" assert w.item(2, 1).text() == "Dir1" assert w.item(3, 1).text() == "AnotherFile.txt" # Created w.sortByColumn(2, QtCore.Qt.AscendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "Dir1" assert w.item(2, 1).text() == "AnotherFile.txt" assert w.item(3, 1).text() == "File1.txt" w.sortByColumn(2, QtCore.Qt.DescendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "File1.txt" assert w.item(2, 1).text() == "AnotherFile.txt" assert w.item(3, 1).text() == "Dir1" # Updated w.sortByColumn(3, QtCore.Qt.AscendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "Dir1" assert w.item(2, 1).text() == "File1.txt" assert w.item(3, 1).text() == "AnotherFile.txt" w.sortByColumn(3, QtCore.Qt.DescendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "AnotherFile.txt" assert w.item(2, 1).text() == "File1.txt" assert w.item(3, 1).text() == "Dir1" # Size w.sortByColumn(4, QtCore.Qt.AscendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "Dir1" assert w.item(2, 1).text() == "AnotherFile.txt" assert w.item(3, 1).text() == "File1.txt" w.sortByColumn(4, QtCore.Qt.DescendingOrder) assert w.item(0, 1).text() == "Workspaces list" assert w.item(1, 1).text() == "File1.txt" assert w.item(2, 1).text() == "AnotherFile.txt" assert w.item(3, 1).text() == "Dir1"