File indexing completed on 2025-01-19 12:48:34
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"