More work on the UI accessibility.
This commit is contained in:
1 parent
c4ccc39aac
commit
d9f4ac4135
3 files changed
+131
-6
No files matched your search
@@ -0,0 +1,129 @@
|
||||
"""Exercise the assembled library UI with fake data and controlled requests."""
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtTest import QTest
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from src.api.models import Album, Artist, Song
|
||||
from src.main_window import MainWindow
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def window(monkeypatch, tmp_path):
|
||||
app = QApplication.instance() or QApplication([])
|
||||
for name in ('XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME'):
|
||||
monkeypatch.setenv(name, str(tmp_path / name))
|
||||
monkeypatch.setattr(MainWindow, 'setupMpris', lambda self: None)
|
||||
monkeypatch.setattr(MainWindow, 'showServerSetup', lambda self: None)
|
||||
# Avoid the production close handler's forced process exit.
|
||||
monkeypatch.setattr(MainWindow, 'closeEvent', lambda self, event: event.accept())
|
||||
monkeypatch.setattr("src.managers.playback_manager.QMediaPlayer", Mock())
|
||||
monkeypatch.setattr("src.managers.playback_manager.QAudioOutput", Mock())
|
||||
w = MainWindow()
|
||||
w.client = Mock()
|
||||
w.startPlaybackWithSongs = Mock()
|
||||
pending = []
|
||||
w._run_background = lambda label, work, on_success=None, **kw: pending.append(on_success)
|
||||
w._applyLibraryData({'artists': [Artist('artist', 'Artist', 1)]})
|
||||
w.show()
|
||||
w.libraryTree.setFocus()
|
||||
app.processEvents()
|
||||
yield w, pending
|
||||
w._executor.shutdown(wait=True)
|
||||
w.close()
|
||||
w.deleteLater()
|
||||
app.processEvents()
|
||||
|
||||
|
||||
def open_album(window):
|
||||
w, pending = window
|
||||
tree = w.libraryTree
|
||||
artist = w.artistsRoot.child(0)
|
||||
tree.setCurrentItem(artist)
|
||||
QTest.keyClick(tree, Qt.Key_Right)
|
||||
pending.pop()([Album('album', 'Album', 'Artist', songCount=1)])
|
||||
QTest.keyClick(tree, Qt.Key_Right)
|
||||
album = tree.currentItem()
|
||||
assert album.parent() is artist
|
||||
QTest.keyClick(tree, Qt.Key_Right)
|
||||
songs = [Song('song', 'Song', 'Album', 'album', 'Artist')]
|
||||
pending.pop()(songs)
|
||||
QApplication.processEvents()
|
||||
return album, songs
|
||||
|
||||
|
||||
def test_album_can_collapse_and_reopen_after_loading(window):
|
||||
w, pending = window
|
||||
album, songs = open_album(window)
|
||||
tree = w.libraryTree
|
||||
assert album.isExpanded()
|
||||
QTest.keyClick(tree, Qt.Key_Right)
|
||||
assert tree.currentItem() is album.child(0)
|
||||
QTest.keyClick(tree, Qt.Key_Left)
|
||||
assert tree.currentItem() is album
|
||||
QTest.keyClick(tree, Qt.Key_Left)
|
||||
assert not album.isExpanded()
|
||||
assert tree.visualItemRect(album.child(0)).isEmpty()
|
||||
QTest.keyClick(tree, Qt.Key_Right)
|
||||
assert album.isExpanded()
|
||||
assert not pending
|
||||
|
||||
|
||||
def test_playback_completion_respects_album_collapse(window):
|
||||
w, pending = window
|
||||
album, songs = open_album(window)
|
||||
QTest.keyClick(w.libraryTree, Qt.Key_Return)
|
||||
assert len(pending) == 1
|
||||
QTest.keyClick(w.libraryTree, Qt.Key_Left)
|
||||
assert not album.isExpanded()
|
||||
pending.pop()((None, songs))
|
||||
QApplication.processEvents()
|
||||
assert not album.isExpanded()
|
||||
assert w.libraryTree.visualItemRect(album.child(0)).isEmpty()
|
||||
w.startPlaybackWithSongs.assert_called_once()
|
||||
|
||||
|
||||
def test_album_can_collapse_with_mouse(window):
|
||||
w, _ = window
|
||||
album, _ = open_album(window)
|
||||
tree = w.libraryTree
|
||||
tree.setCurrentItem(album.child(0))
|
||||
rect = tree.visualItemRect(album)
|
||||
# Click the branch indicator just before the album's text rectangle.
|
||||
point = rect.center()
|
||||
point.setX(rect.left() - tree.indentation() // 2)
|
||||
QTest.mouseClick(tree.viewport(), Qt.LeftButton, pos=point)
|
||||
QApplication.processEvents()
|
||||
assert not album.isExpanded()
|
||||
assert tree.currentItem() is album
|
||||
|
||||
|
||||
def test_album_browse_response_does_not_reopen_collapsed_branch(window):
|
||||
w, pending = window
|
||||
album, songs = open_album(window)
|
||||
data = album.data(0, Qt.UserRole)
|
||||
data['loaded'] = False
|
||||
album.setData(0, Qt.UserRole, data)
|
||||
QTest.keyClick(w.libraryTree, Qt.Key_Left)
|
||||
QTest.keyClick(w.libraryTree, Qt.Key_Right)
|
||||
assert len(pending) == 1
|
||||
QTest.keyClick(w.libraryTree, Qt.Key_Left)
|
||||
pending.pop()(songs)
|
||||
QApplication.processEvents()
|
||||
assert not album.isExpanded()
|
||||
assert not w.libraryTree.isItemNavigable(album.child(0))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('kind', ['artist', 'genre'])
|
||||
def test_other_playback_responses_preserve_collapsed_branches(window, kind):
|
||||
w, _ = window
|
||||
album, songs = open_album(window)
|
||||
album.setExpanded(False)
|
||||
if kind == 'artist':
|
||||
w._onArtistLoadedForPlay(album, (None, songs))
|
||||
else:
|
||||
w._onGenreLoadedForPlay('Genre', album, (songs, False))
|
||||
assert not album.isExpanded()
|
||||
w.startPlaybackWithSongs.assert_called_once()
|
||||
Reference in new issue
Block a user