File indexing completed on 2024-06-23 10:37:21

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2009 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 <KConfigGroup>
0009 #include <KDirLister>
0010 #include <KSharedConfig>
0011 #include <QDir>
0012 #include <QSignalSpy>
0013 #include <QTest>
0014 #include <QTreeView>
0015 #include <kdiroperator.h>
0016 
0017 /**
0018  * Unit test for KDirOperator
0019  */
0020 class KDirOperatorTest : public QObject
0021 {
0022     Q_OBJECT
0023 private Q_SLOTS:
0024     void initTestCase()
0025     {
0026     }
0027 
0028     void cleanupTestCase()
0029     {
0030     }
0031 
0032     void testNoViewConfig()
0033     {
0034         KDirOperator dirOp;
0035 
0036         // setIconsZoom/setIconSize try to write config.
0037         // Make sure it won't crash if setViewConfig() isn't called.
0038 
0039 #if KIOFILEWIDGETS_BUILD_DEPRECATED_SINCE(5, 76)
0040         dirOp.setIconsZoom(40);
0041         QCOMPARE(dirOp.iconsZoom(), 40);
0042 #endif
0043 
0044         // Now the same for setIconSize
0045         dirOp.setIconSize(50);
0046         QCOMPARE(dirOp.iconSize(), 50);
0047     }
0048 
0049     void testReadConfig()
0050     {
0051         // Test: Make sure readConfig() and then setViewMode() restores
0052         // the correct kind of view.
0053         KDirOperator *dirOp = new KDirOperator;
0054         dirOp->setViewMode(KFile::DetailTree);
0055         dirOp->setShowHiddenFiles(true);
0056         KConfigGroup cg(KSharedConfig::openConfig(), "diroperator");
0057         dirOp->writeConfig(cg);
0058         delete dirOp;
0059 
0060         dirOp = new KDirOperator;
0061         dirOp->readConfig(cg);
0062         dirOp->setViewMode(KFile::Default);
0063         QVERIFY(dirOp->showHiddenFiles());
0064         // KDirOperatorDetail inherits QTreeView, so this test should work
0065         QVERIFY(qobject_cast<QTreeView *>(dirOp->view()));
0066         delete dirOp;
0067     }
0068 
0069     /**
0070      * testBug187066 does the following:
0071      *
0072      * 1. Open a KDirOperator in kdelibs/kfile
0073      * 2. Set the current item to "file:///"
0074      * 3. Set the current item to "file:///.../kdelibs/kfile/tests/kdiroperatortest.cpp"
0075      *
0076      * This may result in a crash, see https://bugs.kde.org/show_bug.cgi?id=187066
0077      */
0078 
0079     void testBug187066()
0080     {
0081         const QString dir = QFileInfo(QFINDTESTDATA("kdiroperatortest.cpp")).absolutePath();
0082         const QUrl kFileDirUrl(QUrl::fromLocalFile(dir).adjusted(QUrl::RemoveFilename));
0083 
0084         KDirOperator dirOp(kFileDirUrl);
0085         QSignalSpy completedSpy(dirOp.dirLister(), qOverload<>(&KCoreDirLister::completed));
0086         dirOp.setViewMode(KFile::DetailTree);
0087         completedSpy.wait(1000);
0088         dirOp.setCurrentItem(QUrl(QStringLiteral("file:///")));
0089         dirOp.setCurrentItem(QUrl::fromLocalFile(QFINDTESTDATA("kdiroperatortest.cpp")));
0090         // completedSpy.wait(1000);
0091         QTest::qWait(1000);
0092     }
0093 
0094     void testSetUrlPathAdjustment_data()
0095     {
0096         QTest::addColumn<QUrl>("url");
0097         QTest::addColumn<QUrl>("expectedUrl");
0098 
0099         QTest::newRow("with_host") << QUrl(QStringLiteral("ftp://foo.com/folder")) << QUrl(QStringLiteral("ftp://foo.com/folder/"));
0100         QTest::newRow("with_no_host") << QUrl(QStringLiteral("smb://")) << QUrl(QStringLiteral("smb://"));
0101         QTest::newRow("with_host_without_path") << QUrl(QStringLiteral("ftp://user@example.com")) << QUrl(QStringLiteral("ftp://user@example.com"));
0102         QTest::newRow("with_trailing_slashs") << QUrl::fromLocalFile(QDir::tempPath() + QLatin1String("////////"))
0103                                               << QUrl::fromLocalFile(QDir::tempPath() + QLatin1Char('/'));
0104     }
0105 
0106     void testSetUrlPathAdjustment()
0107     {
0108         QFETCH(QUrl, url);
0109         QFETCH(QUrl, expectedUrl);
0110 
0111         KDirOperator dirOp;
0112         QSignalSpy spy(&dirOp, &KDirOperator::urlEntered);
0113         dirOp.setUrl(url, true);
0114         QCOMPARE(spy.takeFirst().at(0).toUrl(), expectedUrl);
0115     }
0116 
0117     void testSupportedSchemes()
0118     {
0119         KDirOperator dirOp;
0120         QSignalSpy spy(&dirOp, &KDirOperator::urlEntered);
0121         QCOMPARE(dirOp.supportedSchemes(), QStringList());
0122         dirOp.setSupportedSchemes({"file"});
0123         QCOMPARE(dirOp.supportedSchemes(), QStringList("file"));
0124         dirOp.setUrl(QUrl("smb://foo/bar"), true);
0125         QCOMPARE(spy.count(), 0);
0126         const auto fileUrl = QUrl::fromLocalFile(QDir::homePath() + QLatin1Char('/'));
0127         dirOp.setUrl(fileUrl, true);
0128         QCOMPARE(spy.count(), 1);
0129         QCOMPARE(spy.first().at(0).toUrl(), fileUrl);
0130     }
0131 
0132     void testEnabledDirHighlighting()
0133     {
0134         const QString path = QFileInfo(QFINDTESTDATA("kdiroperatortest.cpp")).absolutePath() + QLatin1Char('/');
0135         // <src dir>/autotests/
0136         const QUrl dirC = QUrl::fromLocalFile(path);
0137         const QUrl dirB = dirC.resolved(QUrl(QStringLiteral("..")));
0138         const QUrl dirA = dirB.resolved(QUrl(QStringLiteral("..")));
0139 
0140         KDirOperator dirOp(dirC);
0141 
0142         dirOp.show();
0143         dirOp.activateWindow();
0144         QVERIFY(QTest::qWaitForWindowActive(&dirOp));
0145 
0146         dirOp.setViewMode(KFile::Default);
0147 
0148         // first case, go up...
0149         dirOp.cdUp();
0150         QCOMPARE(dirOp.url(), dirB);
0151 
0152         // the selection will happen after the dirLister has completed listing
0153         QTRY_VERIFY(!dirOp.selectedItems().isEmpty());
0154         QCOMPARE(dirOp.selectedItems().at(0).url(), dirC.adjusted(QUrl::StripTrailingSlash));
0155 
0156         // same as above
0157         dirOp.cdUp();
0158         QCOMPARE(dirOp.url(), dirA);
0159 
0160         QTRY_VERIFY(!dirOp.selectedItems().isEmpty());
0161         QCOMPARE(dirOp.selectedItems().at(0).url(), dirB.adjusted(QUrl::StripTrailingSlash));
0162 
0163         // we were in A/B/C, went up twice, now in A/
0164         // going back, we are in B/ and C/ is highlighted
0165         dirOp.back();
0166         QCOMPARE(dirOp.url(), dirB);
0167 
0168         QTRY_VERIFY(!dirOp.selectedItems().isEmpty());
0169         QCOMPARE(dirOp.selectedItems().at(0).url(), dirC.adjusted(QUrl::StripTrailingSlash));
0170 
0171         dirOp.clearHistory();
0172         // we start in A/
0173         dirOp.setUrl(dirA, true);
0174         QCOMPARE(dirOp.url(), dirA);
0175         // go to B/
0176         dirOp.setUrl(dirB, true);
0177         QCOMPARE(dirOp.url(), dirB);
0178         // go to C/
0179         dirOp.setUrl(dirC, true);
0180         QCOMPARE(dirOp.url(), dirC);
0181 
0182         // go back, C/ is highlighted
0183         dirOp.back();
0184         QCOMPARE(dirOp.url(), dirB);
0185 
0186         QTRY_VERIFY(!dirOp.selectedItems().isEmpty());
0187         QCOMPARE(dirOp.selectedItems().at(0).url(), dirC.adjusted(QUrl::StripTrailingSlash));
0188 
0189         // go back, B/ is highlighted
0190         dirOp.back();
0191         QCOMPARE(dirOp.url(), dirA);
0192 
0193         QTRY_VERIFY(!dirOp.selectedItems().isEmpty());
0194         QCOMPARE(dirOp.selectedItems().at(0).url(), dirB.adjusted(QUrl::StripTrailingSlash));
0195     }
0196 
0197     void testDisabledDirHighlighting()
0198     {
0199         const QString path = QFileInfo(QFINDTESTDATA("kdiroperatortest.cpp")).absolutePath() + QLatin1Char('/');
0200         // <src dir>/autotests/
0201         const QUrl dirC = QUrl::fromLocalFile(path);
0202         const QUrl dirB = dirC.resolved(QUrl(QStringLiteral("..")));
0203         const QUrl dirA = dirB.resolved(QUrl(QStringLiteral("..")));
0204 
0205         KDirOperator dirOp(dirC);
0206         dirOp.setEnableDirHighlighting(false);
0207 
0208         dirOp.show();
0209         dirOp.activateWindow();
0210         QVERIFY(QTest::qWaitForWindowActive(&dirOp));
0211 
0212         dirOp.setViewMode(KFile::Default);
0213 
0214         // finishedLoading is emitted when the dirLister emits the completed signal
0215         QSignalSpy finishedSpy(&dirOp, &KDirOperator::finishedLoading);
0216         // first case, go up...
0217         dirOp.cdUp();
0218         QCOMPARE(dirOp.url(), dirB);
0219 
0220         QVERIFY(finishedSpy.wait(1000));
0221         // ... no items highlighted
0222         QVERIFY(dirOp.selectedItems().isEmpty());
0223 
0224         // same as above
0225         dirOp.cdUp();
0226         QCOMPARE(dirOp.url(), dirA);
0227 
0228         QVERIFY(finishedSpy.wait(1000));
0229         QVERIFY(dirOp.selectedItems().isEmpty());
0230 
0231         // we were in A/B/C, went up twice, now in A/
0232         dirOp.back();
0233         QCOMPARE(dirOp.url(), dirB);
0234 
0235         QVERIFY(finishedSpy.wait(1000));
0236         QVERIFY(dirOp.selectedItems().isEmpty());
0237 
0238         dirOp.clearHistory();
0239         // we start in A/
0240         dirOp.setUrl(dirA, true);
0241         QCOMPARE(dirOp.url(), dirA);
0242         // go to B/
0243         dirOp.setUrl(dirB, true);
0244         QCOMPARE(dirOp.url(), dirB);
0245         // go to C/
0246         dirOp.setUrl(dirC, true);
0247         QCOMPARE(dirOp.url(), dirC);
0248 
0249         dirOp.back();
0250         QCOMPARE(dirOp.url(), dirB);
0251 
0252         QVERIFY(finishedSpy.wait(1000));
0253         QVERIFY(dirOp.selectedItems().isEmpty());
0254 
0255         dirOp.back();
0256         QCOMPARE(dirOp.url(), dirA);
0257 
0258         QVERIFY(finishedSpy.wait(1000));
0259         QVERIFY(dirOp.selectedItems().isEmpty());
0260     }
0261 
0262     /**
0263      * If one copies the location of a file and then paste that into the location bar,
0264      * the directory browser should show the directory of the file instead of showing an error.
0265      * @see https://bugs.kde.org/459900
0266      */
0267     void test_bug459900()
0268     {
0269         KDirOperator dirOp;
0270         QSignalSpy urlEnteredSpy(&dirOp, &KDirOperator::urlEntered);
0271         // Try to open a file
0272         const QString filePath = QFINDTESTDATA("servicemenu_protocol_mime_test_data/kio/servicemenus/mimetype_dir.desktop");
0273         dirOp.setUrl(QUrl::fromLocalFile(filePath), true);
0274         // Should accept the file and use its parent directory
0275         QCOMPARE(urlEnteredSpy.size(), 1);
0276         const QUrl fileUrl = QUrl::fromLocalFile(QFileInfo(filePath).absolutePath());
0277         QCOMPARE(urlEnteredSpy.takeFirst().at(0).toUrl().adjusted(QUrl::StripTrailingSlash), fileUrl);
0278         // Even in the same directory, KDirOperator should update the text in pathCombo
0279         dirOp.setUrl(QUrl::fromLocalFile(filePath), true);
0280         QCOMPARE(urlEnteredSpy.size(), 1);
0281         QCOMPARE(urlEnteredSpy.takeFirst().at(0).toUrl().adjusted(QUrl::StripTrailingSlash), fileUrl.adjusted(QUrl::StripTrailingSlash));
0282     }
0283 };
0284 
0285 QTEST_MAIN(KDirOperatorTest)
0286 
0287 #include "kdiroperatortest.moc"