File: test_source.py

package info (click to toggle)
vorta 0.10.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,684 kB
  • sloc: python: 11,548; makefile: 89; xml: 63; sh: 51
file content (133 lines) | stat: -rw-r--r-- 5,348 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import pytest
from PyQt6 import QtCore
from PyQt6.QtWidgets import QMessageBox

import vorta.views
from vorta.views.main_window import MainWindow
from vorta.views.source_tab import SourceTab


@pytest.fixture()
def source_env(qapp, qtbot, monkeypatch, choose_file_dialog):
    """
    Handles common setup and teardown for unit tests involving the source tab.
    """
    main: MainWindow = qapp.main_window
    tab: SourceTab = main.sourceTab
    main.tabWidget.setCurrentIndex(1)
    qtbot.waitUntil(lambda: tab.sourceFilesWidget.rowCount() == 1, timeout=2000)
    monkeypatch.setattr(vorta.views.source_tab, "choose_file_dialog", choose_file_dialog)

    yield main, tab

    # Wait for directory sizing to finish
    qtbot.waitUntil(lambda: len(qapp.main_window.sourceTab.updateThreads) == 0, timeout=2000)


@pytest.mark.skip(reason="prone to failure due to background thread")
def test_source_add_remove(qapp, qtbot, monkeypatch, mocker, source_env):
    """
    Tests adding and removing source to ensure expected behavior.
    """
    main, tab = source_env
    mocker.patch.object(QMessageBox, "exec")  # prevent QMessageBox from stopping test

    # test adding a folder with os access
    mocker.patch('os.access', return_value=True)
    tab.source_add(want_folder=True)
    qtbot.waitUntil(lambda: tab.sourceFilesWidget.rowCount() == 2, **pytest._wait_defaults)
    assert tab.sourceFilesWidget.rowCount() == 2

    # test adding a folder without os access
    mocker.patch('os.access', return_value=False)
    tab.source_add(want_folder=True)
    assert tab.sourceFilesWidget.rowCount() == 2

    # test removing a folder
    tab.sourceFilesWidget.selectRow(1)
    qtbot.mouseClick(tab.removeButton, QtCore.Qt.MouseButton.LeftButton)
    qtbot.waitUntil(lambda: tab.sourceFilesWidget.rowCount() == 1, **pytest._wait_defaults)
    assert tab.sourceFilesWidget.rowCount() == 1


@pytest.mark.skip(reason="prone to failure due to background thread")
@pytest.mark.parametrize(
    "path, valid",
    [
        (__file__, True),  # valid path
        ("test", False),  # invalid path
        (f"file://{__file__}", True),  # valid - normal path with prefix that will be stripped
        (f"file://{__file__}\n{__file__}", True),  # valid - two files separated by new line
        (f"file://{__file__}{__file__}", False),  # invalid - no new line separating file names
    ],
)
def test_valid_and_invalid_source_paths(qapp, qtbot, mocker, source_env, path, valid):
    """
    Valid paths will be added as a source.
    Invalid paths will trigger an alert and not be added as a source.
    """
    main, tab = source_env
    mock_clipboard = mocker.Mock()
    mock_clipboard.text.return_value = path

    mocker.patch.object(vorta.views.source_tab.QApplication, 'clipboard', return_value=mock_clipboard)
    mocker.patch.object(QMessageBox, "exec")  # prevent QMessageBox from stopping test
    tab.paste_text()

    if valid:
        assert not hasattr(tab, '_msg')
        qtbot.waitUntil(lambda: tab.sourceFilesWidget.rowCount() == 2, **pytest._wait_defaults)
        assert tab.sourceFilesWidget.rowCount() == 2
    else:
        qtbot.waitUntil(lambda: hasattr(tab, "_msg"), **pytest._wait_defaults)
        assert tab._msg.text().startswith("Some of your sources are invalid")
        assert tab.sourceFilesWidget.rowCount() == 1


@pytest.mark.skip(reason="prone to failure due to background thread")
def test_sources_update(qapp, qtbot, mocker, source_env):
    """
    Tests the source update button in the source tab
    """
    main, tab = source_env
    update_path_info_spy = mocker.spy(tab, "update_path_info")

    # test that `update_path_info()` has been called for each source path
    qtbot.mouseClick(tab.updateButton, QtCore.Qt.MouseButton.LeftButton)
    assert tab.sourceFilesWidget.rowCount() == 1
    assert update_path_info_spy.call_count == 1

    # add a new source and reset mock
    tab.source_add(want_folder=True)
    qtbot.waitUntil(lambda: tab.sourceFilesWidget.rowCount() == 2, **pytest._wait_defaults)
    update_path_info_spy.reset_mock()

    # retest that `update_path_info()` has been called for each source path
    qtbot.mouseClick(tab.updateButton, QtCore.Qt.MouseButton.LeftButton)
    assert tab.sourceFilesWidget.rowCount() == 2
    assert update_path_info_spy.call_count == 2


@pytest.mark.skip(reason="prone to failure due to background thread")
def test_source_copy(qapp, qtbot, monkeypatch, mocker, source_env):
    """
    Test source_copy() with and without an index passed.
    If no index is passed, it should copy the first selected source
    """
    main, tab = source_env

    mock_clipboard = mocker.patch.object(qapp.clipboard(), "setMimeData")
    tab.source_add(want_folder=True)
    qtbot.waitUntil(lambda: tab.sourceFilesWidget.rowCount() == 2, **pytest._wait_defaults)

    tab.sourceFilesWidget.selectRow(0)
    tab.source_copy()
    assert mock_clipboard.call_count == 1
    source = mock_clipboard.call_args[0][0]  # retrieves the QMimeData() object used in method call
    assert source.text() == "/tmp"

    index = tab.sourceFilesWidget.model().index(1, 0)
    tab.source_copy(index)
    assert mock_clipboard.call_count == 2
    source = mock_clipboard.call_args[0][0]  # retrieves the QMimeData() object used in method call
    assert source.text() == "/tmp/another"