1 /*
2     SPDX-FileCopyrightText: 2002 David Faure <faure@kde.org>
3     SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.0-only
6 */
7 
8 #include "kruntest.h"
9 
10 #include <KIO/ApplicationLauncherJob>
11 #include <KIO/JobUiDelegate>
12 #include <KIO/OpenUrlJob>
13 
14 #include <KService>
15 #include <QApplication>
16 #include <QDebug>
17 #include <QLabel>
18 #include <QLayout>
19 #include <QPushButton>
20 #include <QTest> // QFINDTESTDATA
21 
22 #include <QDir>
23 #include <qplatformdefs.h>
24 
25 static const int s_maxJobs = 100;
26 
27 static KIO::OpenUrlJob *jobArray[s_maxJobs];
28 
29 static const char testFile[] = "kruntest.cpp";
30 
31 static const struct {
32     const char *text;
33     const char *expectedResult;
34     const char *exec;
35     const char *url;
36 } s_tests[] = {
37     {"run(kwrite, no url)", "should work normally", "kwrite", nullptr},
38     {"run(kwrite, file url)", "should work normally", "kwrite", testFile},
39     {"run(kwrite, remote url)", "should work normally", "kwrite", "http://www.kde.org"},
40     {"run(doesnotexit, no url)", "should show error message", "doesnotexist", nullptr},
41     {"run(doesnotexit, file url)", "should show error message", "doesnotexist", testFile},
42     {"run(doesnotexit, remote url)", "should use kioexec and show error message", "doesnotexist", "http://www.kde.org"},
43     {"run(not-executable-desktopfile)", "should ask for confirmation", "nonexec", nullptr},
44     {"run(missing lib, no url)",
45      "should show error message (remove libqca-qt5.so.2 for this, e.g. by editing LD_LIBRARY_PATH if qca is in its own prefix)",
46      "qcatool-qt5",
47      nullptr},
48     {"run(missing lib, file url)",
49      "should show error message (remove libqca-qt5.so.2 for this, e.g. by editing LD_LIBRARY_PATH if qca is in its own prefix)",
50      "qcatool-qt5",
51      testFile},
52     {"run(missing lib, remote url)",
53      "should show error message (remove libqca-qt5.so.2 for this, e.g. by editing LD_LIBRARY_PATH if qca is in its own prefix)",
54      "qcatool-qt5",
55      "http://www.kde.org"},
56 };
57 
Receiver()58 Receiver::Receiver()
59 {
60     QVBoxLayout *lay = new QVBoxLayout(this);
61     QPushButton *btn = new QPushButton(QStringLiteral("Press here to terminate"), this);
62     lay->addWidget(btn);
63     connect(btn, &QPushButton::clicked, qApp, &QApplication::quit);
64 
65     start = new QPushButton(QStringLiteral("Launch OpenUrlJobs"), this);
66     lay->addWidget(start);
67     connect(start, &QAbstractButton::clicked, this, &Receiver::slotStart);
68 
69     stop = new QPushButton(QStringLiteral("Stop those OpenUrlJobs"), this);
70     stop->setEnabled(false);
71     lay->addWidget(stop);
72     connect(stop, &QAbstractButton::clicked, this, &Receiver::slotStop);
73 
74     QPushButton *launchOne = new QPushButton(QStringLiteral("Launch one http OpenUrlJob"), this);
75     lay->addWidget(launchOne);
76     connect(launchOne, &QAbstractButton::clicked, this, &Receiver::slotLaunchOne);
77 
78     for (uint i = 0; i < sizeof(s_tests) / sizeof(*s_tests); ++i) {
79         QHBoxLayout *hbox = new QHBoxLayout;
80         lay->addLayout(hbox);
81         QPushButton *button = new QPushButton(s_tests[i].text, this);
82         button->setProperty("testNumber", i);
83         hbox->addWidget(button);
84         QLabel *label = new QLabel(s_tests[i].expectedResult, this);
85         hbox->addWidget(label);
86         connect(button, &QAbstractButton::clicked, this, [this, button]() {
87             slotLaunchTest(button);
88         });
89         hbox->addStretch();
90     }
91 
92     adjustSize();
93     show();
94 }
95 
slotLaunchTest(QPushButton * sender)96 void Receiver::slotLaunchTest(QPushButton *sender)
97 {
98     const int testNumber = sender->property("testNumber").toInt();
99     QList<QUrl> urls;
100     if (s_tests[testNumber].url) {
101         QString urlStr(s_tests[testNumber].url);
102         if (urlStr == QLatin1String(testFile)) {
103             urlStr = QFINDTESTDATA(testFile);
104         }
105         urls << QUrl::fromUserInput(urlStr);
106     }
107     KService::Ptr service;
108     if (QByteArray(s_tests[testNumber].exec) == "nonexec") {
109         const QString desktopFile = QFINDTESTDATA("../src/ioslaves/trash/kcmtrash.desktop");
110         if (desktopFile.isEmpty()) {
111             qWarning() << "kcmtrash.desktop not found!";
112         }
113         const QString dest = QStringLiteral("kcmtrash.desktop");
114         QFile::remove(dest);
115         bool ok = QFile::copy(desktopFile, dest);
116         if (!ok) {
117             qWarning() << "Failed to copy" << desktopFile << "to" << dest;
118         }
119         service = KService::Ptr(new KService(QDir::currentPath() + QLatin1Char('/') + dest));
120     } else {
121         service = KService::Ptr(new KService("Some Name", s_tests[testNumber].exec, QString()));
122     }
123     auto *job = new KIO::ApplicationLauncherJob(service, this);
124     job->setUrls(urls);
125     job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
126     job->start();
127 }
128 
slotStop()129 void Receiver::slotStop()
130 {
131     for (int i = 0; i < s_maxJobs; i++) {
132         qDebug() << "deleting job" << i;
133         delete jobArray[i];
134     }
135     start->setEnabled(true);
136     stop->setEnabled(false);
137 }
138 
slotStart()139 void Receiver::slotStart()
140 {
141     for (int i = 0; i < s_maxJobs; i++) {
142         qDebug() << "creating testjob" << i;
143         jobArray[i] = new KIO::OpenUrlJob(QUrl::fromLocalFile(QDir::tempPath()));
144         jobArray[i]->setAutoDelete(false);
145         jobArray[i]->start();
146     }
147     start->setEnabled(false);
148     stop->setEnabled(true);
149 }
150 
slotLaunchOne()151 void Receiver::slotLaunchOne()
152 {
153     auto *job = new KIO::OpenUrlJob(QUrl(QStringLiteral("http://www.kde.org")));
154     job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
155     job->start();
156 }
157 
main(int argc,char ** argv)158 int main(int argc, char **argv)
159 {
160     QApplication::setApplicationName(QStringLiteral("kruntest"));
161     QApplication app(argc, argv);
162 
163     Receiver receiver;
164     return app.exec();
165 }
166