def test_invalid_credentials(manager_factory): """Opening a document without being authenticated is not allowed.""" manager, engine = manager_factory() doc_uid = "0000" Translator(find_resource("i18n"), "en") def has_invalid_credentials(self) -> bool: return True def error_signal() -> None: nonlocal received received = True with manager: direct_edit = manager.direct_edit received = False engine.invalidAuthentication.connect(error_signal) with patch.object(Engine, "has_invalid_credentials", new=has_invalid_credentials): direct_edit._prepare_edit(engine.server_url, doc_uid) assert received
def check_executable_path_error_qt(path: Path, /) -> None: """Display an error using Qt about the app not running from the right path.""" from nxdrive.qt import constants as qt from nxdrive.qt.imports import QApplication, QMessageBox, QPixmap from nxdrive.translator import Translator from nxdrive.utils import find_icon, find_resource app = QApplication([]) app.setQuitOnLastWindowClosed(True) Translator(find_resource("i18n")) content = Translator.get("RUNNING_FROM_WRONG_PATH", values=[str(path), f"{APP_NAME}.app"]) icon = QPixmap(str(find_icon("app_icon.svg"))) msg = QMessageBox() msg.setIconPixmap(icon) msg.setText(content) msg.setWindowTitle(APP_NAME) msg.addButton(Translator.get("QUIT"), qt.AcceptRole) msg.exec_()
def fatal_error_qt(exc_formatted: str) -> None: """Display a "friendly" dialog box on fatal error using Qt.""" from PyQt5.QtCore import Qt, QUrl from PyQt5.QtGui import QDesktopServices, QIcon from PyQt5.QtWidgets import ( QApplication, QDialog, QDialogButtonBox, QLabel, QTextEdit, QVBoxLayout, ) from nxdrive.translator import Translator from nxdrive.utils import find_icon, find_resource def section(header: str, content: str) -> str: """Format a "section" of information.""" return f"{header}\n```\n{content.strip()}\n```" Translator(find_resource("i18n")) tr = Translator.get app = QApplication([]) app.setQuitOnLastWindowClosed(True) dialog = QDialog() dialog.setWindowTitle(tr("FATAL_ERROR_TITLE", [APP_NAME])) dialog.setWindowIcon(QIcon(str(find_icon("app_icon.svg")))) dialog.resize(800, 600) layout = QVBoxLayout() css = "font-family: monospace; font-size: 12px;" details = [] # Display a little message to apologize info = QLabel(tr("FATAL_ERROR_MSG", [APP_NAME, COMPANY])) info.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) layout.addWidget(info) # Display CLI arguments if sys.argv[1:]: text = tr("FATAL_ERROR_CLI_ARGS") label_cli = QLabel(text) label_cli.setAlignment(Qt.AlignVCenter) cli_args = QTextEdit() cli_args.setStyleSheet(css) cli_args.setReadOnly(True) args = "\n".join(arg for arg in sys.argv[1:]) details.append(section(text, args)) cli_args.setText(args) cli_args.setSizeAdjustPolicy(QTextEdit.AdjustToContents) layout.addWidget(label_cli) layout.addWidget(cli_args) # Display the exception text = tr("FATAL_ERROR_EXCEPTION") label_exc = QLabel(text) label_exc.setAlignment(Qt.AlignVCenter) exception = QTextEdit() exception.setStyleSheet(css) exception.setReadOnly(True) details.append(section(text, exc_formatted)) exception.setText(exc_formatted) layout.addWidget(label_exc) layout.addWidget(exception) # Display last lines from the memory log with suppress(Exception): from nxdrive.report import Report # Last 20th lines raw_lines = Report.export_logs(-20) lines = b"\n".join(raw_lines).decode(errors="replace") if lines: text = tr("FATAL_ERROR_LOGS") label_log = QLabel(text) details.append(section(text, lines)) label_log.setAlignment(Qt.AlignVCenter) layout.addWidget(label_log) logs = QTextEdit() logs.setStyleSheet(css) logs.setReadOnly(True) logs.setLineWrapColumnOrWidth(4096) logs.setLineWrapMode(QTextEdit.FixedPixelWidth) logs.setText(lines) layout.addWidget(logs) def open_update_site() -> None: """Open the update web site.""" with suppress(Exception): QDesktopServices.openUrl(QUrl(Options.update_site_url)) # Buttons buttons = QDialogButtonBox() buttons.setStandardButtons(QDialogButtonBox.Ok) buttons.accepted.connect(dialog.close) update_button = buttons.addButton(tr("FATAL_ERROR_UPDATE_BTN"), QDialogButtonBox.ActionRole) update_button.setToolTip(tr("FATAL_ERROR_UPDATE_TOOLTIP", [APP_NAME])) update_button.clicked.connect(open_update_site) layout.addWidget(buttons) def copy() -> None: """Copy details to the clipboard and change the text of the button. """ osi.cb_set("\n".join(details)) copy_paste.setText(tr("FATAL_ERROR_DETAILS_COPIED")) # "Copy details" button with suppress(Exception): from nxdrive.osi import AbstractOSIntegration osi = AbstractOSIntegration.get(None) copy_paste = buttons.addButton(tr("FATAL_ERROR_DETAILS_COPY"), QDialogButtonBox.ActionRole) copy_paste.clicked.connect(copy) dialog.setLayout(layout) dialog.show() app.exec_()