tests: Add plasma-mobile-notificationtest binary

This will make it easier to test all sorts of notifications with our notification widget. Just run `plasma-mobile-notificationtest [test-name]`.
This commit is contained in:
Devin Lin 2024-07-24 23:11:26 -04:00
parent b1d75495e2
commit 89efc8bc7f
8 changed files with 395 additions and 0 deletions

View file

@ -118,6 +118,9 @@ add_subdirectory(kwin)
add_subdirectory(envmanager)
add_subdirectory(initialstart)
add_subdirectory(layout-templates)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
find_program(PlasmaOpenSettings plasma-open-settings)
set_package_properties(PlasmaOpenSettings PROPERTIES

4
tests/CMakeLists.txt Normal file
View file

@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
add_subdirectory(notificationtest)

View file

@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
set(plasma-mobile-notificationtest_SRCS
main.cpp
tests.cpp
utils.h
)
add_executable(plasma-mobile-notificationtest ${plasma-mobile-notificationtest_SRCS} ${RESOURCES})
target_link_libraries(plasma-mobile-notificationtest
Qt::Qml
Qt::Gui
Qt::Widgets
Qt::Quick
KF6::I18n
KF6::ConfigCore
KF6::CoreAddons
KF6::DBusAddons
KF6::Notifications
KF6::JobWidgets
)
target_include_directories(plasma-mobile-notificationtest PRIVATE ${CMAKE_BINARY_DIR})
install(TARGETS plasma-mobile-notificationtest ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES plasma_mobile_notificationtest.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})

View file

@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QIcon>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QString>
#include <KAboutData>
#include "tests.h"
#include "utils.h"
#include "version.h"
using namespace Qt::Literals::StringLiterals;
std::unique_ptr<QCommandLineParser> createParser()
{
auto parser = std::make_unique<QCommandLineParser>();
parser->addOption(QCommandLineOption(u"list"_s, u"Lists the possible test notifications that can be set."_s));
parser->addVersionOption();
parser->addHelpOption();
parser->addPositionalArgument("test", "The test notification to send.");
return parser;
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
auto parser = createParser();
parser->process(app);
QCoreApplication::setApplicationName(u"plasma-mobile-notificationtest"_s);
QCoreApplication::setApplicationVersion(QStringLiteral(PLASMA_MOBILE_VERSION_STRING));
QCoreApplication::setOrganizationDomain(u"kde.org"_s);
std::vector<std::unique_ptr<NotificationTest>> notificationTests;
notificationTests.push_back(std::make_unique<BasicNotificationTest>());
notificationTests.push_back(std::make_unique<UrlNotificationTest>());
notificationTests.push_back(std::make_unique<ReplyNotificationTest>());
notificationTests.push_back(std::make_unique<LowUrgencyNotificationTest>());
notificationTests.push_back(std::make_unique<HighUrgencyNotificationTest>());
notificationTests.push_back(std::make_unique<CriticalUrgencyNotificationTest>());
notificationTests.push_back(std::make_unique<JobNotificationTest>());
if (parser->isSet(u"list"_s)) {
for (auto &notification : notificationTests) {
qInfo() << notification->name();
}
return 0;
} else if (parser->positionalArguments().size() == 0) {
parser->showHelp();
return 0;
}
const auto args = parser->positionalArguments();
const QString name = args[0];
bool found = false;
for (auto &notification : notificationTests) {
if (notification->name() == name) {
qInfo() << "Sending notification" << notification->name();
notification->sendNotification(app);
found = true;
break;
}
}
if (!found) {
qInfo() << "Test not found.";
return 0;
}
return app.exec();
}

View file

@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
[Global]
IconName=notifications
Name=Notification Test
[Event/notificationTest]
Name=Notification Test
Comment=A test notification
Action=Popup

View file

@ -0,0 +1,147 @@
// SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include <KJob>
#include <KNotification>
#include <KNotificationJobUiDelegate>
#include <KNotificationReplyAction>
#include <KUiServerV2JobTracker>
#include <stdlib.h>
#include "tests.h"
NotificationTest::NotificationTest(QObject *parent)
: QObject{parent}
{
}
void BasicNotificationTest::sendNotification(QCoreApplication &app)
{
KNotification *notification = new KNotification(QStringLiteral("notificationTest"));
notification->setComponentName(QStringLiteral("plasma_mobile_notificationtest"));
notification->setIconName(QStringLiteral("notification-active"));
notification->setText("This is a test notification!");
auto action = notification->addAction("Action!");
Q_UNUSED(action);
connect(notification, &KNotification::closed, &app, QCoreApplication::quit);
notification->sendEvent();
}
void UrlNotificationTest::sendNotification(QCoreApplication &app)
{
KNotification *notification = new KNotification(QStringLiteral("notificationTest"));
notification->setComponentName(QStringLiteral("plasma_mobile_notificationtest"));
notification->setTitle("Web link");
notification->setText("I like links!");
notification->setUrls({QUrl{"file:/usr/share/wallpapers/Next/contents/images/1920x1080.png"}});
connect(notification, &KNotification::closed, &app, QCoreApplication::quit);
notification->sendEvent();
}
void ReplyNotificationTest::sendNotification(QCoreApplication &app)
{
KNotification *notification = new KNotification(QStringLiteral("notificationTest"));
notification->setComponentName(QStringLiteral("plasma_mobile_notificationtest"));
notification->setIconName(QStringLiteral("avatar-default-symbolic"));
notification->setTitle("John");
notification->setText("This is great news! Let's meet up tomorrow!");
auto replyAction = std::make_unique<KNotificationReplyAction>("Reply");
replyAction->setPlaceholderText("Reply to John...");
QObject::connect(replyAction.get(), &KNotificationReplyAction::replied, [](const QString &text) {
qDebug() << "you replied with" << text;
});
notification->setReplyAction(std::move(replyAction));
connect(notification, &KNotification::closed, &app, QCoreApplication::quit);
notification->sendEvent();
}
void LowUrgencyNotificationTest::sendNotification(QCoreApplication &app)
{
KNotification *notification = new KNotification(QStringLiteral("notificationTest"));
notification->setComponentName(QStringLiteral("plasma_mobile_notificationtest"));
notification->setIconName(QStringLiteral("notification-inactive"));
notification->setTitle("Low Urgency Notification");
notification->setText("This is not very important...");
notification->setUrgency(KNotification::CriticalUrgency);
connect(notification, &KNotification::closed, &app, QCoreApplication::quit);
notification->sendEvent();
}
void HighUrgencyNotificationTest::sendNotification(QCoreApplication &app)
{
KNotification *notification = new KNotification(QStringLiteral("notificationTest"));
notification->setComponentName(QStringLiteral("plasma_mobile_notificationtest"));
notification->setIconName(QStringLiteral("notification-active"));
notification->setTitle("Urgent Notification");
notification->setText("This is very urgent! AAAAAA");
notification->setUrgency(KNotification::CriticalUrgency);
connect(notification, &KNotification::closed, &app, QCoreApplication::quit);
notification->sendEvent();
}
void CriticalUrgencyNotificationTest::sendNotification(QCoreApplication &app)
{
KNotification *notification = new KNotification(QStringLiteral("notificationTest"));
notification->setComponentName(QStringLiteral("plasma_mobile_notificationtest"));
notification->setIconName(QStringLiteral("notification-active"));
notification->setTitle("Critically Urgent Notification");
notification->setText("This is very urgent! AAAAAA");
notification->setUrgency(KNotification::CriticalUrgency);
auto action = notification->addAction("Action!");
Q_UNUSED(action);
connect(notification, &KNotification::closed, &app, QCoreApplication::quit);
notification->sendEvent();
}
FakeJob::FakeJob(QObject *parent)
: KJob{parent}
, m_timer{new QTimer{this}}
{
setTotalAmount(KJob::Bytes, 100);
setProcessedAmount(KJob::Bytes, 0);
connect(m_timer, &QTimer::timeout, this, &FakeJob::timerFinished);
}
void FakeJob::start()
{
setProcessedAmount(KJob::Bytes, 0);
m_timer->start(1000);
QString s_title = "Processing";
QString s_source = "Source";
QString s_destination = "Destination";
Q_EMIT description(this, s_title, {s_source, QStringLiteral("data:[...]")}, {s_destination, QStringLiteral("data:[...]")});
setFinishedNotificationHidden();
}
void FakeJob::timerFinished()
{
if (processedAmount(KJob::Bytes) + 10 < 100) {
setProcessedAmount(KJob::Bytes, processedAmount(KJob::Bytes) + 10);
emitSpeed(rand() % 100);
} else {
setProcessedAmount(KJob::Bytes, 100);
emitResult();
}
}
void JobNotificationTest::sendNotification(QCoreApplication &app)
{
KUiServerV2JobTracker *jobTracker = new KUiServerV2JobTracker{};
KJob *job = new FakeJob{this};
job->setProperty("immediateProgressReporting", true);
job->setProperty("desktopFileName", "org.kde.plasmashell");
connect(job, &KJob::finished, &app, QCoreApplication::quit);
jobTracker->registerJob(job);
job->start();
}

View file

@ -0,0 +1,114 @@
// SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include <QCoreApplication>
#include <QObject>
#include <QString>
#include <QTimer>
#include <KJob>
#pragma once
class NotificationTest : public QObject
{
Q_OBJECT
public:
explicit NotificationTest(QObject *parent = nullptr);
virtual ~NotificationTest() = default;
virtual QString name() const = 0;
virtual void sendNotification(QCoreApplication &app) = 0;
};
class BasicNotificationTest : public NotificationTest
{
Q_OBJECT
public:
QString name() const override
{
return QStringLiteral("basic");
}
void sendNotification(QCoreApplication &app) override;
};
class UrlNotificationTest : public NotificationTest
{
Q_OBJECT
public:
QString name() const override
{
return QStringLiteral("url");
}
void sendNotification(QCoreApplication &app) override;
};
class ReplyNotificationTest : public NotificationTest
{
Q_OBJECT
public:
QString name() const override
{
return QStringLiteral("reply");
}
void sendNotification(QCoreApplication &app) override;
};
class LowUrgencyNotificationTest : public NotificationTest
{
Q_OBJECT
public:
QString name() const override
{
return QStringLiteral("lowUrgency");
}
void sendNotification(QCoreApplication &app) override;
};
class HighUrgencyNotificationTest : public NotificationTest
{
Q_OBJECT
public:
QString name() const override
{
return QStringLiteral("highUrgency");
}
void sendNotification(QCoreApplication &app) override;
};
class CriticalUrgencyNotificationTest : public NotificationTest
{
Q_OBJECT
public:
QString name() const override
{
return QStringLiteral("criticalUrgency");
}
void sendNotification(QCoreApplication &app) override;
};
class FakeJob : public KJob
{
Q_OBJECT
public:
explicit FakeJob(QObject *parent = nullptr);
virtual void start() override;
private Q_SLOTS:
void timerFinished();
private:
double m_progress{0};
QTimer *m_timer{nullptr};
};
class JobNotificationTest : public NotificationTest
{
Q_OBJECT
public:
QString name() const override
{
return QStringLiteral("job");
}
void sendNotification(QCoreApplication &app) override;
};

View file

@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2024 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QLoggingCategory>
static const QLoggingCategory &LOGGING_CATEGORY()
{
static const QLoggingCategory category("plasma-mobile-notificationtest");
return category;
}