mirror of
https://github.com/borgbase/vorta
synced 2024-12-22 15:57:34 +00:00
b015368fee
Move existing tests into subfolder `tests/unit`. Write integration tests that actually run the installed borg executable. Those tests can be found in `tests/integration`. Those pytest fixtures that are the same for both kinds of tests remain in `tests/conftest.py`. The others can be found in `tests/integration/conftest.py` or `tests/unit/conftest.py`. This adds nox to the project and configures it to run the tests with different borg versions. This also updates the ci workflow to run the integration tests using nox. * noxfile.py : Run pytest with a matrix of borg versions OR a specific borg version * Makefile : Run using nox. Add phonies `test-unit` and `test-integration`. * tests/conftest.py : Move some fixtures/functions to `tests/unit/conftest.py`. * tests/test_*.py --> tests/unit/ : Move unittests and assets into subfolder * tests/integration/ : Write integration tests. * requirements.d/dev.txt: Add `nox` and `pkgconfig`. The latter is needed for installing new borg versions. * .github/actions/setup/action.yml : Update to install pre-commit and nox when needed. The action now no longer installs Vorta. * .github/actions/install-dependencies/action.yml : Install system deps of borg with this new composite action. * .github/workflows/test.yml : Rename `test` ci to `test-unit` and update it for the new test setup. Implement `test-integration` ci. Signed-off-by: Chirag Aggarwal <thechiragaggarwal@gmail.com>
120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
import os
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from PyQt6 import QtCore
|
|
from PyQt6.QtWidgets import QDialogButtonBox, QFileDialog, QMessageBox
|
|
from vorta.store.models import BackupProfileModel, SourceFileModel
|
|
from vorta.views.import_window import ImportWindow
|
|
|
|
VALID_IMPORT_FILE = Path(__file__).parent / 'profile_exports' / 'valid.json'
|
|
|
|
|
|
def test_import_success(qapp, qtbot, rootdir, monkeypatch):
|
|
monkeypatch.setattr(QFileDialog, "getOpenFileName", lambda *args: [VALID_IMPORT_FILE])
|
|
monkeypatch.setattr(QMessageBox, 'information', lambda *args: None)
|
|
|
|
main = qapp.main_window
|
|
main.profile_import_action()
|
|
import_dialog: ImportWindow = main.window
|
|
import_dialog.overwriteExistingSettings.setChecked(True)
|
|
|
|
qtbot.mouseClick(
|
|
import_dialog.buttonBox.button(QDialogButtonBox.StandardButton.Ok), QtCore.Qt.MouseButton.LeftButton
|
|
)
|
|
qtbot.waitSignal(import_dialog.profile_imported, **pytest._wait_defaults)
|
|
|
|
restored_profile = BackupProfileModel.get_or_none(name="Test Profile Restoration")
|
|
assert restored_profile is not None
|
|
|
|
restored_repo = restored_profile.repo
|
|
assert restored_repo is not None
|
|
assert len(SourceFileModel.select().where(SourceFileModel.profile == restored_profile)) == 3
|
|
|
|
|
|
def test_import_bootstrap_success(qapp, mocker):
|
|
mocked_unlink = mocker.MagicMock()
|
|
mocker.patch.object(Path, 'unlink', mocked_unlink)
|
|
qapp.bootstrap_profile(Path(VALID_IMPORT_FILE))
|
|
|
|
assert mocked_unlink.called
|
|
|
|
restored_profile = BackupProfileModel.get_or_none(name="Test Profile Restoration")
|
|
assert restored_profile is not None
|
|
|
|
restored_repo = restored_profile.repo
|
|
assert restored_repo is not None
|
|
|
|
assert len(SourceFileModel.select().where(SourceFileModel.profile == restored_profile)) == 3
|
|
assert BackupProfileModel.select().count() == 2
|
|
|
|
|
|
def test_import_fail_not_json(qapp, rootdir, monkeypatch):
|
|
BAD_FILE = os.path.join(rootdir, 'profile_exports', 'invalid_no_json.json')
|
|
|
|
def getOpenFileName(*args, **kwargs):
|
|
return [BAD_FILE]
|
|
|
|
monkeypatch.setattr(QFileDialog, "getOpenFileName", getOpenFileName)
|
|
|
|
alert_message = None
|
|
|
|
def critical(widget, title, message):
|
|
nonlocal alert_message
|
|
alert_message = message
|
|
|
|
monkeypatch.setattr(QMessageBox, "critical", critical)
|
|
|
|
main = qapp.main_window
|
|
main.profile_import_action()
|
|
|
|
# assert somehow that an alert is shown
|
|
assert alert_message == 'This file does not contain valid JSON: Expecting value: line 1 column 1 (char 0)'
|
|
|
|
|
|
def test_export_success(qapp, qtbot, tmpdir, monkeypatch):
|
|
FILE_PATH = os.path.join(tmpdir, "testresult.json")
|
|
|
|
def getSaveFileName(*args, **kwargs):
|
|
return [FILE_PATH]
|
|
|
|
monkeypatch.setattr(QFileDialog, "getSaveFileName", getSaveFileName)
|
|
|
|
main = qapp.main_window
|
|
main.profile_export_action()
|
|
export_dialog = main.window
|
|
|
|
qtbot.mouseClick(
|
|
export_dialog.buttonBox.button(QDialogButtonBox.StandardButton.Save), QtCore.Qt.MouseButton.LeftButton
|
|
)
|
|
qtbot.waitUntil(lambda: os.path.isfile(FILE_PATH))
|
|
|
|
assert os.path.isfile(FILE_PATH)
|
|
|
|
|
|
def test_export_fail_unwritable(qapp, qtbot, tmpdir, monkeypatch):
|
|
FILE_PATH = os.path.join(os.path.abspath(os.sep), "testresult.vortabackup")
|
|
|
|
def getSaveFileName(*args, **kwargs):
|
|
return [FILE_PATH]
|
|
|
|
monkeypatch.setattr(QFileDialog, "getSaveFileName", getSaveFileName)
|
|
|
|
alert_message = None
|
|
|
|
def critical(widget, title, message):
|
|
nonlocal alert_message
|
|
alert_message = message
|
|
|
|
monkeypatch.setattr(QMessageBox, "critical", critical)
|
|
|
|
main = qapp.main_window
|
|
main.profile_export_action()
|
|
export_dialog = main.window
|
|
|
|
qtbot.mouseClick(
|
|
export_dialog.buttonBox.button(QDialogButtonBox.StandardButton.Save), QtCore.Qt.MouseButton.LeftButton
|
|
)
|
|
|
|
assert 'could not be created' in alert_message
|
|
assert not os.path.isfile(FILE_PATH)
|