File indexing completed on 2024-05-12 05:46:43
0001 /* This file is part of the KDE project 0002 Copyright (C) 2014 David Faure <faure@kde.org> 0003 0004 This library is free software; you can redistribute it and/or modify 0005 it under the terms of the GNU Lesser General Public License as published by 0006 the Free Software Foundation; either version 2 of the License or ( at 0007 your option ) version 3 or, at the discretion of KDE e.V. ( which shall 0008 act as a proxy as in section 14 of the GPLv3 ), any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Lesser General Public License for more details. 0014 0015 You should have received a copy of the GNU Lesser General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include <qtest.h> 0022 #include <QSignalSpy> 0023 #include <QMenu> 0024 #include <QTemporaryDir> 0025 0026 #include <KConfigGroup> 0027 #include <KSharedConfig> 0028 #include <KFileCopyToMenu> 0029 #include "kiotesthelper.h" 0030 #include "jobuidelegatefactory.h" 0031 0032 #include <KIO/CopyJob> 0033 0034 class KFileCopyToMenuTest : public QObject 0035 { 0036 Q_OBJECT 0037 0038 private Q_SLOTS: 0039 void initTestCase() 0040 { 0041 QStandardPaths::setTestModeEnabled(true); 0042 qputenv("KIOSLAVE_ENABLE_TESTMODE", "1"); // ensure the ioslaves call QStandardPaths::setTestModeEnabled too 0043 qputenv("KDE_FORK_SLAVES", "yes"); // to avoid a runtime dependency on klauncher 0044 0045 QVERIFY(m_tempDir.isValid()); 0046 QVERIFY(m_tempDestDir.isValid()); 0047 QVERIFY(m_nonWritableTempDir.isValid()); 0048 QVERIFY(QFile(m_nonWritableTempDir.path()).setPermissions(QFile::ReadOwner | QFile::ReadUser | QFile::ExeOwner | QFile::ExeUser)); 0049 m_srcDir = m_tempDir.path(); 0050 m_destDir = m_tempDestDir.path(); 0051 0052 m_srcFile = m_srcDir + QStringLiteral("/srcfile"); 0053 0054 KIO::setDefaultJobUiDelegateExtension(nullptr); // no "skip" dialogs 0055 0056 // Set a recent dir 0057 KConfigGroup recentDirsGroup(KSharedConfig::openConfig(), "kuick-copy"); 0058 m_recentDirs 0059 << m_destDir + QStringLiteral("/nonexistentsubdir") // will be action number count-3 0060 << m_nonWritableTempDir.path() // will be action number count-2 0061 << m_destDir; // will be action number count-1 0062 recentDirsGroup.writeEntry("Paths", m_recentDirs); 0063 0064 m_lastActionCount = 0; 0065 } 0066 0067 void cleanupTestCase() 0068 { 0069 QVERIFY(QFile(m_nonWritableTempDir.path()).setPermissions(QFile::ReadOwner | QFile::ReadUser | QFile::WriteOwner | QFile::WriteUser | QFile::ExeOwner | QFile::ExeUser)); 0070 } 0071 0072 // Before every test method, ensure the test file m_srcFile exists 0073 void init() 0074 { 0075 if (QFile::exists(m_srcFile)) { 0076 QVERIFY(QFileInfo(m_srcFile).isWritable()); 0077 } else { 0078 QFile srcFile(m_srcFile); 0079 QVERIFY2(srcFile.open(QFile::WriteOnly), qPrintable(srcFile.errorString())); 0080 srcFile.write("Hello world\n"); 0081 } 0082 QVERIFY(QFileInfo(m_srcFile).isWritable()); 0083 } 0084 0085 void shouldHaveParentWidget() 0086 { 0087 KFileCopyToMenu generator(&m_parentWidget); 0088 QCOMPARE(generator.parent(), &m_parentWidget); 0089 } 0090 0091 void shouldAddActions() 0092 { 0093 KFileCopyToMenu generator(&m_parentWidget); 0094 QMenu menu; 0095 generator.addActionsTo(&menu); 0096 QList<QUrl> urls; urls << QUrl::fromLocalFile(m_srcFile); 0097 generator.setUrls(urls); 0098 QCOMPARE(extractActionNames(menu), QStringList() << QStringLiteral("copyTo_submenu") << QStringLiteral("moveTo_submenu")); 0099 //menu.popup(QPoint(-50, -50)); 0100 QMenu *copyMenu = menu.actions().at(0)->menu(); // "copy" submenu 0101 QVERIFY(copyMenu); 0102 0103 // When 0104 copyMenu->popup(QPoint(-100, -100)); 0105 0106 // Then 0107 const QStringList actionNames = extractActionNames(*copyMenu); 0108 QCOMPARE(actionNames.first(), QStringLiteral("home")); 0109 QVERIFY(actionNames.contains(QLatin1String("browse"))); 0110 QCOMPARE(actionNames.at(actionNames.count() - 2), m_nonWritableTempDir.path()); 0111 QCOMPARE(actionNames.last(), m_destDir); 0112 } 0113 0114 void shouldTryCopyingToRecentPath_data() 0115 { 0116 QTest::addColumn<int>("actionNumber"); // from the bottom of the menu, starting at 1; see the recentDirs list in initTestCase 0117 QTest::addColumn<int>("expectedErrorCode"); 0118 0119 QTest::newRow("working") << 1 << 0; // no error 0120 QTest::newRow("non_writable") << 2 << int(KIO::ERR_WRITE_ACCESS_DENIED); 0121 QTest::newRow("non_existing") << 3 << int(KIO::ERR_CANNOT_OPEN_FOR_WRITING); 0122 } 0123 0124 void shouldTryCopyingToRecentPath() 0125 { 0126 QFETCH(int, actionNumber); 0127 QFETCH(int, expectedErrorCode); 0128 0129 KFileCopyToMenu generator(&m_parentWidget); 0130 QMenu menu; 0131 QList<QUrl> urls; urls << QUrl::fromLocalFile(m_srcFile); 0132 generator.setUrls(urls); 0133 generator.addActionsTo(&menu); 0134 QMenu *copyMenu = menu.actions().at(0)->menu(); 0135 copyMenu->popup(QPoint(-100, -100)); 0136 const QList<QAction *> actions = copyMenu->actions(); 0137 if (m_lastActionCount == 0) { 0138 m_lastActionCount = actions.count(); 0139 } else { 0140 QCOMPARE(actions.count(), m_lastActionCount); // should be stable, i.e. selecting a recent dir shouldn't duplicate it 0141 } 0142 QAction *copyAction = actions.at(actions.count() - actionNumber); 0143 QSignalSpy spy(&generator, SIGNAL(error(int,QString))); 0144 0145 // When 0146 copyAction->trigger(); 0147 0148 // Then 0149 QTRY_COMPARE(spy.count(), expectedErrorCode ? 1 : 0); 0150 if (expectedErrorCode) { 0151 QCOMPARE(spy.at(0).at(0).toInt(), expectedErrorCode); 0152 } else { 0153 QTRY_VERIFY(QFile::exists(m_destDir + QStringLiteral("/srcfile"))); 0154 } 0155 } 0156 0157 private: 0158 0159 static QStringList extractActionNames(const QMenu &menu) 0160 { 0161 QStringList ret; 0162 foreach (const QAction *action, menu.actions()) { 0163 ret.append(action->objectName()); 0164 } 0165 return ret; 0166 } 0167 0168 QTemporaryDir m_tempDir; 0169 QString m_srcDir; 0170 QString m_srcFile; 0171 QTemporaryDir m_tempDestDir; 0172 QString m_destDir; 0173 QTemporaryDir m_nonWritableTempDir; 0174 QWidget m_parentWidget; 0175 QStringList m_recentDirs; 0176 int m_lastActionCount; 0177 }; 0178 0179 QTEST_MAIN(KFileCopyToMenuTest) 0180 0181 #include "kfilecopytomenutest.moc" 0182