Ejemplo n.º 1
0
def test_translate_twice():
    """ Check that the values array is not mutated. """
    Translator(MockManager(), get_folder("i18n"))
    values = ["value"]
    first = Translator.get("TOKEN_NORMAL", values)
    second = Translator.get("TOKEN_NORMAL", values)

    assert first == second
    assert values == ["value"]
Ejemplo n.º 2
0
def test_translate_twice_different_values():
    """ Check that the values array is taken into account in the LRU cache. """
    Translator(get_folder("i18n"))
    values1 = ["value1"]
    values2 = ["value2"]
    first = Translator.get("TOKEN_NORMAL", values=values1)
    second = Translator.get("TOKEN_NORMAL", values=values2)

    assert first != second
Ejemplo n.º 3
0
def test_translate_twice():
    """ Check that the values array is not mutated. """
    Translator(get_folder("i18n"))
    values = ["value"]
    first = Translator.get("TOKEN_NORMAL", values)
    second = Translator.get("TOKEN_NORMAL", values)

    assert first == second
    assert values == ["value"]
Ejemplo n.º 4
0
def test_load_existing_language():
    Translator(MockManager(), get_folder("i18n"), "fr")

    # Should not fallback on en
    assert Translator.locale() == "fr"

    # Test the key fallback
    assert Translator.get("FALLBACK") == "Fallback"
    assert Translator.get("LANGUAGE") == "Fran\xe7ais"
    assert Translator.get("BOUZOUF") == "BOUZOUF"
Ejemplo n.º 5
0
def test_load_existing_language():
    Translator(get_folder("i18n"), "fr")

    # Should not fallback on en
    assert Translator.locale() == "fr"

    # Test the key fallback
    assert Translator.get("FALLBACK") == "Fallback"
    assert Translator.get("LANGUAGE") == "Fran\xe7ais"
    assert Translator.get("BOUZOUF") == "BOUZOUF"
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
def test_languages():
    """Check that all languages are well retrieved."""
    folder = Path(__file__).parent.parent.parent / "nxdrive" / "data" / "i18n"
    Translator(folder)
    expected = [
        ("de", "Deutsch"),
        ("en", "English"),
        ("es", "Español"),
        ("eu", "Euskara"),
        ("fr", "Français"),
        ("id", "Bahasa Indonesia"),
        ("it", "Italiano"),
        ("ja", "日本語"),
        ("nl", "Nederlands"),
        ("pl", "Polski"),
        ("sv", "Svenska"),
    ]
    languages = Translator.languages()
    assert languages == expected
    assert len(languages) == len(list(folder.glob("*.json")))
Ejemplo n.º 8
0
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_()
Ejemplo n.º 9
0
def test_load_file():
    manager = MockManager()
    Translator(manager, get_folder("i18n"))

    # Verify the call to save
    assert manager.called
    assert Translator.locale() == "en"
    manager.called = False

    # Change to an existing language
    Translator.set("fr")
    assert manager.called
    assert Translator.locale() == "fr"

    # Test unkown key
    assert Translator.get("BOUZOUF") == "BOUZOUF"

    # Test fallback
    assert Translator.get("FALLBACK") == "Fallback"
    manager.called = False

    # Try to switch to bad language
    with pytest.raises(ValueError):
        Translator.set("abcd")
    assert Translator.locale() == "fr"

    # Nothing should be saved
    assert not manager.called

    # Go back to an existing one
    Translator.set("en")
    assert manager.called
    assert Translator.locale() == "en"
    assert Translator.get("BOUZOUF") == "BOUZOUF"

    # Change to an existing composed language
    Translator.set("de-DE")
    assert Translator.locale() == "de-DE"
    assert Translator.get("CONNECTION_REFUSED") == "Connection refused"
Ejemplo n.º 10
0
def test_token(token, result):
    options = ["First Token", "Another One"]
    Translator(get_folder("i18n"))
    assert Translator.get(token, options) == result
Ejemplo n.º 11
0
def test_load_bad_language():
    Translator(get_folder("i18n"), "zzzzzz")
    # Should fallback on en
    assert Translator.locale() == "en"
Ejemplo n.º 12
0
def test_load_file():
    Translator(get_folder("i18n"))

    # Verify the call to save
    assert Translator.locale() == "en"

    # Change to an existing language
    Translator.set("fr")
    assert Translator.locale() == "fr"

    # Test unkown key
    assert Translator.get("BOUZOUF") == "BOUZOUF"

    # Test fallback
    assert Translator.get("FALLBACK") == "Fallback"

    # Try to switch to bad language
    with pytest.raises(ValueError):
        Translator.set("abcd")
    assert Translator.locale() == "fr"

    # Go back to an existing one
    Translator.set("en")
    assert Translator.locale() == "en"
    assert Translator.get("BOUZOUF") == "BOUZOUF"

    # Change to an existing composed language
    Translator.set("de-DE")
    assert Translator.locale() == "de-DE"
    assert Translator.get("CONNECTION_REFUSED") == "Connection refused"
Ejemplo n.º 13
0
def test_non_iniialized():
    Translator._singleton = None
    with pytest.raises(RuntimeError):
        Translator.get("TEST")
Ejemplo n.º 14
0
def test_token(token, result):
    options = ["First Token", "Another One"]
    Translator(get_folder("i18n"))
    assert Translator.get(token, values=options) == result
Ejemplo n.º 15
0
def test_token(token, result):
    options = ["First Token", "Another One"]
    Translator(MockManager(), get_folder("i18n"))
    assert Translator.get(token, options) == result
Ejemplo n.º 16
0
def test_non_iniialized():
    Translator._singleton = None
    with pytest.raises(RuntimeError):
        Translator.get("TEST")
Ejemplo n.º 17
0
def test_load_bad_language():
    Translator(MockManager(), get_folder("i18n"), "zzzzzz")
    # Should fallback on en
    assert Translator.locale() == "en"
Ejemplo n.º 18
0
    def setUpApp(self, server_profile=None, register_roots=True):
        if Manager._singleton:
            Manager._singleton = None

        # Install callback early to be called the last
        self.addCleanup(self._check_cleanup)

        self.report_path = os.environ.get("REPORT_PATH")

        self.tmpdir = os.path.join(os.environ.get("WORKSPACE", ""), "tmp")
        self.addCleanup(clean_dir, self.tmpdir)
        if not os.path.isdir(self.tmpdir):
            os.makedirs(self.tmpdir)

        self.upload_tmp_dir = tempfile.mkdtemp("-nxdrive-uploads",
                                               dir=self.tmpdir)

        # Check the local filesystem test environment
        self.local_test_folder_1 = tempfile.mkdtemp("drive-1", dir=self.tmpdir)
        self.local_test_folder_2 = tempfile.mkdtemp("drive-2", dir=self.tmpdir)

        # Correct the casing of the temp folders for windows
        if WINDOWS:
            import win32api

            self.local_test_folder_1 = win32api.GetLongPathNameW(
                self.local_test_folder_1)
            self.local_test_folder_2 = win32api.GetLongPathNameW(
                self.local_test_folder_2)

        self.local_nxdrive_folder_1 = os.path.join(self.local_test_folder_1,
                                                   "Nuxeo Drive")
        os.mkdir(self.local_nxdrive_folder_1)
        self.local_nxdrive_folder_2 = os.path.join(self.local_test_folder_2,
                                                   "Nuxeo Drive")
        os.mkdir(self.local_nxdrive_folder_2)

        self.nxdrive_conf_folder_1 = os.path.join(self.local_test_folder_1,
                                                  "nuxeo-drive-conf")
        os.mkdir(self.nxdrive_conf_folder_1)
        self.nxdrive_conf_folder_2 = os.path.join(self.local_test_folder_2,
                                                  "nuxeo-drive-conf")
        os.mkdir(self.nxdrive_conf_folder_2)

        Options.delay = TEST_DEFAULT_DELAY
        Options.nxdrive_home = self.nxdrive_conf_folder_1
        self.manager_1 = Manager()
        self.connected = False
        i18n_path = self.location + "/resources/i18n"
        Translator(self.manager_1, i18n_path)
        Options.nxdrive_home = self.nxdrive_conf_folder_2
        Manager._singleton = None
        self.manager_2 = Manager()

        self.setUpServer(server_profile)
        self.addCleanup(self.tearDownServer, server_profile)
        self.addCleanup(self._stop_managers)
        self.addCleanup(self.generate_report)

        self._wait_sync = {}
        self._wait_remote_scan = {}
        self._remote_changes_count = {}
        self._no_remote_changes = {}

        # Set engine_1 and engine_2 attributes
        self.bind_engine(1, start_engine=False)
        self.queue_manager_1 = self.engine_1.get_queue_manager()
        self.bind_engine(2, start_engine=False)

        self.sync_root_folder_1 = os.path.join(self.local_nxdrive_folder_1,
                                               self.workspace_title_1)
        self.sync_root_folder_2 = os.path.join(self.local_nxdrive_folder_2,
                                               self.workspace_title_2)

        self.local_root_client_1 = self.engine_1.local

        self.local_1 = self.get_local_client(self.sync_root_folder_1)
        self.local_2 = self.get_local_client(self.sync_root_folder_2)

        # Document client to be used to create remote test documents
        # and folders
        self.remote_document_client_1 = DocRemote(
            pytest.nuxeo_url,
            self.user_1,
            "nxdrive-test-device-1",
            pytest.version,
            password=self.password_1,
            base_folder=self.workspace_1,
            upload_tmp_dir=self.upload_tmp_dir,
        )

        self.remote_document_client_2 = DocRemote(
            pytest.nuxeo_url,
            self.user_2,
            "nxdrive-test-device-2",
            pytest.version,
            password=self.password_2,
            base_folder=self.workspace_2,
            upload_tmp_dir=self.upload_tmp_dir,
        )

        # File system client to be used to create remote test documents
        # and folders
        self.remote_1 = RemoteBase(
            pytest.nuxeo_url,
            self.user_1,
            "nxdrive-test-device-1",
            pytest.version,
            password=self.password_1,
            base_folder=self.workspace_1,
            upload_tmp_dir=self.upload_tmp_dir,
        )

        self.remote_2 = RemoteBase(
            pytest.nuxeo_url,
            self.user_2,
            "nxdrive-test-device-2",
            pytest.version,
            password=self.password_2,
            base_folder=self.workspace_2,
            upload_tmp_dir=self.upload_tmp_dir,
        )

        # Register sync roots
        if register_roots:
            self.remote_1.register_as_root(self.workspace_1)
            self.addCleanup(self._unregister, self.workspace_1)
            self.remote_2.register_as_root(self.workspace_2)
            self.addCleanup(self._unregister, self.workspace_2)
Ejemplo n.º 19
0
def test_non_existing_file():
    with pytest.raises(OSError):
        Translator(MockManager(), get_folder("imagine"))
Ejemplo n.º 20
0
def test_load_file():
    Translator(get_folder("i18n"))

    # Verify the call to save
    assert Translator.locale() == "en"

    # Change to an existing language
    Translator.set("fr")
    assert Translator.locale() == "fr"

    # Test unknown key
    assert Translator.get("BOUZOUF") == "BOUZOUF"

    # Test fallback
    assert Translator.get("FALLBACK") == "Fallback"

    # Try to switch to bad language
    with pytest.raises(ValueError):
        Translator.set("abcd")
    assert Translator.locale() == "fr"

    # Go back to an existing one
    Translator.set("en")
    assert Translator.locale() == "en"
    assert Translator.get("BOUZOUF") == "BOUZOUF"

    # Change to an existing composed language
    Translator.set("de-DE")
    assert Translator.locale() == "de-DE"
    assert Translator.get("CONNECTION_REFUSED") == "Connection refused"
Ejemplo n.º 21
0
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_()
Ejemplo n.º 22
0
# resolution of some databases (MySQL...)
REMOTE_MODIFICATION_TIME_RESOLUTION = 1.0

# 1s resolution on HFS+ on OSX
# ~0.01  sec for NTFS
#  0.001 sec for EXT4FS
OS_STAT_MTIME_RESOLUTION = 1.0

log = getLogger(__name__)

DEFAULT_WAIT_SYNC_TIMEOUT = 10
FILE_CONTENT = b"Lorem ipsum dolor sit amet ..."
FAKER = Faker("en_US")
LOCATION = normalized_path(__file__).parent.parent

Translator(LOCATION / "resources" / "i18n")


def nuxeo_url() -> str:
    """Retrieve the Nuxeo URL."""
    return env.NXDRIVE_TEST_NUXEO_URL.split("#")[0]


def root_remote(base_folder: str = "/") -> DocRemote:
    return DocRemote(
        nuxeo_url(),
        env.NXDRIVE_TEST_USERNAME,
        "nxdrive-test-administrator-device",
        __version__,
        password=env.NXDRIVE_TEST_PASSWORD,
        base_folder=base_folder,