File indexing completed on 2024-04-21 03:54:51

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