2022-04-02 18:24:21 +05:00

195 lines
7.2 KiB
C++

/*
SPDX-FileCopyrightText: 2009 David Faure <faure@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <KIO/FileUndoManager>
#include <QDesktopServices>
#include <QSignalSpy>
#include <QStandardPaths>
#include <QTemporaryFile>
#include <QTest>
#include <kdirlister.h>
#include <kio/copyjob.h>
#include <kio/job.h>
static void doUndo() // see FileUndoManagerTest::doUndo()
{
QEventLoop eventLoop;
QObject::connect(KIO::FileUndoManager::self(), &KIO::FileUndoManager::undoJobFinished, &eventLoop, &QEventLoop::quit);
KIO::FileUndoManager::self()->undo();
eventLoop.exec(QEventLoop::ExcludeUserInputEvents); // wait for undo job to finish
}
class TestDesktop : public QObject
{
Q_OBJECT
public:
TestDesktop()
{
}
private Q_SLOTS:
void initTestCase()
{
setenv("KDE_FORK_SLAVES", "yes", true);
// make KIOs use test mode too
setenv("KIOSLAVE_ENABLE_TESTMODE", "1", 1);
QStandardPaths::setTestModeEnabled(true);
// Warning: even with test mode enabled, this is the real user's Desktop directory
m_desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
m_testFileName = QLatin1String("kio_desktop_test_file");
cleanupTestCase();
}
void cleanupTestCase()
{
QFile::remove(m_desktopPath + '/' + m_testFileName);
QFile::remove(m_desktopPath + '/' + m_testFileName + ".part");
QFile::remove(m_desktopPath + '/' + m_testFileName + "_link");
}
void testCopyToDesktop()
{
QTemporaryFile tempFile;
QVERIFY(tempFile.open());
tempFile.write("Hello world\n", 12);
QString fileName = tempFile.fileName();
tempFile.close();
KIO::Job *job = KIO::file_copy(QUrl::fromLocalFile(fileName), QUrl("desktop:/" + m_testFileName), -1, KIO::HideProgressInfo);
job->setUiDelegate(nullptr);
QVERIFY(job->exec());
QVERIFY(QFile::exists(m_desktopPath + '/' + m_testFileName));
}
void testMostLocalUrl() // relies on testCopyToDesktop being run before
{
const QUrl desktopUrl("desktop:/" + m_testFileName);
const QString filePath(m_desktopPath + '/' + m_testFileName);
KIO::StatJob *job = KIO::mostLocalUrl(desktopUrl, KIO::HideProgressInfo);
QVERIFY(job);
bool ok = job->exec();
QVERIFY(ok);
QCOMPARE(job->mostLocalUrl().toLocalFile(), filePath);
}
void testCreateSymlink()
{
const QUrl desktopUrl("desktop:/" + m_testFileName);
const QUrl desktopLink("desktop:/" + m_testFileName + "_link");
const QString source = m_desktopPath + '/' + m_testFileName;
const QString localLink = source + "_link";
// Create a symlink using kio_desktop
KIO::Job *linkJob = KIO::symlink(m_testFileName, desktopLink, KIO::HideProgressInfo);
QVERIFY(linkJob->exec());
QVERIFY(QFileInfo(localLink).isSymLink());
QCOMPARE(QFileInfo(localLink).symLinkTarget(), source);
// Now try changing the link target, without Overwrite -> error
linkJob = KIO::symlink(m_testFileName + QLatin1Char('2'), desktopLink, KIO::HideProgressInfo);
QVERIFY(!linkJob->exec());
QCOMPARE(linkJob->error(), (int)KIO::ERR_FILE_ALREADY_EXIST);
// Now try changing the link target, with Overwrite (bug 360487)
linkJob = KIO::symlink(m_testFileName + QLatin1Char('3'), desktopLink, KIO::Overwrite | KIO::HideProgressInfo);
QVERIFY(linkJob->exec());
QVERIFY(QFileInfo(localLink).isSymLink());
QCOMPARE(QFileInfo(localLink).symLinkTarget(), source + QLatin1Char('3'));
}
void testRename_data()
{
QTest::addColumn<bool>("withDirListerCache");
QTest::addColumn<QUrl>("srcUrl");
QTest::addColumn<QUrl>("destUrl");
const QString str = "desktop:/" + m_testFileName;
const QUrl orig(str);
const QUrl part(str + ".part");
QTest::newRow("orig_to_part") << false << orig << part;
QTest::newRow("part_to_orig") << false << part << orig;
// Warnings: all tests without dirlister cache should above this line
// and all tests with it should be below - the cache stays forever once it exists.
QTest::newRow("orig_to_part_with_cache") << true << orig << part;
QTest::newRow("part_to_orig_with_cache") << true << part << orig; // #218719
}
void testRename() // relies on testCopyToDesktop being run before
{
QFETCH(bool, withDirListerCache);
QFETCH(QUrl, srcUrl);
QFETCH(QUrl, destUrl);
QScopedPointer<KDirLister> lister(nullptr);
if (withDirListerCache) {
lister.reset(new KDirLister);
lister->openUrl(QUrl(QStringLiteral("desktop:/")));
QSignalSpy spyCompleted(lister.data(), static_cast<void (KDirLister::*)()>(&KDirLister::completed));
spyCompleted.wait();
}
org::kde::KDirNotify kdirnotify(QString(), QString(), QDBusConnection::sessionBus(), this);
QSignalSpy spyFilesAdded(&kdirnotify, &org::kde::KDirNotify::FilesAdded);
QSignalSpy spyFileRenamed(&kdirnotify, &org::kde::KDirNotify::FileRenamed);
QSignalSpy spyFileRenamedWithLocalPath(&kdirnotify, &org::kde::KDirNotify::FileRenamedWithLocalPath);
const QString srcFilePath(m_desktopPath + srcUrl.path());
QVERIFY(QFile::exists(srcFilePath));
const QString destFilePath(m_desktopPath + destUrl.path());
QVERIFY(!QFile::exists(destFilePath));
KIO::Job *job = KIO::rename(srcUrl, destUrl, KIO::HideProgressInfo);
job->setUiDelegate(nullptr);
QVERIFY(job);
bool ok = job->exec();
QVERIFY(ok);
QVERIFY(!QFile::exists(srcFilePath));
QVERIFY(QFile::exists(destFilePath));
// kio_desktop's rename() calls org::kde::KDirNotify::emitFileRenamedWithLocalPath
QTRY_COMPARE(spyFileRenamed.count(), 1);
QTRY_COMPARE(spyFileRenamedWithLocalPath.count(), 1);
// and then desktopnotifier notices something changed and emits KDirNotify::FilesAdded
QTRY_VERIFY(spyFilesAdded.count() >= 1); // can be 3, depending on kdirwatch's behaviour in desktopnotifier
// check that KDirLister now has the correct item (#382341)
if (lister) {
QTRY_COMPARE(lister->findByUrl(destUrl).targetUrl(), QUrl::fromLocalFile(destFilePath));
}
}
void testTrashAndUndo()
{
// Given a file on the desktop...
const QString localPath = m_desktopPath + '/' + m_testFileName;
QVERIFY(QFile::exists(localPath));
// ...moved to the trash
const QUrl desktopUrl("desktop:/" + m_testFileName);
KIO::Job *job = KIO::trash({desktopUrl}, KIO::HideProgressInfo);
job->setUiDelegate(nullptr);
KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Trash, {desktopUrl}, QUrl(QStringLiteral("trash:/")), job);
QVERIFY2(job->exec(), qPrintable(job->errorString()));
QVERIFY(!QFile::exists(localPath));
// When the user calls undo
doUndo();
// Then the file should re-appear
QVERIFY(QFile::exists(localPath));
}
private:
QString m_desktopPath;
QString m_testFileName;
};
QTEST_GUILESS_MAIN(TestDesktop)
#include "kio_desktop_test.moc"