Refactoring: remove last exec_, add tests, retain archive deletion message. By @samuel-w (#722)

This commit is contained in:
Samuel 2020-11-19 18:46:09 -06:00 committed by GitHub
parent 39b7f58483
commit 0b6961213f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 93 additions and 93 deletions

View File

@ -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__':

View File

@ -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()

View File

@ -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:

View File

@ -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_())

View File

@ -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()))

View File

@ -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.'))

View File

@ -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()

View File

@ -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"}

View File

@ -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()

View File

@ -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)

View File

@ -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")