kio_desktop_test.cpp 7.97 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* This file is part of the KDE project
   Copyright (C) 2009 David Faure <faure@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

Alexander Lohnau's avatar
Alexander Lohnau committed
20
#include <KIO/FileUndoManager>
21
#include <QDesktopServices>
22
#include <QSignalSpy>
Alexander Lohnau's avatar
Alexander Lohnau committed
23
#include <QStandardPaths>
24
25
#include <QTemporaryFile>
#include <QTest>
Alexander Lohnau's avatar
Alexander Lohnau committed
26
#include <kdirlister.h>
27
#include <kio/copyjob.h>
Alexander Lohnau's avatar
Alexander Lohnau committed
28
#include <kio/job.h>
29
30
31
32

static void doUndo() // see FileUndoManagerTest::doUndo()
{
    QEventLoop eventLoop;
Alexander Lohnau's avatar
Alexander Lohnau committed
33
    QObject::connect(KIO::FileUndoManager::self(), &KIO::FileUndoManager::undoJobFinished, &eventLoop, &QEventLoop::quit);
34
35
36
    KIO::FileUndoManager::self()->undo();
    eventLoop.exec(QEventLoop::ExcludeUserInputEvents); // wait for undo job to finish
}
37
38
39
40
41
42

class TestDesktop : public QObject
{
    Q_OBJECT

public:
Alexander Lohnau's avatar
Alexander Lohnau committed
43
44
45
    TestDesktop()
    {
    }
46
47
48
49

private Q_SLOTS:
    void initTestCase()
    {
Alexander Lohnau's avatar
Alexander Lohnau committed
50
        setenv("KDE_FORK_SLAVES", "yes", true);
51

Alexander Lohnau's avatar
Alexander Lohnau committed
52
        // make KIOs use test mode too
53
54
55
        setenv("KIOSLAVE_ENABLE_TESTMODE", "1", 1);
        QStandardPaths::setTestModeEnabled(true);

David Faure's avatar
David Faure committed
56
        // Warning: even with test mode enabled, this is the real user's Desktop directory
57
        m_desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
58
        m_testFileName = QLatin1String("kio_desktop_test_file");
David Faure's avatar
David Faure committed
59
60

        cleanupTestCase();
61
62
63
64
65
    }
    void cleanupTestCase()
    {
        QFile::remove(m_desktopPath + '/' + m_testFileName);
        QFile::remove(m_desktopPath + '/' + m_testFileName + ".part");
David Faure's avatar
David Faure committed
66
        QFile::remove(m_desktopPath + '/' + m_testFileName + "_link");
67
68
69
70
    }

    void testCopyToDesktop()
    {
71
        QTemporaryFile tempFile;
72
        QVERIFY(tempFile.open());
Alexander Lohnau's avatar
Alexander Lohnau committed
73
        tempFile.write("Hello world\n", 12);
74
75
        QString fileName = tempFile.fileName();
        tempFile.close();
Alexander Lohnau's avatar
Alexander Lohnau committed
76
        KIO::Job *job = KIO::file_copy(QUrl::fromLocalFile(fileName), QUrl("desktop:/" + m_testFileName), -1, KIO::HideProgressInfo);
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
77
        job->setUiDelegate(nullptr);
78
79
80
81
82
83
84
85
        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);
Alexander Lohnau's avatar
Alexander Lohnau committed
86
        KIO::StatJob *job = KIO::mostLocalUrl(desktopUrl, KIO::HideProgressInfo);
87
88
89
90
91
92
        QVERIFY(job);
        bool ok = job->exec();
        QVERIFY(ok);
        QCOMPARE(job->mostLocalUrl().toLocalFile(), filePath);
    }

David Faure's avatar
David Faure committed
93
94
95
96
97
98
99
100
    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
Alexander Lohnau's avatar
Alexander Lohnau committed
101
        KIO::Job *linkJob = KIO::symlink(m_testFileName, desktopLink, KIO::HideProgressInfo);
David Faure's avatar
David Faure committed
102
103
104
105
106
        QVERIFY(linkJob->exec());
        QVERIFY(QFileInfo(localLink).isSymLink());
        QCOMPARE(QFileInfo(localLink).symLinkTarget(), source);

        // Now try changing the link target, without Overwrite -> error
Laurent Montel's avatar
Laurent Montel committed
107
        linkJob = KIO::symlink(m_testFileName + QLatin1Char('2'), desktopLink, KIO::HideProgressInfo);
David Faure's avatar
David Faure committed
108
109
110
111
        QVERIFY(!linkJob->exec());
        QCOMPARE(linkJob->error(), (int)KIO::ERR_FILE_ALREADY_EXIST);

        // Now try changing the link target, with Overwrite (bug 360487)
Laurent Montel's avatar
Laurent Montel committed
112
        linkJob = KIO::symlink(m_testFileName + QLatin1Char('3'), desktopLink, KIO::Overwrite | KIO::HideProgressInfo);
David Faure's avatar
David Faure committed
113
114
        QVERIFY(linkJob->exec());
        QVERIFY(QFileInfo(localLink).isSymLink());
Laurent Montel's avatar
Laurent Montel committed
115
        QCOMPARE(QFileInfo(localLink).symLinkTarget(), source + QLatin1Char('3'));
David Faure's avatar
David Faure committed
116
117
    }

118
119
120
    void testRename_data()
    {
        QTest::addColumn<bool>("withDirListerCache");
121
122
123
124
125
126
127
128
        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;
129
130
        // 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.
131
132
        QTest::newRow("orig_to_part_with_cache") << true << orig << part;
        QTest::newRow("part_to_orig_with_cache") << true << part << orig; // #218719
133
134
135
136
137
    }

    void testRename() // relies on testCopyToDesktop being run before
    {
        QFETCH(bool, withDirListerCache);
138
139
        QFETCH(QUrl, srcUrl);
        QFETCH(QUrl, destUrl);
140

141
        QScopedPointer<KDirLister> lister(nullptr);
142
        if (withDirListerCache) {
143
144
145
146
            lister.reset(new KDirLister);
            lister->openUrl(QUrl(QStringLiteral("desktop:/")));
            QSignalSpy spyCompleted(lister.data(), static_cast<void (KDirLister::*)()>(&KDirLister::completed));
            spyCompleted.wait();
147
148
        }

149
150
151
152
        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);
153
154
155
156
157
158

        const QString srcFilePath(m_desktopPath + srcUrl.path());
        QVERIFY(QFile::exists(srcFilePath));
        const QString destFilePath(m_desktopPath + destUrl.path());
        QVERIFY(!QFile::exists(destFilePath));

Alexander Lohnau's avatar
Alexander Lohnau committed
159
        KIO::Job *job = KIO::rename(srcUrl, destUrl, KIO::HideProgressInfo);
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
160
        job->setUiDelegate(nullptr);
161
162
163
164
165
        QVERIFY(job);
        bool ok = job->exec();
        QVERIFY(ok);
        QVERIFY(!QFile::exists(srcFilePath));
        QVERIFY(QFile::exists(destFilePath));
166
167
168
169
170

        // 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
Ahmad Samir's avatar
Ahmad Samir committed
171
        QTRY_VERIFY(spyFilesAdded.count() >= 1); // can be 3, depending on kdirwatch's behaviour in desktopnotifier
172
173
174

        // check that KDirLister now has the correct item (#382341)
        if (lister) {
175
            QTRY_COMPARE(lister->findByUrl(destUrl).targetUrl(), QUrl::fromLocalFile(destFilePath));
176
        }
177
178
    }

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
    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));
    }

200
201
202
203
204
private:
    QString m_desktopPath;
    QString m_testFileName;
};

205
QTEST_GUILESS_MAIN(TestDesktop)
206
207

#include "kio_desktop_test.moc"