/* SPDX-FileCopyrightText: 2023 Fushan Wen SPDX-License-Identifier: GPL-2.0-or-later */ #define QT_FORCE_ASSERTS 1 #include #include #include #include #include #include #include "mprisinterface.h" namespace { template T evaluate(QObject *scope, const QString &expression) { QQmlExpression expr(qmlContext(scope), scope, expression); QVariant result = expr.evaluate(); if (expr.hasError()) { qWarning() << expr.error().toString(); } return result.value(); } bool initView(QQuickView *view, const QString &urlStr) { view->setSource(QUrl(urlStr)); QSignalSpy statusSpy(view, &QQuickView::statusChanged); if (view->status() == QQuickView::Loading) { statusSpy.wait(); } else if (view->status() != QQuickView::Ready) { qCritical() << "Not loading" << view->errors(); return false; } if (view->status() != QQuickView::Ready) { qCritical() << view->errors(); return false; } return true; } } class MprisDeclarativeTest : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); /** * Loads Mpris2Model in QML, and tests a few functions */ void test_Mpris2Model(); /** * Loads MultiplexerModel in QML */ void test_MultiplexerModel(); private: QProcess *m_playerProcess = MprisInterface::startPlayer(this); }; void MprisDeclarativeTest::cleanupTestCase() { MprisInterface::stopPlayer(m_playerProcess); } void MprisDeclarativeTest::test_Mpris2Model() { auto view = std::make_unique(); QByteArray errorMessage; QVERIFY(initView(view.get(), QFINDTESTDATA(QStringLiteral("data/tst_Mpris2Model.qml")))); QQuickItem *rootObject = view->rootObject(); QSignalSpy countSpy(rootObject, SIGNAL(countChanged())); bool ok = false; int count = rootObject->property("count").toInt(&ok); QVERIFY(ok); if (count == 0) { QVERIFY(countSpy.wait()); } QCOMPARE(evaluate(rootObject, QStringLiteral("count")), 1); auto currentPlayer = evaluate(rootObject, QLatin1String("mpris.currentPlayer")); QVERIFY(currentPlayer); auto currentIndex = evaluate(rootObject, QLatin1String("mpris.currentIndex")); QCOMPARE(currentIndex, 0u); // Mpris2Model::playerForLauncherUrl auto playerContainerFromPid = evaluate( rootObject, QLatin1String("mpris.playerForLauncherUrl(\"applications:invalidlauncherurl.desktop\", %1)").arg(QString::number(m_playerProcess->processId()))); QCOMPARE(currentPlayer, playerContainerFromPid); auto playerContainerFromLauncherUrl = evaluate(rootObject, QLatin1String("mpris.playerForLauncherUrl(\"applications:audacious.desktop\", 0)")); QCOMPARE(currentPlayer, playerContainerFromLauncherUrl); // Make sure it's a real player container, and make sure PlayerContainer is registered QCOMPARE(evaluate(rootObject, QStringLiteral("mpris.currentPlayer.identity")), QStringLiteral("Audacious")); // Make sure an unrelated launcher doesn't have any associated player container. // This checks the `pid > 0` condition when matching KDEPidRole auto launcherShouldNotHavePlayerContainer = evaluate(rootObject, QLatin1String("mpris.playerForLauncherUrl(\"applications:dolphin.desktop\", 0)")); QVERIFY(!launcherShouldNotHavePlayerContainer); } void MprisDeclarativeTest::test_MultiplexerModel() { auto view = std::make_unique(); QByteArray errorMessage; QVERIFY(initView(view.get(), QFINDTESTDATA(QStringLiteral("data/tst_MultiplexerModel.qml")))); QQuickItem *rootObject = view->rootObject(); QSignalSpy countSpy(rootObject, SIGNAL(countChanged())); bool ok = false; int count = rootObject->property("count").toInt(&ok); QVERIFY(ok); if (count == 0) { QVERIFY(countSpy.wait()); } QCOMPARE(evaluate(rootObject, QStringLiteral("count")), 1); QCOMPARE(evaluate(rootObject, QStringLiteral("modelData.identity")), QStringLiteral("Choose player automatically")); } QTEST_MAIN(MprisDeclarativeTest) #include "mprisdeclarativetest.moc"