mirror of https://github.com/borgbase/vorta
Refactoring: remove last exec_, add tests, retain archive deletion message. By @samuel-w (#722)
This commit is contained in:
parent
39b7f58483
commit
0b6961213f
|
@ -37,7 +37,7 @@ def main():
|
|||
app = VortaApp(sys.argv, single_app=True)
|
||||
app.updater = get_updater()
|
||||
|
||||
sys.exit(app.exec_())
|
||||
sys.exit(app.exec())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -138,4 +138,4 @@ class VortaApp(QtSingleApplication):
|
|||
msg.setText(self.tr("No Borg Binary Found"))
|
||||
msg.setInformativeText(self.tr("Vorta was unable to locate a usable Borg Backup binary."))
|
||||
msg.setStandardButtons(QMessageBox.Ok)
|
||||
msg.exec_()
|
||||
msg.exec()
|
||||
|
|
|
@ -344,14 +344,7 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
|
|||
def list_archive_result(self, result):
|
||||
self._set_status('')
|
||||
if result['returncode'] == 0:
|
||||
archive = ArchiveModel.get(name=result['params']['archive_name'])
|
||||
window = ExtractDialog(result['data'], archive)
|
||||
self._toggle_all_buttons(True)
|
||||
window.setParent(self, QtCore.Qt.Sheet)
|
||||
self._window = window # for testing
|
||||
window.show()
|
||||
|
||||
if window.exec_():
|
||||
def process_result():
|
||||
def receive():
|
||||
extraction_folder = dialog.selectedFiles()
|
||||
if extraction_folder:
|
||||
|
@ -369,6 +362,14 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
|
|||
dialog = choose_file_dialog(self, self.tr("Choose Extraction Point"), want_folder=True)
|
||||
dialog.open(receive)
|
||||
|
||||
archive = ArchiveModel.get(name=result['params']['archive_name'])
|
||||
window = ExtractDialog(result['data'], archive)
|
||||
self._toggle_all_buttons(True)
|
||||
window.setParent(self, QtCore.Qt.Sheet)
|
||||
self._window = window # for testing
|
||||
window.show()
|
||||
window.accepted.connect(process_result)
|
||||
|
||||
def extract_archive_result(self, result):
|
||||
self._toggle_all_buttons(True)
|
||||
|
||||
|
@ -412,12 +413,12 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
|
|||
self._set_status(params['message'])
|
||||
return
|
||||
|
||||
archive_name = self.selected_archive_name()
|
||||
if archive_name is not None:
|
||||
self.archive_name = self.selected_archive_name()
|
||||
if self.archive_name is not None:
|
||||
if not self.confirm_dialog(trans_late('ArchiveTab', "Confirm deletion"),
|
||||
trans_late('ArchiveTab', "Are you sure you want to delete the archive?")):
|
||||
return
|
||||
params['cmd'][-1] += f'::{archive_name}'
|
||||
params['cmd'][-1] += f'::{self.archive_name}'
|
||||
|
||||
thread = BorgDeleteThread(params['cmd'], params, parent=self.app)
|
||||
thread.updated.connect(self._set_status)
|
||||
|
@ -430,20 +431,15 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
|
|||
def delete_result(self, result):
|
||||
if result['returncode'] == 0:
|
||||
self._set_status(self.tr('Archive deleted.'))
|
||||
self.list_action()
|
||||
deleted_row = self.archiveTable.findItems(self.archive_name, QtCore.Qt.MatchExactly)[0].row()
|
||||
self.archiveTable.removeRow(deleted_row)
|
||||
ArchiveModel.get(name=self.archive_name).delete_instance()
|
||||
del self.archive_name
|
||||
else:
|
||||
self._toggle_all_buttons(True)
|
||||
|
||||
def diff_action(self):
|
||||
profile = self.profile()
|
||||
|
||||
window = DiffDialog(self.archiveTable)
|
||||
self._toggle_all_buttons(True)
|
||||
window.setParent(self, QtCore.Qt.Sheet)
|
||||
self._window = window # for testing
|
||||
window.show()
|
||||
|
||||
if window.exec_():
|
||||
def process_result():
|
||||
if window.selected_archives:
|
||||
self.selected_archives = window.selected_archives
|
||||
archive_cell_newer = self.archiveTable.item(self.selected_archives[0], 4)
|
||||
|
@ -465,6 +461,15 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
|
|||
else:
|
||||
self._set_status(params['message'])
|
||||
|
||||
profile = self.profile()
|
||||
|
||||
window = DiffDialog(self.archiveTable)
|
||||
self._toggle_all_buttons(True)
|
||||
window.setParent(self, QtCore.Qt.Sheet)
|
||||
self._window = window # for testing
|
||||
window.show()
|
||||
window.accepted.connect(process_result)
|
||||
|
||||
def list_diff_result(self, result):
|
||||
self._set_status('')
|
||||
if result['returncode'] == 0:
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import sys
|
||||
import os
|
||||
import datetime
|
||||
from collections import namedtuple
|
||||
|
||||
from PyQt5 import uic
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QApplication, QHeaderView
|
||||
from PyQt5.QtWidgets import QHeaderView
|
||||
|
||||
from vorta.utils import get_asset, get_dict_from_list, nested_dict
|
||||
from vorta.views.partials.tree_view import TreeModel
|
||||
|
@ -88,19 +85,3 @@ class ExtractTree(TreeModel):
|
|||
return Qt.NoItemFlags
|
||||
|
||||
return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
"""
|
||||
For local testing:
|
||||
|
||||
borg list --progress --info --log-json --format="{size:8d}{TAB}{mtime}{TAB}{path}{NL}"
|
||||
"""
|
||||
FakeArchive = namedtuple("Archive", ["name", "time"])
|
||||
app = QApplication(sys.argv)
|
||||
test_list = open("/Users/manu/Downloads/nyx2-list.txt").read()
|
||||
|
||||
archive = FakeArchive("test-archive", datetime.datetime.now())
|
||||
view = ExtractDialog(test_list, archive)
|
||||
view.show()
|
||||
sys.exit(app.exec_())
|
||||
|
|
|
@ -134,6 +134,7 @@ class MainWindow(MainWindowBase, MainWindowUI):
|
|||
window = EditProfileWindow(rename_existing_id=self.profileSelector.currentData())
|
||||
self.window = window # For tests
|
||||
window.setParent(self, QtCore.Qt.Sheet)
|
||||
window.open()
|
||||
window.profile_changed.connect(self.add_profile_entry)
|
||||
window.rejected.connect(lambda: self.profileSelector.setCurrentIndex(self.profileSelector.currentIndex()))
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import re
|
||||
from PyQt5 import uic
|
||||
from PyQt5 import uic, QtCore
|
||||
|
||||
from vorta.utils import get_private_keys, get_asset, choose_file_dialog, borg_compat
|
||||
from vorta.borg.init import BorgInitThread
|
||||
|
@ -12,6 +12,8 @@ AddRepoUI, AddRepoBase = uic.loadUiType(uifile)
|
|||
|
||||
|
||||
class AddRepoWindow(AddRepoBase, AddRepoUI):
|
||||
added_repo = QtCore.pyqtSignal(dict)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
@ -85,7 +87,7 @@ class AddRepoWindow(AddRepoBase, AddRepoUI):
|
|||
def run_result(self, result):
|
||||
self.saveButton.setEnabled(True)
|
||||
if result['returncode'] == 0:
|
||||
self.result = result
|
||||
self.added_repo.emit(result)
|
||||
self.accept()
|
||||
else:
|
||||
self._set_status(self.tr('Unable to add your repository.'))
|
||||
|
|
|
@ -66,7 +66,7 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
|||
|
||||
def set_repos(self):
|
||||
count = self.repoSelector.count()
|
||||
for x in range(4, count): # Repositories are listed after 4th entry in repoSelector
|
||||
for _ in range(4, count): # Repositories are listed after 4th entry in repoSelector
|
||||
self.repoSelector.removeItem(4)
|
||||
for repo in RepoModel.select():
|
||||
self.repoSelector.addItem(repo.url, repo.id)
|
||||
|
@ -113,12 +113,11 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
|||
def ssh_select_action(self, index):
|
||||
if index == 1:
|
||||
ssh_add_window = SSHAddWindow()
|
||||
self._window = ssh_add_window # For tests
|
||||
ssh_add_window.setParent(self, QtCore.Qt.Sheet)
|
||||
ssh_add_window.show()
|
||||
if ssh_add_window.exec_():
|
||||
self.init_ssh()
|
||||
else:
|
||||
self.sshComboBox.setCurrentIndex(0)
|
||||
ssh_add_window.accepted.connect(self.init_ssh)
|
||||
ssh_add_window.rejected.connect(lambda: self.sshComboBox.setCurrentIndex(0))
|
||||
else:
|
||||
profile = self.profile()
|
||||
profile.ssh_key = self.sshComboBox.itemData(index)
|
||||
|
@ -138,8 +137,8 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
|||
clipboard = QApplication.clipboard()
|
||||
clipboard.setText(pub_key)
|
||||
|
||||
msg.setText(self.tr("Public Key Copied to Clipboard"))
|
||||
msg.setInformativeText(self.tr(
|
||||
msg.setWindowTitle(self.tr("Public Key Copied to Clipboard"))
|
||||
msg.setText(self.tr(
|
||||
"The selected public SSH key was copied to the clipboard. "
|
||||
"Use it to set up remote repo permissions."))
|
||||
|
||||
|
@ -147,7 +146,7 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
|||
msg.setText(self.tr("Couldn't find public key."))
|
||||
else:
|
||||
msg.setText(self.tr("Select a public key from the dropdown first."))
|
||||
msg.exec_()
|
||||
msg.show()
|
||||
|
||||
def compression_select_action(self, index):
|
||||
profile = self.profile()
|
||||
|
@ -163,12 +162,11 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
|||
window = AddRepoWindow()
|
||||
else:
|
||||
window = ExistingRepoWindow()
|
||||
self._window = window # For tests
|
||||
window.setParent(self, QtCore.Qt.Sheet)
|
||||
window.show()
|
||||
if window.exec_():
|
||||
self.process_new_repo(window.result)
|
||||
else:
|
||||
self.repoSelector.setCurrentIndex(0)
|
||||
window.added_repo.connect(self.process_new_repo)
|
||||
window.rejected.connect(lambda: self.repoSelector.setCurrentIndex(0))
|
||||
else:
|
||||
profile = self.profile()
|
||||
profile.repo = self.repoSelector.currentData()
|
||||
|
@ -203,9 +201,9 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
|||
repo.delete_instance(recursive=True) # This also deletes archives.
|
||||
self.repoSelector.setCurrentIndex(0)
|
||||
self.repoSelector.removeItem(selected_repo_index)
|
||||
msg.setText(self.tr('Repository was Unlinked'))
|
||||
msg.setInformativeText(self.tr('You can always connect it again later.'))
|
||||
msg.exec_()
|
||||
msg.setWindowTitle(self.tr('Repository was Unlinked'))
|
||||
msg.setText(self.tr('You can always connect it again later.'))
|
||||
msg.show()
|
||||
|
||||
self.repo_changed.emit()
|
||||
self.init_repo_stats()
|
||||
|
@ -219,4 +217,4 @@ class RepoTab(RepoBase, RepoUI, BackupProfileMixin):
|
|||
msg.setStandardButtons(QMessageBox.Ok)
|
||||
msg.setParent(self, QtCore.Qt.Sheet)
|
||||
msg.setText(self.tr("Select a repository from the dropdown first."))
|
||||
msg.exec_()
|
||||
msg.show()
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"type": "log_message", "time": 1605817314.144782, "message": "Deleting archive: test-archive1 Thu, 2020-11-19 14:20:48 [c361322b52718ac564129d24f34b203bd0e3fd573a0c66469d80e2428dffc9df] (1/1)", "levelname": "INFO", "name": "borg.archiver"}
|
|
@ -108,7 +108,7 @@ def test_archive_mount(qapp, qtbot, mocker, borg_json_output, monkeypatch, choos
|
|||
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Un-mounted successfully.'), timeout=10000)
|
||||
|
||||
|
||||
def test_archive_extract(qapp, qtbot, mocker, borg_json_output, monkeypatch):
|
||||
def test_archive_extract(qapp, qtbot, mocker, borg_json_output):
|
||||
main = qapp.main_window
|
||||
tab = main.archiveTab
|
||||
main.tabWidget.setCurrentIndex(3)
|
||||
|
@ -116,10 +116,6 @@ def test_archive_extract(qapp, qtbot, mocker, borg_json_output, monkeypatch):
|
|||
tab.populate_from_profile()
|
||||
qtbot.waitUntil(lambda: tab.archiveTable.rowCount() == 2)
|
||||
|
||||
monkeypatch.setattr(
|
||||
vorta.views.extract_dialog.ExtractDialog, "exec_", lambda *args: True
|
||||
)
|
||||
|
||||
tab.archiveTable.selectRow(0)
|
||||
stdout, stderr = borg_json_output('list_archive')
|
||||
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
||||
|
@ -127,13 +123,14 @@ def test_archive_extract(qapp, qtbot, mocker, borg_json_output, monkeypatch):
|
|||
qtbot.mouseClick(tab.extractButton, QtCore.Qt.LeftButton)
|
||||
|
||||
qtbot.waitUntil(lambda: hasattr(tab, '_window'), timeout=10000)
|
||||
qtbot.waitUntil(lambda: tab._window == qapp.activeWindow(), timeout=5000)
|
||||
|
||||
assert tab._window.treeView.model().rootItem.childItems[0].data(0) == 'Users'
|
||||
tab._window.treeView.model().rootItem.childItems[0].load_children()
|
||||
assert tab._window.archiveNameLabel.text().startswith('test-archive, 2000')
|
||||
|
||||
|
||||
def test_archive_diff(qapp, qtbot, mocker, borg_json_output, monkeypatch):
|
||||
def test_archive_delete(qapp, qtbot, mocker, borg_json_output):
|
||||
main = qapp.main_window
|
||||
tab = main.archiveTab
|
||||
main.tabWidget.setCurrentIndex(3)
|
||||
|
@ -141,13 +138,25 @@ def test_archive_diff(qapp, qtbot, mocker, borg_json_output, monkeypatch):
|
|||
tab.populate_from_profile()
|
||||
qtbot.waitUntil(lambda: tab.archiveTable.rowCount() == 2)
|
||||
|
||||
monkeypatch.setattr(
|
||||
vorta.views.diff_dialog.DiffDialog, "exec_", lambda *args: True
|
||||
)
|
||||
tab.archiveTable.selectRow(0)
|
||||
stdout, stderr = borg_json_output('delete')
|
||||
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
||||
mocker.patch.object(vorta.borg.borg_thread, 'Popen', return_value=popen_result)
|
||||
mocker.patch.object(vorta.views.archive_tab.ArchiveTab, 'confirm_dialog', lambda x, y, z: True)
|
||||
qtbot.mouseClick(tab.deleteButton, QtCore.Qt.LeftButton)
|
||||
|
||||
monkeypatch.setattr(
|
||||
tab, "selected_archives", (0, 1)
|
||||
)
|
||||
qtbot.waitUntil(lambda: main.progressText.text() == 'Archive deleted.', timeout=3000)
|
||||
assert ArchiveModel.select().count() == 1
|
||||
assert tab.archiveTable.rowCount() == 1
|
||||
|
||||
|
||||
def test_archive_diff(qapp, qtbot, mocker, borg_json_output):
|
||||
main = qapp.main_window
|
||||
tab = main.archiveTab
|
||||
main.tabWidget.setCurrentIndex(3)
|
||||
|
||||
tab.populate_from_profile()
|
||||
qtbot.waitUntil(lambda: tab.archiveTable.rowCount() == 2)
|
||||
|
||||
stdout, stderr = borg_json_output('diff_archives')
|
||||
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
||||
|
@ -155,11 +164,13 @@ def test_archive_diff(qapp, qtbot, mocker, borg_json_output, monkeypatch):
|
|||
|
||||
qtbot.mouseClick(tab.diffButton, QtCore.Qt.LeftButton)
|
||||
qtbot.waitUntil(lambda: hasattr(tab, '_window'), timeout=5000)
|
||||
qtbot.waitUntil(lambda: tab._window == qapp.activeWindow(), timeout=5000)
|
||||
|
||||
monkeypatch.setattr(
|
||||
vorta.views.diff_result.DiffResult, "exec_", lambda *args: True
|
||||
)
|
||||
tab._window.archiveTable.selectRow(0)
|
||||
tab._window.archiveTable.selectRow(1)
|
||||
qtbot.mouseClick(tab._window.diffButton, QtCore.Qt.LeftButton)
|
||||
qtbot.waitUntil(lambda: hasattr(tab, '_resultwindow'), timeout=5000)
|
||||
qtbot.waitUntil(lambda: tab._resultwindow == qapp.activeWindow(), timeout=5000)
|
||||
|
||||
assert tab._resultwindow.treeView.model().rootItem.childItems[0].data(0) == 'test'
|
||||
tab._resultwindow.treeView.model().rootItem.childItems[0].load_children()
|
||||
|
|
|
@ -9,8 +9,9 @@ def test_profile_add(qapp, qtbot):
|
|||
qtbot.mouseClick(main.profileAddButton, QtCore.Qt.LeftButton)
|
||||
|
||||
add_profile_window = main.window
|
||||
|
||||
qtbot.addWidget(add_profile_window)
|
||||
qtbot.waitUntil(lambda: add_profile_window == qapp.activeWindow(), timeout=5000)
|
||||
|
||||
qtbot.keyClicks(add_profile_window.profileNameField, 'Test Profile')
|
||||
qtbot.mouseClick(add_profile_window.buttonBox.button(QDialogButtonBox.Save), QtCore.Qt.LeftButton)
|
||||
|
||||
|
@ -25,8 +26,9 @@ def test_profile_edit(qapp, qtbot):
|
|||
qtbot.mouseClick(main.profileRenameButton, QtCore.Qt.LeftButton)
|
||||
|
||||
edit_profile_window = main.window
|
||||
|
||||
qtbot.addWidget(edit_profile_window)
|
||||
qtbot.waitUntil(lambda: edit_profile_window == qapp.activeWindow(), timeout=5000)
|
||||
|
||||
edit_profile_window.profileNameField.setText("")
|
||||
qtbot.keyClicks(edit_profile_window.profileNameField, 'Test Profile')
|
||||
qtbot.mouseClick(edit_profile_window.buttonBox.button(QDialogButtonBox.Save), QtCore.Qt.LeftButton)
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import os
|
||||
import uuid
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
import vorta.borg.borg_thread
|
||||
import vorta.models
|
||||
from vorta.views.repo_add_dialog import AddRepoWindow
|
||||
from vorta.views.ssh_dialog import SSHAddWindow
|
||||
from vorta.keyring.abc import get_keyring
|
||||
from vorta.models import EventLogModel, RepoModel, ArchiveModel
|
||||
|
||||
|
||||
def test_repo_add_failures(qapp, qtbot, mocker, borg_json_output):
|
||||
# Add new repo window
|
||||
main = qapp.main_window
|
||||
add_repo_window = AddRepoWindow(main)
|
||||
main.repoTab.repoSelector.setCurrentIndex(1)
|
||||
add_repo_window = main.repoTab._window
|
||||
qtbot.addWidget(add_repo_window)
|
||||
|
||||
qtbot.keyClicks(add_repo_window.repoURL, 'aaa')
|
||||
|
@ -25,8 +24,7 @@ def test_repo_add_failures(qapp, qtbot, mocker, borg_json_output):
|
|||
assert add_repo_window.errorText.text() == 'Please use a longer passphrase.'
|
||||
|
||||
|
||||
def test_repo_unlink(qapp, qtbot, monkeypatch):
|
||||
monkeypatch.setattr(QMessageBox, "exec_", lambda *args: QMessageBox.Yes)
|
||||
def test_repo_unlink(qapp, qtbot):
|
||||
main = qapp.main_window
|
||||
tab = main.repoTab
|
||||
|
||||
|
@ -44,8 +42,8 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output):
|
|||
|
||||
# Add new repo window
|
||||
main = qapp.main_window
|
||||
main.repoTab.repo_added.disconnect()
|
||||
add_repo_window = AddRepoWindow(main)
|
||||
main.repoTab.repoSelector.setCurrentIndex(1)
|
||||
add_repo_window = main.repoTab._window
|
||||
test_repo_url = f'vorta-test-repo.{uuid.uuid4()}.com:repo' # Random repo URL to avoid macOS keychain
|
||||
|
||||
qtbot.keyClicks(add_repo_window.repoURL, test_repo_url)
|
||||
|
@ -57,21 +55,22 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output):
|
|||
|
||||
qtbot.mouseClick(add_repo_window.saveButton, QtCore.Qt.LeftButton)
|
||||
|
||||
with qtbot.waitSignal(add_repo_window.thread.result, timeout=3000) as blocker:
|
||||
with qtbot.waitSignal(add_repo_window.thread.result, timeout=3000) as _:
|
||||
pass
|
||||
|
||||
main.repoTab.process_new_repo(blocker.args[0])
|
||||
|
||||
assert EventLogModel.select().count() == 1
|
||||
assert EventLogModel.select().count() == 2
|
||||
assert RepoModel.get(id=2).url == test_repo_url
|
||||
|
||||
from vorta.keyring.abc import get_keyring
|
||||
keyring = get_keyring()
|
||||
assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD
|
||||
assert main.repoTab.repoSelector.currentText() == test_repo_url
|
||||
|
||||
|
||||
def test_ssh_dialog(qtbot, tmpdir):
|
||||
ssh_dialog = SSHAddWindow()
|
||||
def test_ssh_dialog(qapp, qtbot, tmpdir):
|
||||
main = qapp.main_window
|
||||
main.repoTab.sshComboBox.setCurrentIndex(1)
|
||||
ssh_dialog = main.repoTab._window
|
||||
|
||||
ssh_dir = tmpdir
|
||||
key_tmpfile = ssh_dir.join("id_rsa-test")
|
||||
pub_tmpfile = ssh_dir.join("id_rsa-test.pub")
|
||||
|
|
Loading…
Reference in New Issue