1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
/*
This file is part of the KDE project
SPDX-FileCopyrightText: 2014 David Faure <faure@kde.org>
SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include <QMenu>
#include <QSignalSpy>
#include <QTemporaryDir>
#include <QTest>
#include "jobuidelegatefactory.h"
#include "kiotesthelper.h"
#include <KConfigGroup>
#include <KFileCopyToMenu>
#include <KSharedConfig>
#include <KIO/CopyJob>
class KFileCopyToMenuTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase()
{
QStandardPaths::setTestModeEnabled(true);
qputenv("KIOSLAVE_ENABLE_TESTMODE", "1"); // ensure the KIO workers call QStandardPaths::setTestModeEnabled too
QVERIFY(m_tempDir.isValid());
QVERIFY(m_tempDestDir.isValid());
QVERIFY(m_nonWritableTempDir.isValid());
QVERIFY(QFile(m_nonWritableTempDir.path()).setPermissions(QFile::ReadOwner | QFile::ReadUser | QFile::ExeOwner | QFile::ExeUser));
m_srcDir = m_tempDir.path();
m_destDir = m_tempDestDir.path();
m_srcFile = m_srcDir + QStringLiteral("/srcfile");
KIO::setDefaultJobUiDelegateFactoryV2(nullptr); // no "skip" dialogs
// Set a recent dir
KConfigGroup recentDirsGroup(KSharedConfig::openConfig(), "kuick-copy");
m_recentDirs << m_destDir + QStringLiteral("/nonexistentsubdir") // will be action number count-3
<< m_nonWritableTempDir.path() // will be action number count-2
<< m_destDir; // will be action number count-1
recentDirsGroup.writeEntry("Paths", m_recentDirs);
m_lastActionCount = 0;
}
void cleanupTestCase()
{
QVERIFY(QFile(m_nonWritableTempDir.path())
.setPermissions(QFile::ReadOwner | QFile::ReadUser | QFile::WriteOwner | QFile::WriteUser | QFile::ExeOwner | QFile::ExeUser));
}
// Before every test method, ensure the test file m_srcFile exists
void init()
{
if (QFile::exists(m_srcFile)) {
QVERIFY(QFileInfo(m_srcFile).isWritable());
} else {
QFile srcFile(m_srcFile);
QVERIFY2(srcFile.open(QFile::WriteOnly), qPrintable(srcFile.errorString()));
srcFile.write("Hello world\n");
}
QVERIFY(QFileInfo(m_srcFile).isWritable());
}
void shouldHaveParentWidget()
{
KFileCopyToMenu generator(&m_parentWidget);
QCOMPARE(generator.parent(), &m_parentWidget);
}
void shouldAddActions()
{
KFileCopyToMenu generator(&m_parentWidget);
QMenu menu;
generator.addActionsTo(&menu);
QList<QUrl> urls;
urls << QUrl::fromLocalFile(m_srcFile);
generator.setUrls(urls);
QCOMPARE(extractActionNames(menu), QStringList() << QStringLiteral("copyTo_submenu") << QStringLiteral("moveTo_submenu"));
QAction *copyMenuAction = menu.actions().at(0);
// When
menu.setActiveAction(copyMenuAction);
menu.popup(QPoint(-100, -100));
// Then
const QStringList actionNames = extractActionNames(*copyMenuAction->menu());
QVERIFY(!actionNames.isEmpty());
QCOMPARE(actionNames.first(), QStringLiteral("home"));
QVERIFY(actionNames.contains(QLatin1String("browse")));
QCOMPARE(actionNames.at(actionNames.count() - 2), m_nonWritableTempDir.path());
QCOMPARE(actionNames.last(), m_destDir);
}
void shouldTryCopyingToRecentPath_data()
{
QTest::addColumn<int>("actionNumber"); // from the bottom of the menu, starting at 1; see the recentDirs list in initTestCase
QTest::addColumn<int>("expectedErrorCode");
QTest::newRow("working") << 1 << 0; // no error
QTest::newRow("non_writable") << 2 << int(KIO::ERR_WRITE_ACCESS_DENIED);
QTest::newRow("non_existing") << 3 << int(KIO::ERR_CANNOT_OPEN_FOR_WRITING);
}
void shouldTryCopyingToRecentPath()
{
QFETCH(int, actionNumber);
QFETCH(int, expectedErrorCode);
KFileCopyToMenu generator(&m_parentWidget);
QMenu menu;
QList<QUrl> urls;
urls << QUrl::fromLocalFile(m_srcFile);
generator.setUrls(urls);
generator.addActionsTo(&menu);
QAction *copyMenuAction = menu.actions().at(0);
menu.setActiveAction(copyMenuAction);
menu.popup(QPoint(-100, -100));
const QList<QAction *> actions = copyMenuAction->menu()->actions();
if (m_lastActionCount == 0) {
m_lastActionCount = actions.count();
} else {
QCOMPARE(actions.count(), m_lastActionCount); // should be stable, i.e. selecting a recent dir shouldn't duplicate it
}
QAction *copyAction = actions.at(actions.count() - actionNumber);
QSignalSpy spy(&generator, &KFileCopyToMenu::error);
// When
copyAction->trigger();
// Then
QTRY_COMPARE(spy.count(), expectedErrorCode ? 1 : 0);
if (expectedErrorCode) {
QCOMPARE(spy.at(0).at(0).toInt(), expectedErrorCode);
} else {
QTRY_VERIFY(QFile::exists(m_destDir + QStringLiteral("/srcfile")));
}
if (actionNumber == 1) { // This part only makes sense if the copy is going to work
QFile::remove(m_destDir + QStringLiteral("/srcfile"));
// Remove the recent dirs entry for m_destDir from the config
KConfigGroup group(KSharedConfig::openConfig(), "kuick-copy");
auto list = group.readEntry("Paths", QStringList{});
list.removeOne(m_destDir);
group.writeEntry("Paths", list);
group.sync();
// Triggering the action again, should insert a recent dirs corresponding
// to m_destDir, which calls KFileCopyToMainMenu::copyOrMoveTo(), which
// trims the recent dirs config to 10 urls, and _shouldn't_ crash
copyAction->trigger();
// Back to normal for the next tests to pass
group.writeEntry("Paths", m_recentDirs);
}
}
private:
static QStringList extractActionNames(const QMenu &menu)
{
QStringList ret;
const QList<QAction *> actionsList = menu.actions();
for (const QAction *action : actionsList) {
ret.append(action->objectName());
}
return ret;
}
QTemporaryDir m_tempDir;
QString m_srcDir;
QString m_srcFile;
QTemporaryDir m_tempDestDir;
QString m_destDir;
QTemporaryDir m_nonWritableTempDir;
QWidget m_parentWidget;
QStringList m_recentDirs;
int m_lastActionCount;
};
QTEST_MAIN(KFileCopyToMenuTest)
#include "kfilecopytomenutest.moc"
|