Remove sessions from test_playlistmodel.py
This commit is contained in:
parent
aec994bafd
commit
a2baf489c3
@ -1,480 +0,0 @@
|
|||||||
"""
|
|
||||||
Tests are named 'test_nnn_xxxx' where 'nn n' is a number. This is used to ensure that
|
|
||||||
the tests run in order as we rely (in some cases) upon the results of an earlier test.
|
|
||||||
Yes, we shouldn't do that.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Standard library imports
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import tempfile
|
|
||||||
import unittest
|
|
||||||
from unittest.mock import MagicMock, patch
|
|
||||||
|
|
||||||
# PyQt imports
|
|
||||||
from PyQt6.QtWidgets import QDialog, QFileDialog
|
|
||||||
|
|
||||||
# Third party imports
|
|
||||||
from mutagen.mp3 import MP3 # type: ignore
|
|
||||||
import pytest
|
|
||||||
from pytestqt.plugin import QtBot # type: ignore
|
|
||||||
|
|
||||||
# App imports
|
|
||||||
from app import ds, musicmuster
|
|
||||||
from app.models import (
|
|
||||||
db,
|
|
||||||
Tracks,
|
|
||||||
)
|
|
||||||
from config import Config
|
|
||||||
from file_importer import FileImporter
|
|
||||||
|
|
||||||
|
|
||||||
# Custom fixture to adapt qtbot for use with unittest.TestCase
|
|
||||||
@pytest.fixture(scope="class")
|
|
||||||
def qtbot_adapter(qapp, request):
|
|
||||||
"""Adapt qtbot fixture for usefixtures and unittest.TestCase"""
|
|
||||||
request.cls.qtbot = QtBot(request)
|
|
||||||
|
|
||||||
|
|
||||||
# Fixture for tmp_path to be available in the class
|
|
||||||
@pytest.fixture(scope="class")
|
|
||||||
def class_tmp_path(request, tmp_path_factory):
|
|
||||||
"""Provide a class-wide tmp_path"""
|
|
||||||
request.cls.tmp_path = tmp_path_factory.mktemp("pytest_tmp")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("qtbot_adapter", "class_tmp_path")
|
|
||||||
class MyTestCase(unittest.TestCase):
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
"""Runs once before any test in this class"""
|
|
||||||
|
|
||||||
db.create_all()
|
|
||||||
|
|
||||||
cls.widget = musicmuster.Window()
|
|
||||||
|
|
||||||
# Create a playlist for all tests
|
|
||||||
playlist_name = "file importer playlist"
|
|
||||||
playlist = ds.playlist_create(name=playlist_name, template_id=0)
|
|
||||||
cls.widget._open_playlist(playlist)
|
|
||||||
|
|
||||||
# Create our musicstore
|
|
||||||
cls.import_source = tempfile.mkdtemp(suffix="_MMsource_pytest", dir="/tmp")
|
|
||||||
Config.REPLACE_FILES_DEFAULT_SOURCE = cls.import_source
|
|
||||||
cls.musicstore = tempfile.mkdtemp(suffix="_MMstore_pytest", dir="/tmp")
|
|
||||||
Config.IMPORT_DESTINATION = cls.musicstore
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
"""Runs once after all tests"""
|
|
||||||
|
|
||||||
db.drop_all()
|
|
||||||
shutil.rmtree(cls.musicstore)
|
|
||||||
shutil.rmtree(cls.import_source)
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
"""Runs before each test"""
|
|
||||||
|
|
||||||
with self.qtbot.waitExposed(self.widget):
|
|
||||||
self.widget.show()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
"""Runs after each test"""
|
|
||||||
self.widget.close() # Close UI to prevent side effects
|
|
||||||
|
|
||||||
def wait_for_workers(self, timeout: int = 10000):
|
|
||||||
"""
|
|
||||||
Let import threads workers run to completion
|
|
||||||
"""
|
|
||||||
|
|
||||||
def workers_empty():
|
|
||||||
assert FileImporter.workers == {}
|
|
||||||
|
|
||||||
self.qtbot.waitUntil(workers_empty, timeout=timeout)
|
|
||||||
|
|
||||||
def test_001_import_no_files(self):
|
|
||||||
"""Try importing with no files to import"""
|
|
||||||
|
|
||||||
with patch("file_importer.show_OK") as mock_show_ok:
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
mock_show_ok.assert_called_once_with(
|
|
||||||
"File import",
|
|
||||||
f"No files in {Config.REPLACE_FILES_DEFAULT_SOURCE} to import",
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_002_import_file_and_cancel(self):
|
|
||||||
"""Cancel file import"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/isa.mp3"
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
|
|
||||||
with (
|
|
||||||
patch("file_importer.PickMatch") as MockPickMatch,
|
|
||||||
patch("file_importer.show_OK") as mock_show_ok,
|
|
||||||
):
|
|
||||||
# Create a mock instance of PickMatch
|
|
||||||
mock_dialog_instance = MagicMock()
|
|
||||||
MockPickMatch.return_value = mock_dialog_instance
|
|
||||||
|
|
||||||
# Simulate the user clicking OK in the dialog
|
|
||||||
mock_dialog_instance.exec.return_value = QDialog.DialogCode.Rejected
|
|
||||||
mock_dialog_instance.selected_track_id = -1 # Simulated return value
|
|
||||||
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
|
|
||||||
# Ensure PickMatch was instantiated correctly
|
|
||||||
MockPickMatch.assert_called_once_with(
|
|
||||||
new_track_description="I'm So Afraid (Fleetwood Mac)",
|
|
||||||
choices=[("Do not import", -1, ""), ("Import as new track", 0, "")],
|
|
||||||
default=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify exec() was called
|
|
||||||
mock_dialog_instance.exec.assert_called_once()
|
|
||||||
|
|
||||||
# Ensure selected_track_id was accessed after dialog.exec()
|
|
||||||
assert mock_dialog_instance.selected_track_id < 0
|
|
||||||
|
|
||||||
mock_show_ok.assert_called_once_with(
|
|
||||||
"File not imported",
|
|
||||||
"isa.mp3 will not be imported because you asked not to import this file",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_003_import_first_file(self):
|
|
||||||
"""Import file into empty directory"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/isa.mp3"
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
|
|
||||||
with patch("file_importer.PickMatch") as MockPickMatch:
|
|
||||||
# Create a mock instance of PickMatch
|
|
||||||
mock_dialog_instance = MagicMock()
|
|
||||||
MockPickMatch.return_value = mock_dialog_instance
|
|
||||||
|
|
||||||
# Simulate the user clicking OK in the dialog
|
|
||||||
mock_dialog_instance.exec.return_value = QDialog.DialogCode.Accepted
|
|
||||||
mock_dialog_instance.selected_track_id = 0 # Simulated return value
|
|
||||||
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
|
|
||||||
# Ensure PickMatch was instantiated correctly
|
|
||||||
MockPickMatch.assert_called_once_with(
|
|
||||||
new_track_description="I'm So Afraid (Fleetwood Mac)",
|
|
||||||
choices=[("Do not import", -1, ""), ("Import as new track", 0, "")],
|
|
||||||
default=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify exec() was called
|
|
||||||
mock_dialog_instance.exec.assert_called_once()
|
|
||||||
|
|
||||||
# Ensure selected_track_id was accessed after dialog.exec()
|
|
||||||
assert mock_dialog_instance.selected_track_id == 0
|
|
||||||
|
|
||||||
self.wait_for_workers()
|
|
||||||
|
|
||||||
# Check track was imported
|
|
||||||
tracks = ds.get_all_tracks()
|
|
||||||
assert len(tracks) == 1
|
|
||||||
track = tracks[0]
|
|
||||||
assert track.title == "I'm So Afraid"
|
|
||||||
assert track.artist == "Fleetwood Mac"
|
|
||||||
track_file = os.path.join(
|
|
||||||
self.musicstore, os.path.basename(test_track_path)
|
|
||||||
)
|
|
||||||
assert track.path == track_file
|
|
||||||
assert os.path.exists(track_file)
|
|
||||||
assert os.listdir(self.import_source) == []
|
|
||||||
|
|
||||||
def test_004_import_second_file(self):
|
|
||||||
"""Import a second file"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/lovecats.mp3"
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
|
|
||||||
with patch("file_importer.PickMatch") as MockPickMatch:
|
|
||||||
# Create a mock instance of PickMatch
|
|
||||||
mock_dialog_instance = MagicMock()
|
|
||||||
MockPickMatch.return_value = mock_dialog_instance
|
|
||||||
|
|
||||||
# Simulate the user clicking OK in the dialog
|
|
||||||
mock_dialog_instance.exec.return_value = QDialog.DialogCode.Accepted
|
|
||||||
mock_dialog_instance.selected_track_id = 0 # Simulated return value
|
|
||||||
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
|
|
||||||
# Ensure PickMatch was instantiated correctly
|
|
||||||
MockPickMatch.assert_called_once_with(
|
|
||||||
new_track_description="The Lovecats (The Cure)",
|
|
||||||
choices=[("Do not import", -1, ""), ("Import as new track", 0, "")],
|
|
||||||
default=1,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify exec() was called
|
|
||||||
mock_dialog_instance.exec.assert_called_once()
|
|
||||||
|
|
||||||
# Ensure selected_track_id was accessed after dialog.exec()
|
|
||||||
assert mock_dialog_instance.selected_track_id == 0
|
|
||||||
|
|
||||||
self.wait_for_workers()
|
|
||||||
|
|
||||||
# Check track was imported
|
|
||||||
tracks = ds.get_all_tracks()
|
|
||||||
assert len(tracks) == 2
|
|
||||||
track = tracks[1]
|
|
||||||
assert track.title == "The Lovecats"
|
|
||||||
assert track.artist == "The Cure"
|
|
||||||
track_file = os.path.join(
|
|
||||||
self.musicstore, os.path.basename(test_track_path)
|
|
||||||
)
|
|
||||||
assert track.path == track_file
|
|
||||||
assert os.path.exists(track_file)
|
|
||||||
assert os.listdir(self.import_source) == []
|
|
||||||
|
|
||||||
def test_005_replace_file(self):
|
|
||||||
"""Import the same file again and update existing track"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/lovecats.mp3"
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
|
|
||||||
with patch("file_importer.PickMatch") as MockPickMatch:
|
|
||||||
# Create a mock instance of PickMatch
|
|
||||||
mock_dialog_instance = MagicMock()
|
|
||||||
MockPickMatch.return_value = mock_dialog_instance
|
|
||||||
|
|
||||||
# Simulate the user clicking OK in the dialog
|
|
||||||
mock_dialog_instance.exec.return_value = QDialog.DialogCode.Accepted
|
|
||||||
mock_dialog_instance.selected_track_id = 2 # Simulated return value
|
|
||||||
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
|
|
||||||
# Ensure PickMatch was instantiated correctly
|
|
||||||
MockPickMatch.assert_called_once_with(
|
|
||||||
new_track_description="The Lovecats (The Cure)",
|
|
||||||
choices=[
|
|
||||||
("Do not import", -1, ""),
|
|
||||||
("Import as new track", 0, ""),
|
|
||||||
(
|
|
||||||
"The Lovecats (The Cure) (100%)",
|
|
||||||
2,
|
|
||||||
os.path.join(
|
|
||||||
self.musicstore, os.path.basename(test_track_path)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
default=2,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify exec() was called
|
|
||||||
mock_dialog_instance.exec.assert_called_once()
|
|
||||||
|
|
||||||
self.wait_for_workers()
|
|
||||||
|
|
||||||
# Check track was imported
|
|
||||||
tracks = ds.get_all_tracks()
|
|
||||||
assert len(tracks) == 2
|
|
||||||
track = tracks[1]
|
|
||||||
assert track.title == "The Lovecats"
|
|
||||||
assert track.artist == "The Cure"
|
|
||||||
assert track.track_id == 2
|
|
||||||
track_file = os.path.join(
|
|
||||||
self.musicstore, os.path.basename(test_track_path)
|
|
||||||
)
|
|
||||||
assert track.path == track_file
|
|
||||||
assert os.path.exists(track_file)
|
|
||||||
assert os.listdir(self.import_source) == []
|
|
||||||
|
|
||||||
def test_006_import_file_no_tags(self) -> None:
|
|
||||||
"""Try to import untagged file"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/lovecats.mp3"
|
|
||||||
test_filename = os.path.basename(test_track_path)
|
|
||||||
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
import_file = os.path.join(self.import_source, test_filename)
|
|
||||||
assert os.path.exists(import_file)
|
|
||||||
|
|
||||||
# Remove tags
|
|
||||||
src = MP3(import_file)
|
|
||||||
src.delete()
|
|
||||||
src.save()
|
|
||||||
|
|
||||||
with patch("file_importer.show_OK") as mock_show_ok:
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
mock_show_ok.assert_called_once_with(
|
|
||||||
"File not imported",
|
|
||||||
f"{test_filename} will not be imported because of tag errors "
|
|
||||||
f"(Missing tags in {import_file})",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_007_import_unreadable_file(self) -> None:
|
|
||||||
"""Import unreadable file"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/lovecats.mp3"
|
|
||||||
test_filename = os.path.basename(test_track_path)
|
|
||||||
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
import_file = os.path.join(self.import_source, test_filename)
|
|
||||||
assert os.path.exists(import_file)
|
|
||||||
|
|
||||||
# Make undreadable
|
|
||||||
os.chmod(import_file, 0)
|
|
||||||
|
|
||||||
with patch("file_importer.show_OK") as mock_show_ok:
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
mock_show_ok.assert_called_once_with(
|
|
||||||
"File not imported",
|
|
||||||
f"{test_filename} will not be imported because {import_file} is unreadable",
|
|
||||||
)
|
|
||||||
|
|
||||||
# clean up
|
|
||||||
os.chmod(import_file, 0o777)
|
|
||||||
os.unlink(import_file)
|
|
||||||
|
|
||||||
def test_008_import_new_file_existing_destination(self) -> None:
|
|
||||||
"""Import duplicate file"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/lovecats.mp3"
|
|
||||||
test_filename = os.path.basename(test_track_path)
|
|
||||||
new_destination = os.path.join(self.musicstore, "lc2.mp3")
|
|
||||||
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
import_file = os.path.join(self.import_source, test_filename)
|
|
||||||
assert os.path.exists(import_file)
|
|
||||||
|
|
||||||
with (
|
|
||||||
patch("file_importer.PickMatch") as MockPickMatch,
|
|
||||||
patch.object(
|
|
||||||
QFileDialog, "getSaveFileName", return_value=(new_destination, "")
|
|
||||||
) as mock_file_dialog,
|
|
||||||
patch("file_importer.show_OK") as mock_show_ok,
|
|
||||||
):
|
|
||||||
mock_file_dialog.return_value = (
|
|
||||||
new_destination,
|
|
||||||
"",
|
|
||||||
) # Ensure mock correctly returns expected value
|
|
||||||
|
|
||||||
# Create a mock instance of PickMatch
|
|
||||||
mock_dialog_instance = MagicMock()
|
|
||||||
MockPickMatch.return_value = mock_dialog_instance
|
|
||||||
|
|
||||||
# Simulate the user clicking OK in the dialog
|
|
||||||
mock_dialog_instance.exec.return_value = QDialog.DialogCode.Accepted
|
|
||||||
mock_dialog_instance.selected_track_id = 0 # Simulated return value
|
|
||||||
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
|
|
||||||
# Ensure PickMatch was instantiated correctly
|
|
||||||
MockPickMatch.assert_called_once_with(
|
|
||||||
new_track_description="The Lovecats (The Cure)",
|
|
||||||
choices=[
|
|
||||||
("Do not import", -1, ""),
|
|
||||||
("Import as new track", 0, ""),
|
|
||||||
(
|
|
||||||
"The Lovecats (The Cure) (100%)",
|
|
||||||
2,
|
|
||||||
os.path.join(
|
|
||||||
self.musicstore, os.path.basename(test_track_path)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
default=2,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify exec() was called
|
|
||||||
mock_dialog_instance.exec.assert_called_once()
|
|
||||||
|
|
||||||
destination = os.path.join(self.musicstore, test_filename)
|
|
||||||
mock_show_ok.assert_called_once_with(
|
|
||||||
title="Desintation path exists",
|
|
||||||
msg=f"New import requested but default destination path ({destination}) "
|
|
||||||
"already exists. Click OK and choose where to save this track",
|
|
||||||
parent=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.wait_for_workers()
|
|
||||||
|
|
||||||
# Ensure QFileDialog was called and returned expected value
|
|
||||||
assert mock_file_dialog.called # Ensure the mock was used
|
|
||||||
result = mock_file_dialog()
|
|
||||||
assert result[0] == new_destination # Validate return value
|
|
||||||
|
|
||||||
# Check track was imported
|
|
||||||
tracks = ds.get_all_tracks()
|
|
||||||
track = tracks[2]
|
|
||||||
assert track.title == "The Lovecats"
|
|
||||||
assert track.artist == "The Cure"
|
|
||||||
assert track.track_id == 3
|
|
||||||
assert track.path == new_destination
|
|
||||||
assert os.path.exists(new_destination)
|
|
||||||
assert os.listdir(self.import_source) == []
|
|
||||||
|
|
||||||
# Remove file so as not to interfere with later tests
|
|
||||||
ds.delete(track)
|
|
||||||
tracks = ds.get_all_tracks()
|
|
||||||
assert len(tracks) == 2
|
|
||||||
|
|
||||||
os.unlink(new_destination)
|
|
||||||
assert not os.path.exists(new_destination)
|
|
||||||
|
|
||||||
def test_009_import_similar_file(self) -> None:
|
|
||||||
"""Import file with similar, but different, title"""
|
|
||||||
|
|
||||||
test_track_path = "testdata/lovecats.mp3"
|
|
||||||
test_filename = os.path.basename(test_track_path)
|
|
||||||
|
|
||||||
shutil.copy(test_track_path, self.import_source)
|
|
||||||
import_file = os.path.join(self.import_source, test_filename)
|
|
||||||
assert os.path.exists(import_file)
|
|
||||||
|
|
||||||
# Change title tag
|
|
||||||
src = MP3(import_file)
|
|
||||||
src["TIT2"].text[0] += " xyz"
|
|
||||||
src.save()
|
|
||||||
|
|
||||||
with patch("file_importer.PickMatch") as MockPickMatch:
|
|
||||||
# Create a mock instance of PickMatch
|
|
||||||
mock_dialog_instance = MagicMock()
|
|
||||||
MockPickMatch.return_value = mock_dialog_instance
|
|
||||||
|
|
||||||
# Simulate the user clicking OK in the dialog
|
|
||||||
mock_dialog_instance.exec.return_value = QDialog.DialogCode.Accepted
|
|
||||||
mock_dialog_instance.selected_track_id = 2 # Simulated return value
|
|
||||||
|
|
||||||
self.widget.import_files_wrapper()
|
|
||||||
|
|
||||||
# Ensure PickMatch was instantiated correctly
|
|
||||||
MockPickMatch.assert_called_once_with(
|
|
||||||
new_track_description="The Lovecats xyz (The Cure)",
|
|
||||||
choices=[
|
|
||||||
("Do not import", -1, ""),
|
|
||||||
("Import as new track", 0, ""),
|
|
||||||
(
|
|
||||||
"The Lovecats (The Cure) (93%)",
|
|
||||||
2,
|
|
||||||
os.path.join(
|
|
||||||
self.musicstore, os.path.basename(test_track_path)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
default=2,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Verify exec() was called
|
|
||||||
mock_dialog_instance.exec.assert_called_once()
|
|
||||||
|
|
||||||
self.wait_for_workers()
|
|
||||||
|
|
||||||
# Check track was imported
|
|
||||||
tracks = ds.get_all_tracks()
|
|
||||||
assert len(tracks) == 2
|
|
||||||
track = tracks[1]
|
|
||||||
assert track.title == "The Lovecats xyz"
|
|
||||||
assert track.artist == "The Cure"
|
|
||||||
assert track.track_id == 2
|
|
||||||
track_file = os.path.join(
|
|
||||||
self.musicstore, os.path.basename(test_track_path)
|
|
||||||
)
|
|
||||||
assert track.path == track_file
|
|
||||||
assert os.path.exists(track_file)
|
|
||||||
assert os.listdir(self.import_source) == []
|
|
||||||
@ -9,11 +9,7 @@ from PyQt6.QtCore import Qt, QModelIndex
|
|||||||
# App imports
|
# App imports
|
||||||
from app.helpers import get_all_track_metadata
|
from app.helpers import get_all_track_metadata
|
||||||
from app import ds, playlistmodel
|
from app import ds, playlistmodel
|
||||||
from app.models import (
|
from app.models import db
|
||||||
db,
|
|
||||||
Playlists,
|
|
||||||
Tracks,
|
|
||||||
)
|
|
||||||
from classes import (
|
from classes import (
|
||||||
TrackAndPlaylist,
|
TrackAndPlaylist,
|
||||||
)
|
)
|
||||||
@ -294,22 +290,3 @@ class TestMMMiscRowMove(unittest.TestCase):
|
|||||||
9,
|
9,
|
||||||
10,
|
10,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# # def test_edit_header(monkeypatch, session): # edit header row in middle of playlist
|
|
||||||
|
|
||||||
# # monkeypatch.setattr(playlistmodel, "Session", session)
|
|
||||||
# # note_text = "test text"
|
|
||||||
# # initial_row_count = 11
|
|
||||||
# # insert_row = 6
|
|
||||||
|
|
||||||
# # model = create_model_with_playlist_rows(session, initial_row_count)
|
|
||||||
# # model.insert_header_row(insert_row, note_text)
|
|
||||||
# # assert model.rowCount() == initial_row_count + 1
|
|
||||||
# # prd = model.playlist_rows[insert_row]
|
|
||||||
# # # Test against edit_role because display_role for headers is
|
|
||||||
# # # handled differently (sets up row span)
|
|
||||||
# # assert (
|
|
||||||
# # model.edit_role(model.rowCount(), playlistmodel.Col.NOTE.value, prd)
|
|
||||||
# # == note_text
|
|
||||||
# # )
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user