From 89efc8bc7fbda0aac03b98e81d2e154d098f9877 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Wed, 24 Jul 2024 23:11:26 -0400 Subject: [PATCH] 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]`. --- CMakeLists.txt | 3 + tests/CMakeLists.txt | 4 + tests/notificationtest/CMakeLists.txt | 26 ++++ tests/notificationtest/main.cpp | 78 ++++++++++ .../plasma_mobile_notificationtest.notifyrc | 11 ++ tests/notificationtest/tests.cpp | 147 ++++++++++++++++++ tests/notificationtest/tests.h | 114 ++++++++++++++ tests/notificationtest/utils.h | 12 ++ 8 files changed, 395 insertions(+) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/notificationtest/CMakeLists.txt create mode 100644 tests/notificationtest/main.cpp create mode 100644 tests/notificationtest/plasma_mobile_notificationtest.notifyrc create mode 100644 tests/notificationtest/tests.cpp create mode 100644 tests/notificationtest/tests.h create mode 100644 tests/notificationtest/utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6186dd47..478aaa3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000..33e66600 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: 2024 Devin Lin +# SPDX-License-Identifier: GPL-2.0-or-later + +add_subdirectory(notificationtest) \ No newline at end of file diff --git a/tests/notificationtest/CMakeLists.txt b/tests/notificationtest/CMakeLists.txt new file mode 100644 index 00000000..a687ce15 --- /dev/null +++ b/tests/notificationtest/CMakeLists.txt @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2024 Devin Lin +# 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}) diff --git a/tests/notificationtest/main.cpp b/tests/notificationtest/main.cpp new file mode 100644 index 00000000..3c1c017a --- /dev/null +++ b/tests/notificationtest/main.cpp @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: 2024 Devin Lin +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include + +#include + +#include "tests.h" +#include "utils.h" +#include "version.h" + +using namespace Qt::Literals::StringLiterals; + +std::unique_ptr createParser() +{ + auto parser = std::make_unique(); + 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> notificationTests; + notificationTests.push_back(std::make_unique()); + notificationTests.push_back(std::make_unique()); + notificationTests.push_back(std::make_unique()); + notificationTests.push_back(std::make_unique()); + notificationTests.push_back(std::make_unique()); + notificationTests.push_back(std::make_unique()); + notificationTests.push_back(std::make_unique()); + + if (parser->isSet(u"list"_s)) { + for (auto ¬ification : 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 ¬ification : 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(); +} diff --git a/tests/notificationtest/plasma_mobile_notificationtest.notifyrc b/tests/notificationtest/plasma_mobile_notificationtest.notifyrc new file mode 100644 index 00000000..11b29ade --- /dev/null +++ b/tests/notificationtest/plasma_mobile_notificationtest.notifyrc @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2024 Devin Lin +# 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 diff --git a/tests/notificationtest/tests.cpp b/tests/notificationtest/tests.cpp new file mode 100644 index 00000000..3de1ec63 --- /dev/null +++ b/tests/notificationtest/tests.cpp @@ -0,0 +1,147 @@ +// SPDX-FileCopyrightText: 2024 Devin Lin +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include + +#include + +#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("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(); +} \ No newline at end of file diff --git a/tests/notificationtest/tests.h b/tests/notificationtest/tests.h new file mode 100644 index 00000000..27dff644 --- /dev/null +++ b/tests/notificationtest/tests.h @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: 2024 Devin Lin +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include + +#include + +#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; +}; diff --git a/tests/notificationtest/utils.h b/tests/notificationtest/utils.h new file mode 100644 index 00000000..e29262d2 --- /dev/null +++ b/tests/notificationtest/utils.h @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2024 Devin Lin +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +static const QLoggingCategory &LOGGING_CATEGORY() +{ + static const QLoggingCategory category("plasma-mobile-notificationtest"); + return category; +}