diff --git a/src/vorta/assets/UI/scheduletab.ui b/src/vorta/assets/UI/scheduletab.ui index f7cb7b34e..56942c17c 100644 --- a/src/vorta/assets/UI/scheduletab.ui +++ b/src/vorta/assets/UI/scheduletab.ui @@ -530,7 +530,7 @@ 12 - + 4 @@ -557,6 +557,13 @@ + + + + Allow new networks by default + + + diff --git a/src/vorta/store/migrations.py b/src/vorta/store/migrations.py index a26892597..55ad81064 100644 --- a/src/vorta/store/migrations.py +++ b/src/vorta/store/migrations.py @@ -248,6 +248,11 @@ def run_migrations(current_schema, db_connection): 'name', pw.CharField(default=''), ), + migrator.add_column( + BackupProfileModel._meta.table_name, + 'allow_new_networks', + pw.BooleanField(default=True), + ), ) diff --git a/src/vorta/store/models.py b/src/vorta/store/models.py index 400299fb2..a5a2e7bba 100644 --- a/src/vorta/store/models.py +++ b/src/vorta/store/models.py @@ -102,6 +102,7 @@ class BackupProfileModel(BaseModel): pre_backup_cmd = pw.CharField(default='') post_backup_cmd = pw.CharField(default='') dont_run_on_metered_networks = pw.BooleanField(default=True) + allow_new_networks = pw.BooleanField(default=False) def refresh(self): return type(self).get(self._pk_expr()) diff --git a/src/vorta/utils.py b/src/vorta/utils.py index 033b486a5..839679497 100644 --- a/src/vorta/utils.py +++ b/src/vorta/utils.py @@ -314,12 +314,13 @@ def get_sorted_wifis(profile): # Pull networks known to OS and all other backup profiles system_wifis = get_network_status_monitor().get_known_wifis() from_other_profiles = WifiSettingModel.select().where(WifiSettingModel.profile != profile.id).execute() + allow_new_networks = profile.allow_new_networks for wifi in list(from_other_profiles) + system_wifis: db_wifi, created = WifiSettingModel.get_or_create( ssid=wifi.ssid, profile=profile.id, - defaults={'last_connected': wifi.last_connected, 'allowed': True}, + defaults={'last_connected': wifi.last_connected, 'allowed': allow_new_networks}, ) # Update last connected time diff --git a/src/vorta/views/schedule_tab.py b/src/vorta/views/schedule_tab.py index dc97cfa47..5e917c305 100644 --- a/src/vorta/views/schedule_tab.py +++ b/src/vorta/views/schedule_tab.py @@ -86,6 +86,9 @@ def __init__(self, parent=None): self.meteredNetworksCheckBox.stateChanged.connect( lambda new_val, attr='dont_run_on_metered_networks': self.save_profile_attr(attr, not new_val) ) + self.allowNewNetworksCheckBox.stateChanged.connect( + lambda new_val, attr='allow_new_networks': self.save_profile_attr(attr, new_val) + ) self.postBackupCmdLineEdit.textEdited.connect( lambda new_val, attr='post_backup_cmd': self.save_profile_attr(attr, new_val) ) @@ -161,6 +164,7 @@ def populate_from_profile(self): self.missedBackupsCheckBox.setCheckState( QtCore.Qt.CheckState.Checked if profile.schedule_make_up_missed else QtCore.Qt.CheckState.Unchecked ) + self.allowNewNetworksCheckBox.setChecked(profile.allow_new_networks) self.meteredNetworksCheckBox.setChecked(False if profile.dont_run_on_metered_networks else True) self.preBackupCmdLineEdit.setText(profile.pre_backup_cmd) diff --git a/tests/conftest.py b/tests/conftest.py index 0f7810265..07ea5f6e6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,11 +1,37 @@ import os import sys +from datetime import datetime as dt +from unittest.mock import MagicMock import pytest import vorta import vorta.application import vorta.borg.jobs_manager from peewee import SqliteDatabase +from vorta.store.models import ( + ArchiveModel, + BackupProfileModel, + EventLogModel, + RepoModel, + RepoPassword, + SchemaVersion, + SettingsModel, + SourceFileModel, + WifiSettingModel, +) +from vorta.views.main_window import MainWindow + +models = [ + RepoModel, + RepoPassword, + BackupProfileModel, + SourceFileModel, + SettingsModel, + ArchiveModel, + WifiSettingModel, + EventLogModel, + SchemaVersion, +] def pytest_configure(config): @@ -29,8 +55,87 @@ def qapp(tmpdir_factory): from vorta.application import VortaApp + VortaApp.set_borg_details_action = MagicMock() # Can't use pytest-mock in session scope + VortaApp.scheduler = MagicMock() + qapp = VortaApp([]) # Only init QApplication once to avoid segfaults while testing. yield qapp mock_db.close() qapp.quit() + + +@pytest.fixture(scope='function', autouse=True) +def init_db(qapp, qtbot, tmpdir_factory): + tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite') + mock_db = SqliteDatabase( + str(tmp_db), + pragmas={ + 'journal_mode': 'wal', + }, + ) + vorta.store.connection.init_db(mock_db) + + default_profile = BackupProfileModel(name='Default') + default_profile.save() + + new_repo = RepoModel(url='i0fi93@i593.repo.borgbase.com:repo') + new_repo.encryption = 'none' + new_repo.save() + + default_profile.repo = new_repo.id + default_profile.dont_run_on_metered_networks = False + default_profile.allow_new_networks = True + default_profile.validation_on = False + default_profile.save() + + test_archive = ArchiveModel(snapshot_id='99999', name='test-archive', time=dt(2000, 1, 1, 0, 0), repo=1) + test_archive.save() + + test_archive1 = ArchiveModel(snapshot_id='99998', name='test-archive1', time=dt(2000, 1, 1, 0, 0), repo=1) + test_archive1.save() + + source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo, dir_size=100, dir_files_count=18, path_isdir=True) + source_dir.save() + + qapp.main_window.deleteLater() + del qapp.main_window + qapp.main_window = MainWindow(qapp) # Re-open main window to apply mock data in UI + + yield + + qapp.jobs_manager.cancel_all_jobs() + qapp.backup_finished_event.disconnect() + qapp.scheduler.schedule_changed.disconnect() + qtbot.waitUntil(lambda: not qapp.jobs_manager.is_worker_running(), **pytest._wait_defaults) + mock_db.close() + + +@pytest.fixture +def choose_file_dialog(*args): + class MockFileDialog: + def __init__(self, *args, **kwargs): + pass + + def open(self, func): + func() + + def selectedFiles(self): + return ['/tmp'] + + return MockFileDialog + + +@pytest.fixture +def borg_json_output(): + def _read_json(subcommand): + stdout = open(f'tests/borg_json_output/{subcommand}_stdout.json') + stderr = open(f'tests/borg_json_output/{subcommand}_stderr.json') + return stdout, stderr + + return _read_json + + +@pytest.fixture +def rootdir(): + return os.path.dirname(os.path.abspath(__file__)) diff --git a/tests/unit/profile_exports/valid.json b/tests/unit/profile_exports/valid.json index ee252a74b..636dd2382 100644 --- a/tests/unit/profile_exports/valid.json +++ b/tests/unit/profile_exports/valid.json @@ -35,6 +35,7 @@ "password": "Tr0ub4dor&3", "post_backup_cmd": "", "dont_run_on_metered_networks": true, + "allow_new_networks": true, "SourceFileModel": [ { "dir": "/this/is/a/test/file",