Warning, file /frameworks/kio/autotests/kurlrequestertest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     This file is part of the KDE Frameworks
0003     SPDX-FileCopyrightText: 2008, 2016 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include <KComboBox>
0009 #include <kdiroperator.h>
0010 #include <kfilewidget.h>
0011 #include <kurlrequester.h>
0012 
0013 #include <QLineEdit>
0014 #include <QSignalSpy>
0015 #include <QTemporaryFile>
0016 #include <QTest>
0017 
0018 /*
0019 IMPORTANT:
0020   Because this unittest interacts with the file dialog,
0021   remember to run it both with plugins/platformthemes/KDEPlasmaPlatformTheme.so (to use KFileWidget)
0022   and without it (to use the builtin QFileDialog code)
0023 */
0024 
0025 class KUrlRequesterTest : public QObject
0026 {
0027     Q_OBJECT
0028 private Q_SLOTS:
0029     void testUrlRequester();
0030     void testComboRequester();
0031     void testComboRequester_data();
0032 
0033 private:
0034     bool createTestFile(const QString &fileName)
0035     {
0036         QFile file(fileName);
0037         if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
0038             return false;
0039         }
0040         file.write("Hello world\n");
0041         return true;
0042     }
0043 };
0044 
0045 // Same as in kfiledialog_unittest.cpp
0046 static KFileWidget *findFileWidget()
0047 {
0048     QList<KFileWidget *> widgets;
0049     const QList<QWidget *> widgetsList = QApplication::topLevelWidgets();
0050     for (QWidget *widget : widgetsList) {
0051         KFileWidget *fw = widget->findChild<KFileWidget *>();
0052         if (fw) {
0053             widgets.append(fw);
0054         }
0055     }
0056     return (widgets.count() == 1) ? widgets.first() : nullptr;
0057 }
0058 
0059 void KUrlRequesterTest::testUrlRequester()
0060 {
0061     KUrlRequester req;
0062     req.setFileDialogModality(Qt::NonModal);
0063     const QString fileName = QStringLiteral("some_test_file");
0064     QVERIFY(createTestFile(fileName));
0065     QTemporaryFile tempFile;
0066     QVERIFY(tempFile.open());
0067     const QString filePath2 = tempFile.fileName();
0068     QVERIFY(QFile::exists(filePath2));
0069 
0070     // Set start dir
0071     const QUrl dirUrl = QUrl::fromLocalFile(QDir::currentPath());
0072     req.setStartDir(dirUrl);
0073     QCOMPARE(req.startDir().toString(), dirUrl.toString());
0074 
0075     // Click the button
0076     req.button()->click();
0077     QFileDialog *fileDialog = req.findChild<QFileDialog *>();
0078     QVERIFY(fileDialog);
0079 
0080     // Find out if we're using KFileDialog or QFileDialog
0081     KFileWidget *fw = findFileWidget();
0082 
0083     // Wait for directory listing
0084     if (fw) {
0085         QSignalSpy spy(fw->dirOperator(), &KDirOperator::finishedLoading);
0086         QVERIFY(spy.wait());
0087     }
0088 
0089     // Select file
0090     const QString filePath = dirUrl.toLocalFile() + '/' + fileName;
0091     fileDialog->selectFile(fileName);
0092 
0093     // Click OK, check URLRequester shows and returns selected file
0094     QKeyEvent keyPressEv(QKeyEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
0095     qApp->sendEvent(fw ? static_cast<QWidget *>(fw) : static_cast<QWidget *>(fileDialog), &keyPressEv);
0096     QCOMPARE(fileDialog->result(), static_cast<int>(QDialog::Accepted));
0097     QCOMPARE(fileDialog->selectedFiles(), QStringList{filePath});
0098     QCOMPARE(req.url().toLocalFile(), filePath);
0099 
0100     // Check there is no longer any file dialog visible
0101     QVERIFY(fileDialog->isHidden());
0102 
0103     // Click KUrlRequester button again. This time the filedialog is initialized with a file URL
0104     req.button()->click();
0105     fileDialog = req.findChild<QFileDialog *>();
0106     QVERIFY(fileDialog);
0107     fw = findFileWidget();
0108     if (fw) { // no need to wait for dir listing again, but we need it to be visible at least (for Key_Return to accept)
0109         // QVERIFY(QTest::qWaitForWindowExposed(fw->window())); // doesn't seem to be enough
0110         QTRY_VERIFY(fw->isVisible());
0111     }
0112 
0113     // Select file 2
0114     fileDialog->selectFile(filePath2);
0115 
0116     // Click OK, check URLRequester shows and returns selected file
0117     qApp->sendEvent(fw ? static_cast<QWidget *>(fw) : static_cast<QWidget *>(fileDialog), &keyPressEv);
0118     QCOMPARE(fileDialog->result(), static_cast<int>(QDialog::Accepted));
0119     QCOMPARE(fileDialog->selectedFiles(), QStringList{filePath2});
0120     QCOMPARE(req.url().toLocalFile(), filePath2);
0121 }
0122 
0123 void KUrlRequesterTest::testComboRequester()
0124 {
0125     QFETCH(bool, editable);
0126 
0127     KUrlComboRequester req;
0128     req.show();
0129 
0130     QList<QLineEdit *> lineEdits = req.findChildren<QLineEdit *>();
0131     QVERIFY(lineEdits.isEmpty()); // no lineedits, only a readonly combo
0132 
0133     QSignalSpy textSpy(&req, &KUrlComboRequester::textChanged);
0134     QSignalSpy editSpy(&req, &KUrlComboRequester::textEdited);
0135 
0136 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 80)
0137     QSignalSpy returnSpy(&req, qOverload<>(&KUrlComboRequester::returnPressed));
0138 #endif
0139     QSignalSpy returnWithTextSpy(&req, qOverload<const QString &>(&KUrlComboRequester::returnPressed));
0140 
0141     QVERIFY(!req.comboBox()->isEditable());
0142     if (editable) {
0143         req.comboBox()->setEditable(true);
0144 
0145         const auto text = QStringLiteral("foobar");
0146         QTest::keyClicks(req.comboBox(), text, Qt::NoModifier);
0147         QCOMPARE(textSpy.size(), text.size());
0148         QCOMPARE(editSpy.size(), text.size());
0149         QCOMPARE(textSpy.last().first().toString(), text);
0150         QCOMPARE(editSpy.last().first().toString(), text);
0151 
0152 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 80)
0153         QCOMPARE(returnSpy.size(), 0);
0154 #endif
0155         QCOMPARE(returnWithTextSpy.size(), 0);
0156 
0157         QTest::keyEvent(QTest::Click, req.comboBox(), Qt::Key_Return);
0158 
0159 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 80)
0160         QCOMPARE(returnSpy.size(), 1);
0161 #endif
0162         QCOMPARE(returnWithTextSpy.size(), 1);
0163         QCOMPARE(returnWithTextSpy.last().first().toString(), text);
0164     } else {
0165         const auto url1 = QUrl("file:///foo/bar/1");
0166         const auto url2 = QUrl("file:///foo/bar/2");
0167         req.comboBox()->addUrl(url1);
0168         QCOMPARE(textSpy.size(), 1);
0169         QCOMPARE(textSpy.last().first().toUrl(), url1);
0170 
0171         req.comboBox()->addUrl(url2);
0172         QCOMPARE(textSpy.size(), 1);
0173 
0174         QTest::keyEvent(QTest::Click, req.comboBox(), Qt::Key_Down);
0175         QCOMPARE(textSpy.size(), 2);
0176         QCOMPARE(textSpy.last().first().toUrl(), url2);
0177 
0178         // only editable combo boxes get the edit and return signals emitted
0179         QCOMPARE(editSpy.size(), 0);
0180 
0181 #if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 80)
0182         QCOMPARE(returnSpy.size(), 0);
0183 #endif
0184         QCOMPARE(returnWithTextSpy.size(), 0);
0185     }
0186 }
0187 
0188 void KUrlRequesterTest::testComboRequester_data()
0189 {
0190     QTest::addColumn<bool>("editable");
0191 
0192     QTest::newRow("read-only") << false;
0193     QTest::newRow("editable") << true;
0194 }
0195 
0196 QTEST_MAIN(KUrlRequesterTest)
0197 #include "kurlrequestertest.moc"