cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1077 lines
40 KiB
C++
1077 lines
40 KiB
C++
/*
|
|
This file is part of the KDE project
|
|
SPDX-FileCopyrightText: 2006 David Faure <faure@kde.org>
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
*/
|
|
|
|
#include "kfileitemtest.h"
|
|
#include <QTest>
|
|
#include <kfileitem.h>
|
|
#include <kfileitemlistproperties.h>
|
|
|
|
#include "kiotesthelper.h"
|
|
#include <KConfigGroup>
|
|
#include <KDesktopFile>
|
|
#include <KSycoca>
|
|
#include <KUser>
|
|
#include <QTemporaryDir>
|
|
#include <QTemporaryFile>
|
|
|
|
#include <KProtocolInfo>
|
|
#include <QMimeDatabase>
|
|
|
|
QTEST_MAIN(KFileItemTest)
|
|
|
|
struct CaseInsensitiveStringCompareHelper {
|
|
explicit CaseInsensitiveStringCompareHelper(QStringView str)
|
|
: m_str(str)
|
|
{
|
|
}
|
|
QStringView m_str;
|
|
bool operator==(QStringView other) const
|
|
{
|
|
return other.compare(m_str, Qt::CaseInsensitive) == 0;
|
|
}
|
|
};
|
|
|
|
char *toString(const CaseInsensitiveStringCompareHelper &h)
|
|
{
|
|
return QTest::toString(h.m_str);
|
|
}
|
|
|
|
void KFileItemTest::initTestCase()
|
|
{
|
|
QStandardPaths::setTestModeEnabled(true);
|
|
KSycoca::setupTestMenu();
|
|
}
|
|
|
|
void KFileItemTest::testPermissionsString()
|
|
{
|
|
// Directory
|
|
QTemporaryDir tempDir;
|
|
KFileItem dirItem(QUrl::fromLocalFile(tempDir.path() + '/'));
|
|
QCOMPARE((uint)dirItem.permissions(), (uint)0700);
|
|
QCOMPARE(dirItem.permissionsString(), QStringLiteral("drwx------"));
|
|
QVERIFY(dirItem.isReadable());
|
|
|
|
// File
|
|
QFile file(tempDir.path() + "/afile");
|
|
QVERIFY(file.open(QIODevice::WriteOnly));
|
|
file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadOther); // 0604
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()), QString(), KFileItem::Unknown);
|
|
QCOMPARE((uint)fileItem.permissions(), (uint)0604);
|
|
QCOMPARE(fileItem.permissionsString(), QStringLiteral("-rw----r--"));
|
|
QVERIFY(fileItem.isReadable());
|
|
QCOMPARE(fileItem.getStatusBarInfo(), CaseInsensitiveStringCompareHelper(QStringLiteral("afile (Empty document, 0 B)")));
|
|
|
|
// Folder
|
|
QVERIFY(QDir(tempDir.path())
|
|
.mkdir(QStringLiteral("afolder"),
|
|
QFile::ReadOwner | QFile::WriteOwner | QFile::ExeUser | QFile::ReadGroup | QFile::ExeGroup | QFile::ReadOther | QFile::ExeOther));
|
|
QFile folderFile(tempDir.path() + "/afolder");
|
|
KFileItem folderItem(QUrl::fromLocalFile(folderFile.fileName()), QString(), KFileItem::Unknown);
|
|
#ifdef Q_OS_FREEBSD
|
|
// QDir::mkdir does not apply permissions correctly on FreeBSD
|
|
QCOMPARE(folderItem.permissionsString(), QStringLiteral("drwx------")); // 700
|
|
#else
|
|
QCOMPARE(folderItem.permissionsString(), QStringLiteral("drwxr-xr-x")); // 755
|
|
#endif
|
|
QVERIFY(folderItem.isReadable());
|
|
QCOMPARE(folderItem.getStatusBarInfo(), CaseInsensitiveStringCompareHelper(QStringLiteral("afolder (Folder)")));
|
|
|
|
// Symlink to file
|
|
QString symlink = tempDir.path() + "/asymlink";
|
|
QVERIFY(file.link(symlink));
|
|
QUrl symlinkUrl = QUrl::fromLocalFile(symlink);
|
|
KFileItem symlinkItem(symlinkUrl, QString(), KFileItem::Unknown);
|
|
QCOMPARE((uint)symlinkItem.permissions(), (uint)0604);
|
|
// This is a bit different from "ls -l": we get the 'l' but we see the permissions of the target.
|
|
// This is actually useful though; the user sees it's a link, and can check if he can read the [target] file.
|
|
QCOMPARE(symlinkItem.permissionsString(), QStringLiteral("lrw----r--"));
|
|
QVERIFY(symlinkItem.isReadable());
|
|
QCOMPARE(symlinkItem.getStatusBarInfo(),
|
|
CaseInsensitiveStringCompareHelper(QStringLiteral("asymlink (Empty document, Link to %1/afile)").arg(tempDir.path())));
|
|
|
|
#ifdef Q_OS_UNIX
|
|
// changing home temporarly
|
|
auto home = QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
|
|
setenv("HOME", tempDir.path().toLatin1(), 1);
|
|
|
|
QCOMPARE(symlinkItem.getStatusBarInfo(), CaseInsensitiveStringCompareHelper(QStringLiteral("asymlink (Empty document, Link to ~/afile)")));
|
|
|
|
setenv("HOME", home.toLatin1(), 1);
|
|
#endif
|
|
|
|
#ifdef Q_OS_UNIX
|
|
// relative Symlink to a file
|
|
QString relativeSymlink = tempDir.path() + "/afolder/relative-symlink";
|
|
QVERIFY(::symlink("../afile", relativeSymlink.toLatin1()) == 0);
|
|
QUrl relativeSymlinkUrl = QUrl::fromLocalFile(relativeSymlink);
|
|
KFileItem relativeSymlinkItem(relativeSymlinkUrl, QString(), KFileItem::Unknown);
|
|
QCOMPARE((uint)relativeSymlinkItem.permissions(), (uint)0604);
|
|
// This is a bit different from "ls -l": we get the 'l' but we see the permissions of the target.
|
|
// This is actually useful though; the user sees it's a link, and can check if he can read the [target] file.
|
|
QCOMPARE(relativeSymlinkItem.permissionsString(), QStringLiteral("lrw----r--"));
|
|
QVERIFY(relativeSymlinkItem.isReadable());
|
|
QCOMPARE(relativeSymlinkItem.getStatusBarInfo(), CaseInsensitiveStringCompareHelper(QStringLiteral("relative-symlink (Empty document, Link to ../afile)")));
|
|
#endif
|
|
|
|
// Symlink to directory (#162544)
|
|
QVERIFY(QFile::remove(symlink));
|
|
QVERIFY(QFile(tempDir.path() + '/').link(symlink));
|
|
KFileItem symlinkToDirItem(symlinkUrl, QString(), KFileItem::Unknown);
|
|
QCOMPARE((uint)symlinkToDirItem.permissions(), (uint)0700);
|
|
QCOMPARE(symlinkToDirItem.permissionsString(), QStringLiteral("lrwx------"));
|
|
QCOMPARE(symlinkToDirItem.getStatusBarInfo(), CaseInsensitiveStringCompareHelper(QStringLiteral("asymlink (Folder, Link to %1)").arg(tempDir.path())));
|
|
|
|
// unkwnown file
|
|
QFile unkwnownFile(tempDir.path() + "/unkwnown_file");
|
|
KFileItem unkwnownfileItem(QUrl::fromLocalFile(unkwnownFile.fileName()), QString(), KFileItem::Unknown);
|
|
QCOMPARE(unkwnownfileItem.getStatusBarInfo(), CaseInsensitiveStringCompareHelper(QStringLiteral("unkwnown_file (Unknown)")));
|
|
}
|
|
|
|
// https://bugs.kde.org/475422
|
|
void KFileItemTest::testRelativeSymlinkGetStatusBarInfo()
|
|
{
|
|
#ifdef Q_OS_UNIX
|
|
QTemporaryDir tempDir;
|
|
|
|
// relative symlink to a file
|
|
{
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("afile.relative"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, QStringLiteral("afile"));
|
|
|
|
KFileItem symlinkItem(entry, QUrl::fromLocalFile(tempDir.path()), true, true);
|
|
QCOMPARE(symlinkItem.getStatusBarInfo(),
|
|
CaseInsensitiveStringCompareHelper(QStringLiteral("afile.relative (Unknown, Link to afile)").arg(tempDir.path())));
|
|
}
|
|
|
|
// relative symlink to a file in a different directory
|
|
{
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("afile.relative"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, QStringLiteral("../afile"));
|
|
|
|
KFileItem symlinkItem(entry, QUrl::fromLocalFile(tempDir.path()), true, true);
|
|
QCOMPARE(symlinkItem.getStatusBarInfo(),
|
|
CaseInsensitiveStringCompareHelper(QStringLiteral("afile.relative (Unknown, Link to ../afile)").arg(tempDir.path())));
|
|
}
|
|
|
|
// relative symlink to a file, name has spaces
|
|
{
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("a file with spaces.relative"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, QStringLiteral("a file with spaces"));
|
|
|
|
KFileItem symlinkItem(entry, QUrl::fromLocalFile(tempDir.path()), true, true);
|
|
QCOMPARE(symlinkItem.getStatusBarInfo(),
|
|
CaseInsensitiveStringCompareHelper(QStringLiteral("a file with spaces.relative (Unknown, Link to a file with spaces)").arg(tempDir.path())));
|
|
}
|
|
|
|
// relative symlink in remote
|
|
{
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("afile.relative"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, QStringLiteral("afile"));
|
|
|
|
QString remotePath = QStringLiteral("fish://192.168.1.1/tmp");
|
|
|
|
KFileItem symlinkItem(entry, QUrl(remotePath), true, true);
|
|
QCOMPARE(symlinkItem.getStatusBarInfo(),
|
|
CaseInsensitiveStringCompareHelper(QStringLiteral("afile.relative (Unknown, Link to %1/afile)").arg(remotePath)));
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
void KFileItemTest::testNull()
|
|
{
|
|
KFileItem null;
|
|
QVERIFY(null.isNull());
|
|
KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/")), QString(), KFileItem::Unknown);
|
|
QVERIFY(!fileItem.isNull());
|
|
null = fileItem; // ok, now 'null' isn't so null anymore
|
|
QVERIFY(!null.isNull());
|
|
QVERIFY(null.isReadable());
|
|
QVERIFY(!null.isWritable());
|
|
QVERIFY(!null.isHidden());
|
|
}
|
|
|
|
void KFileItemTest::testDoesNotExist()
|
|
{
|
|
KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/doesnotexist")), QString(), KFileItem::Unknown);
|
|
QVERIFY(!fileItem.isNull());
|
|
QVERIFY(!fileItem.isReadable());
|
|
QVERIFY(!fileItem.isWritable());
|
|
QVERIFY(fileItem.user().isEmpty());
|
|
QVERIFY(fileItem.group().isEmpty());
|
|
}
|
|
|
|
void KFileItemTest::testDetach()
|
|
{
|
|
KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown);
|
|
QCOMPARE(fileItem.name(), QStringLiteral("one"));
|
|
KFileItem fileItem2(fileItem);
|
|
QVERIFY(fileItem == fileItem2);
|
|
QVERIFY(fileItem.d == fileItem2.d);
|
|
fileItem2.setName(QStringLiteral("two"));
|
|
QCOMPARE(fileItem2.name(), QStringLiteral("two"));
|
|
QCOMPARE(fileItem.name(), QStringLiteral("one")); // it detached
|
|
QVERIFY(fileItem == fileItem2);
|
|
QVERIFY(fileItem.d != fileItem2.d);
|
|
|
|
fileItem = fileItem2;
|
|
QCOMPARE(fileItem.name(), QStringLiteral("two"));
|
|
QVERIFY(fileItem == fileItem2);
|
|
QVERIFY(fileItem.d == fileItem2.d);
|
|
QVERIFY(!(fileItem != fileItem2));
|
|
}
|
|
|
|
void KFileItemTest::testMove()
|
|
{
|
|
// Test move constructor
|
|
{
|
|
KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown);
|
|
QCOMPARE(fileItem.name(), QStringLiteral("one"));
|
|
KFileItem fileItem2(std::move(fileItem));
|
|
QCOMPARE(fileItem2.name(), QStringLiteral("one"));
|
|
}
|
|
|
|
// Test move assignment
|
|
{
|
|
KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown);
|
|
QCOMPARE(fileItem.name(), QStringLiteral("one"));
|
|
KFileItem fileItem2(QUrl::fromLocalFile(QStringLiteral("/two")), QString(), KFileItem::Unknown);
|
|
fileItem2 = std::move(fileItem);
|
|
QCOMPARE(fileItem2.name(), QStringLiteral("one"));
|
|
}
|
|
|
|
// Now to test some value changes to make sure moving works as intended.
|
|
KFileItem fileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString(), KFileItem::Unknown);
|
|
QCOMPARE(fileItem.name(), QStringLiteral("one"));
|
|
fileItem.setUrl(QUrl::fromLocalFile(QStringLiteral("/two")));
|
|
QCOMPARE(fileItem.name(), QStringLiteral("two"));
|
|
|
|
// Move fileitem to fileItem2, it should now contain everything fileItem had.
|
|
// Just testing a property to make sure it does.
|
|
KFileItem fileItem2(std::move(fileItem));
|
|
QCOMPARE(fileItem2.name(), QStringLiteral("two"));
|
|
}
|
|
|
|
void KFileItemTest::testMimeTypeCtor()
|
|
{
|
|
KFileItem fileItem;
|
|
|
|
fileItem = KFileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString("inode/directory"));
|
|
QVERIFY(fileItem.isDir());
|
|
QVERIFY(fileItem.isMimeTypeKnown());
|
|
|
|
fileItem = KFileItem(QUrl::fromLocalFile(QStringLiteral("/one")), QString("image/jpeg"));
|
|
QVERIFY(!fileItem.isDir());
|
|
QVERIFY(fileItem.isMimeTypeKnown());
|
|
|
|
fileItem = KFileItem(QUrl::fromLocalFile(QStringLiteral("/one.txt")), QString("inode/directory"));
|
|
QVERIFY(fileItem.isDir());
|
|
QVERIFY(fileItem.isMimeTypeKnown());
|
|
|
|
fileItem = KFileItem(QUrl::fromLocalFile(QStringLiteral("/one.txt")), QString(" "));
|
|
QVERIFY(!fileItem.isMimeTypeKnown());
|
|
}
|
|
|
|
void KFileItemTest::testBasicFile()
|
|
{
|
|
QTemporaryFile file;
|
|
QVERIFY(file.open());
|
|
QFile fileObj(file.fileName());
|
|
QVERIFY(fileObj.open(QIODevice::WriteOnly));
|
|
fileObj.write(QByteArray("Hello"));
|
|
fileObj.close();
|
|
|
|
QUrl url = QUrl::fromLocalFile(file.fileName());
|
|
KFileItem fileItem(url, QString(), KFileItem::Unknown);
|
|
QCOMPARE(fileItem.text(), url.fileName());
|
|
QVERIFY(fileItem.isLocalFile());
|
|
QCOMPARE(fileItem.localPath(), url.toLocalFile());
|
|
QCOMPARE(fileItem.size(), KIO::filesize_t(5));
|
|
QVERIFY(fileItem.linkDest().isEmpty());
|
|
QVERIFY(!fileItem.isHidden());
|
|
QVERIFY(fileItem.isReadable());
|
|
QVERIFY(fileItem.isWritable());
|
|
QVERIFY(fileItem.isFile());
|
|
QVERIFY(fileItem.isRegularFile());
|
|
QVERIFY(!fileItem.isDir());
|
|
QVERIFY(!fileItem.isDesktopFile());
|
|
QCOMPARE(fileItem.mimetype(), "text/plain");
|
|
// StatMimeType was not requested
|
|
QVERIFY(!fileItem.entry().contains(KIO::UDSEntry::UDS_MIME_TYPE));
|
|
#ifndef Q_OS_WIN
|
|
QCOMPARE(fileItem.user(), KUser().loginName());
|
|
#endif
|
|
// TODO test date fields
|
|
}
|
|
|
|
void KFileItemTest::testBasicDirectory()
|
|
{
|
|
QSKIP("TODO testBasicDirectory doesn't pass FIXME");
|
|
|
|
QTemporaryDir dir;
|
|
QUrl dirUrl = QUrl::fromLocalFile(dir.path());
|
|
KFileItem dirItem(dirUrl, QString(), KFileItem::Unknown);
|
|
QCOMPARE(dirItem.text(), dirUrl.fileName());
|
|
QVERIFY(dirItem.isLocalFile());
|
|
QCOMPARE(dirItem.localPath(), dirUrl.toLocalFile());
|
|
QVERIFY(dirItem.size() > 0);
|
|
QVERIFY(dirItem.linkDest().isEmpty());
|
|
QVERIFY(!dirItem.isHidden());
|
|
QVERIFY(dirItem.isReadable());
|
|
QVERIFY(dirItem.isWritable());
|
|
QVERIFY(!dirItem.isFile());
|
|
QVERIFY(!dirItem.isRegularFile());
|
|
QVERIFY(dirItem.isDir());
|
|
QCOMPARE(dirItem.mimetype(), "inode/directory");
|
|
// StatMimeType was not requested
|
|
QVERIFY(!dirItem.entry().contains(KIO::UDSEntry::UDS_MIME_TYPE));
|
|
QVERIFY(!dirItem.isDesktopFile());
|
|
// TODO test date fields
|
|
}
|
|
|
|
void KFileItemTest::testRootDirectory()
|
|
{
|
|
const QString rootPath = QDir::rootPath();
|
|
QUrl url = QUrl::fromLocalFile(rootPath);
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("."));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
KFileItem fileItem(entry, url);
|
|
QCOMPARE(fileItem.text(), QStringLiteral("."));
|
|
QVERIFY(fileItem.isLocalFile());
|
|
QCOMPARE(fileItem.localPath(), url.toLocalFile());
|
|
QVERIFY(fileItem.linkDest().isEmpty());
|
|
QVERIFY(!fileItem.isHidden());
|
|
QVERIFY(!fileItem.isFile());
|
|
QVERIFY(fileItem.isDir());
|
|
QVERIFY(!fileItem.isDesktopFile());
|
|
}
|
|
|
|
void KFileItemTest::testHiddenFile()
|
|
{
|
|
QTemporaryDir tempDir;
|
|
QFile file(tempDir.path() + "/.hiddenfile");
|
|
QVERIFY(file.open(QIODevice::WriteOnly));
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()), QString(), KFileItem::Unknown);
|
|
QCOMPARE(fileItem.text(), QStringLiteral(".hiddenfile"));
|
|
QVERIFY(fileItem.isLocalFile());
|
|
QVERIFY(fileItem.isHidden());
|
|
}
|
|
|
|
void KFileItemTest::testMimeTypeOnDemand()
|
|
{
|
|
QTemporaryFile file;
|
|
QVERIFY(file.open());
|
|
|
|
{
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
fileItem.setDelayedMimeTypes(true);
|
|
QVERIFY(fileItem.currentMimeType().isDefault());
|
|
QVERIFY(!fileItem.isMimeTypeKnown());
|
|
QVERIFY(!fileItem.isFinalIconKnown());
|
|
// qDebug() << fileItem.determineMimeType().name();
|
|
QCOMPARE(fileItem.determineMimeType().name(), QStringLiteral("application/x-zerosize"));
|
|
QCOMPARE(fileItem.mimetype(), QStringLiteral("application/x-zerosize"));
|
|
QVERIFY(fileItem.isMimeTypeKnown());
|
|
QVERIFY(fileItem.isFinalIconKnown());
|
|
}
|
|
|
|
{
|
|
// Calling mimeType directly also does MIME type determination
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
fileItem.setDelayedMimeTypes(true);
|
|
QVERIFY(!fileItem.isMimeTypeKnown());
|
|
QCOMPARE(fileItem.mimetype(), QStringLiteral("application/x-zerosize"));
|
|
QVERIFY(fileItem.isMimeTypeKnown());
|
|
}
|
|
|
|
{
|
|
// Calling overlays should NOT do MIME type determination (#237668)
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
fileItem.setDelayedMimeTypes(true);
|
|
QVERIFY(!fileItem.isMimeTypeKnown());
|
|
fileItem.overlays();
|
|
QVERIFY(!fileItem.isMimeTypeKnown());
|
|
}
|
|
|
|
{
|
|
QTemporaryFile file;
|
|
QVERIFY(file.open());
|
|
// Check whether mime-magic is used.
|
|
// No known extension, so it should be used by determineMimeType.
|
|
file.write(QByteArray("%PDF-"));
|
|
QString fileName = file.fileName();
|
|
QVERIFY(!fileName.isEmpty());
|
|
file.close();
|
|
KFileItem fileItem(QUrl::fromLocalFile(fileName));
|
|
fileItem.setDelayedMimeTypes(true);
|
|
QCOMPARE(fileItem.currentMimeType().name(), QLatin1String("application/octet-stream"));
|
|
QVERIFY(fileItem.currentMimeType().isValid());
|
|
QVERIFY(fileItem.currentMimeType().isDefault());
|
|
QVERIFY(!fileItem.isMimeTypeKnown());
|
|
QCOMPARE(fileItem.determineMimeType().name(), QStringLiteral("application/pdf"));
|
|
QCOMPARE(fileItem.mimetype(), QStringLiteral("application/pdf"));
|
|
}
|
|
|
|
{
|
|
QTemporaryFile file(QDir::tempPath() + QLatin1String("/kfileitemtest_XXXXXX.txt"));
|
|
QVERIFY(file.open());
|
|
// Check whether mime-magic is used.
|
|
// Known extension, so it should NOT be used.
|
|
file.write(QByteArray("<smil"));
|
|
QString fileName = file.fileName();
|
|
QVERIFY(!fileName.isEmpty());
|
|
file.close();
|
|
KFileItem fileItem(QUrl::fromLocalFile(fileName));
|
|
fileItem.setDelayedMimeTypes(true);
|
|
QCOMPARE(fileItem.currentMimeType().name(), QStringLiteral("text/plain"));
|
|
QVERIFY(fileItem.isMimeTypeKnown());
|
|
QCOMPARE(fileItem.determineMimeType().name(), QStringLiteral("text/plain"));
|
|
QCOMPARE(fileItem.mimetype(), QStringLiteral("text/plain"));
|
|
|
|
// And if the MIME type is not on demand?
|
|
KFileItem fileItem2(QUrl::fromLocalFile(fileName));
|
|
QCOMPARE(fileItem2.currentMimeType().name(), QStringLiteral("text/plain")); // XDG says: application/smil; but can't sniff all files so this can't work
|
|
QVERIFY(fileItem2.isMimeTypeKnown());
|
|
}
|
|
}
|
|
|
|
void KFileItemTest::testCmp()
|
|
{
|
|
QTemporaryFile file;
|
|
QVERIFY(file.open());
|
|
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
fileItem.setDelayedMimeTypes(true);
|
|
KFileItem fileItem2(QUrl::fromLocalFile(file.fileName()));
|
|
QVERIFY(fileItem == fileItem2); // created independently, but still 'equal'
|
|
QVERIFY(fileItem.d != fileItem2.d);
|
|
QVERIFY(!(fileItem != fileItem2));
|
|
QVERIFY(fileItem.cmp(fileItem2));
|
|
}
|
|
|
|
void KFileItemTest::testCmpAndInit()
|
|
{
|
|
QTemporaryDir tempDir;
|
|
KFileItem dirItem(QUrl::fromLocalFile(tempDir.path()));
|
|
QVERIFY(dirItem.isDir()); // this calls init()
|
|
|
|
KFileItem dirItem2(QUrl::fromLocalFile(tempDir.path()));
|
|
// not yet init() called on dirItem2, but must be equal
|
|
// compare init()ialized to un-init()ialized KFileItem
|
|
QVERIFY(dirItem.cmp(dirItem2));
|
|
QVERIFY(dirItem2.isDir());
|
|
QVERIFY(dirItem.cmp(dirItem2));
|
|
QVERIFY(dirItem == dirItem2);
|
|
QVERIFY(dirItem.d != dirItem2.d);
|
|
QVERIFY(!(dirItem != dirItem2));
|
|
|
|
// now the other way around, compare un-init()ialized to init()ialized KFileItem
|
|
KFileItem dirItem3(QUrl::fromLocalFile(tempDir.path()));
|
|
// not yet init() called on dirItem3, but must be equal
|
|
QVERIFY(dirItem3.cmp(dirItem));
|
|
QVERIFY(dirItem3.isDir());
|
|
QVERIFY(dirItem3.cmp(dirItem));
|
|
QVERIFY(dirItem == dirItem3);
|
|
QVERIFY(dirItem.d != dirItem3.d);
|
|
QVERIFY(!(dirItem != dirItem3));
|
|
}
|
|
|
|
void KFileItemTest::testCmpByUrl()
|
|
{
|
|
const QUrl nulUrl;
|
|
const QUrl url = QUrl::fromLocalFile(QStringLiteral("1foo"));
|
|
const QUrl url2 = QUrl::fromLocalFile(QStringLiteral("fo1"));
|
|
const QUrl url3 = QUrl::fromLocalFile(QStringLiteral("foo"));
|
|
KFileItem nulFileItem;
|
|
KFileItem nulFileItem2(nulUrl);
|
|
KFileItem fileItem(url);
|
|
KFileItem fileItem2(url2);
|
|
KFileItem fileItem3(url3);
|
|
|
|
// an invalid KFileItem is considered equal to any other invalid KFileItem or invalid QUrl.
|
|
QVERIFY(!(nulFileItem < nulFileItem));
|
|
QVERIFY(!(nulFileItem < nulFileItem2));
|
|
QVERIFY(!(nulFileItem2 < nulFileItem));
|
|
QVERIFY(!(nulFileItem < nulUrl));
|
|
// an invalid KFileItem is considered less than any valid KFileItem.
|
|
QVERIFY(nulFileItem < fileItem);
|
|
// a valid KFileItem is not less than an invalid KFileItem or invalid QUrl
|
|
QVERIFY(!(fileItem < nulUrl));
|
|
QVERIFY(!(fileItem < nulFileItem));
|
|
QVERIFY(!(fileItem < nulFileItem2));
|
|
|
|
QVERIFY(fileItem < fileItem2);
|
|
QVERIFY(fileItem < url2);
|
|
QVERIFY(!(fileItem2 < fileItem));
|
|
QVERIFY(fileItem2 < fileItem3);
|
|
QVERIFY(fileItem < url3);
|
|
QVERIFY(!(fileItem3 < fileItem2));
|
|
QVERIFY(!(fileItem3 < fileItem));
|
|
// Must be false as they are considered equal
|
|
QVERIFY(!(fileItem < fileItem));
|
|
QVERIFY(!(fileItem < url));
|
|
}
|
|
|
|
void KFileItemTest::testRename()
|
|
{
|
|
KIO::UDSEntry entry;
|
|
const QString origName = QStringLiteral("foo");
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, origName);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
KFileItem fileItem(entry, QUrl::fromLocalFile(QStringLiteral("/dir/foo")));
|
|
QCOMPARE(fileItem.name(), origName);
|
|
QCOMPARE(fileItem.text(), origName);
|
|
const QString newName = QStringLiteral("FiNeX_rocks");
|
|
fileItem.setName(newName);
|
|
QCOMPARE(fileItem.name(), newName);
|
|
QCOMPARE(fileItem.text(), newName);
|
|
QCOMPARE(fileItem.entry().stringValue(KIO::UDSEntry::UDS_NAME), newName); // #195385
|
|
}
|
|
|
|
void KFileItemTest::testRefresh()
|
|
{
|
|
QTemporaryDir tempDir;
|
|
QFileInfo dirInfo(tempDir.path());
|
|
// Refresh on a dir
|
|
KFileItem dirItem(QUrl::fromLocalFile(tempDir.path()));
|
|
QVERIFY(dirItem.isDir());
|
|
QVERIFY(dirItem.entry().isDir());
|
|
QDateTime lastModified = dirInfo.lastModified();
|
|
// Qt 5.8 adds milliseconds (but UDSEntry has no support for that)
|
|
lastModified = lastModified.addMSecs(-lastModified.time().msec());
|
|
QCOMPARE(dirItem.time(KFileItem::ModificationTime), lastModified);
|
|
dirItem.refresh();
|
|
QVERIFY(dirItem.isDir());
|
|
QVERIFY(dirItem.entry().isDir());
|
|
QCOMPARE(dirItem.time(KFileItem::ModificationTime), lastModified);
|
|
|
|
// Refresh on a file
|
|
QFile file(tempDir.path() + "/afile");
|
|
QVERIFY(file.open(QIODevice::WriteOnly));
|
|
file.write("Hello world\n");
|
|
file.close();
|
|
QFileInfo fileInfo(file.fileName());
|
|
const KIO::filesize_t expectedSize = 12;
|
|
QCOMPARE(KIO::filesize_t(fileInfo.size()), expectedSize);
|
|
file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadOther); // 0604
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
QVERIFY(fileItem.isFile());
|
|
QVERIFY(!fileItem.isLink());
|
|
QCOMPARE(fileItem.size(), expectedSize);
|
|
#ifndef Q_OS_WIN
|
|
QCOMPARE(fileItem.user(), KUser().loginName());
|
|
#endif
|
|
// Qt 5.8 adds milliseconds (but UDSEntry has no support for that)
|
|
lastModified = dirInfo.lastModified();
|
|
// Truncate away the milliseconds...
|
|
lastModified = lastModified.addMSecs(-lastModified.time().msec());
|
|
// ...but it looks like the kernel rounds up when the msecs are .998 or .999,
|
|
// so add a bit of tolerance
|
|
auto expectedLastModified = lastModified;
|
|
if (fileItem.time(KFileItem::ModificationTime) != lastModified && fileItem.time(KFileItem::ModificationTime) == lastModified.addSecs(1)) {
|
|
expectedLastModified = expectedLastModified.addSecs(1);
|
|
}
|
|
QCOMPARE(fileItem.time(KFileItem::ModificationTime), expectedLastModified);
|
|
fileItem.refresh();
|
|
QVERIFY(fileItem.isFile());
|
|
QVERIFY(!fileItem.isLink());
|
|
QCOMPARE(fileItem.size(), expectedSize);
|
|
#ifndef Q_OS_WIN
|
|
QCOMPARE(fileItem.user(), KUser().loginName());
|
|
#endif
|
|
QCOMPARE(fileItem.time(KFileItem::ModificationTime), expectedLastModified);
|
|
|
|
// Refresh on a symlink to a file
|
|
const QString symlink = tempDir.path() + "/asymlink";
|
|
QVERIFY(file.link(symlink));
|
|
QDateTime symlinkTime = QDateTime::currentDateTime().addSecs(-20);
|
|
// we currently lose milliseconds....
|
|
symlinkTime = symlinkTime.addMSecs(-symlinkTime.time().msec());
|
|
setTimeStamp(symlink, symlinkTime); // differentiate link time and source file time
|
|
const QUrl symlinkUrl = QUrl::fromLocalFile(symlink);
|
|
KFileItem symlinkItem(symlinkUrl);
|
|
QVERIFY(symlinkItem.isFile());
|
|
QVERIFY(symlinkItem.isLink());
|
|
QCOMPARE(symlinkItem.size(), expectedSize);
|
|
QCOMPARE(symlinkItem.time(KFileItem::ModificationTime), symlinkTime);
|
|
symlinkItem.refresh();
|
|
QVERIFY(symlinkItem.isFile());
|
|
QVERIFY(symlinkItem.isLink());
|
|
QCOMPARE(symlinkItem.size(), expectedSize);
|
|
QCOMPARE(symlinkItem.time(KFileItem::ModificationTime), symlinkTime);
|
|
|
|
// Symlink to directory (#162544)
|
|
QVERIFY(QFile::remove(symlink));
|
|
QVERIFY(QFile(tempDir.path() + '/').link(symlink));
|
|
KFileItem symlinkToDirItem(symlinkUrl);
|
|
QVERIFY(symlinkToDirItem.isDir());
|
|
QVERIFY(symlinkToDirItem.isLink());
|
|
symlinkToDirItem.refresh();
|
|
QVERIFY(symlinkToDirItem.isDir());
|
|
QVERIFY(symlinkToDirItem.isLink());
|
|
}
|
|
|
|
void KFileItemTest::testExists()
|
|
{
|
|
QTest::failOnWarning(QRegularExpression(".?"));
|
|
|
|
KFileItem dummy;
|
|
QVERIFY(!dummy.exists());
|
|
|
|
QTemporaryFile f;
|
|
QVERIFY(f.open());
|
|
f.close();
|
|
const auto fileName = f.fileName();
|
|
dummy = KFileItem(QUrl::fromLocalFile(fileName));
|
|
dummy.refresh();
|
|
QVERIFY(dummy.exists());
|
|
|
|
QVERIFY(QFile::remove(fileName));
|
|
QVERIFY(dummy.exists());
|
|
dummy.refresh();
|
|
QVERIFY(!dummy.exists());
|
|
|
|
dummy = KFileItem(QUrl::fromLocalFile(fileName));
|
|
// this should trigger a warning
|
|
QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression("^KFileItem: exists called when not initialised QUrl"));
|
|
QVERIFY(!dummy.exists());
|
|
}
|
|
|
|
void KFileItemTest::testDotDirectory()
|
|
{
|
|
QTemporaryDir tempDir;
|
|
QFile file(tempDir.path() + "/.directory");
|
|
QVERIFY(file.open(QIODevice::WriteOnly));
|
|
file.write("[Desktop Entry]\nIcon=foo\nComment=com\n");
|
|
file.close();
|
|
{
|
|
KFileItem fileItem(QUrl::fromLocalFile(tempDir.path() + '/'), QString(), KFileItem::Unknown);
|
|
QVERIFY(fileItem.isLocalFile());
|
|
QCOMPARE(fileItem.mimeComment(), QStringLiteral("com"));
|
|
QCOMPARE(fileItem.iconName(), QStringLiteral("foo"));
|
|
}
|
|
// Test for calling iconName first, to trigger MIME type resolution
|
|
{
|
|
KFileItem fileItem(QUrl::fromLocalFile(tempDir.path()), QString(), KFileItem::Unknown);
|
|
QVERIFY(fileItem.isLocalFile());
|
|
QCOMPARE(fileItem.iconName(), QStringLiteral("foo"));
|
|
}
|
|
}
|
|
|
|
void KFileItemTest::testDecodeFileName_data()
|
|
{
|
|
QTest::addColumn<QString>("filename");
|
|
QTest::addColumn<QString>("expectedText");
|
|
|
|
QTest::newRow("simple") << "filename"
|
|
<< "filename";
|
|
QTest::newRow("/ at end") << QString(QStringLiteral("foo") + QChar(0x2044)) << QString(QStringLiteral("foo") + QChar(0x2044));
|
|
QTest::newRow("/ at begin") << QString(QChar(0x2044)) << QString(QChar(0x2044));
|
|
}
|
|
|
|
void KFileItemTest::testDecodeFileName()
|
|
{
|
|
QFETCH(QString, filename);
|
|
QFETCH(QString, expectedText);
|
|
QCOMPARE(KIO::decodeFileName(filename), expectedText);
|
|
}
|
|
|
|
void KFileItemTest::testEncodeFileName_data()
|
|
{
|
|
QTest::addColumn<QString>("text");
|
|
QTest::addColumn<QString>("expectedFileName");
|
|
|
|
QTest::newRow("simple") << "filename"
|
|
<< "filename";
|
|
QTest::newRow("/ at end") << "foo/" << QString(QStringLiteral("foo") + QChar(0x2044));
|
|
QTest::newRow("/ at begin") << "/" << QString(QChar(0x2044));
|
|
}
|
|
|
|
void KFileItemTest::testEncodeFileName()
|
|
{
|
|
QFETCH(QString, text);
|
|
QFETCH(QString, expectedFileName);
|
|
QCOMPARE(KIO::encodeFileName(text), expectedFileName);
|
|
}
|
|
|
|
void KFileItemTest::testListProperties_data()
|
|
{
|
|
QTest::addColumn<QString>("itemDescriptions");
|
|
QTest::addColumn<bool>("expectedReading");
|
|
QTest::addColumn<bool>("expectedDeleting");
|
|
QTest::addColumn<bool>("expectedIsLocal");
|
|
QTest::addColumn<bool>("expectedIsDirectory");
|
|
QTest::addColumn<bool>("expectedIsFile");
|
|
QTest::addColumn<QString>("expectedMimeType");
|
|
QTest::addColumn<QString>("expectedMimeGroup");
|
|
|
|
/* clang-format off */
|
|
QTest::newRow("one file") << "f" << true << true << true << false << true << "text/plain" << "text";
|
|
QTest::newRow("one dir") << "d" << true << true << true << true << false << "inode/directory" << "inode";
|
|
QTest::newRow("root dir") << "/" << true << false << true << true << false << "inode/directory" << "inode";
|
|
QTest::newRow("file+dir") << "fd" << true << true << true << false << false << "" << "";
|
|
QTest::newRow("two dirs") << "dd" << true << true << true << true << false << "inode/directory" << "inode";
|
|
QTest::newRow("dir+root dir") << "d/" << true << false << true << true << false << "inode/directory" << "inode";
|
|
QTest::newRow("two (text+html) files") << "ff" << true << true << true << false << true << "" << "text";
|
|
QTest::newRow("three (text+html+empty) files") << "fff" << true << true << true << false << true << "" << "";
|
|
QTest::newRow("http url") << "h" << true << true /*says kio_http...*/ << false << false << true << "application/octet-stream" << "application";
|
|
QTest::newRow("2 http urls") << "hh" << true << true /*says kio_http...*/ << false << false << true << "application/octet-stream" << "application";
|
|
/* clang-format on */
|
|
}
|
|
|
|
void KFileItemTest::testListProperties()
|
|
{
|
|
QFETCH(QString, itemDescriptions);
|
|
QFETCH(bool, expectedReading);
|
|
QFETCH(bool, expectedDeleting);
|
|
QFETCH(bool, expectedIsLocal);
|
|
QFETCH(bool, expectedIsDirectory);
|
|
QFETCH(bool, expectedIsFile);
|
|
QFETCH(QString, expectedMimeType);
|
|
QFETCH(QString, expectedMimeGroup);
|
|
|
|
QTemporaryDir tempDir;
|
|
QDir baseDir(tempDir.path());
|
|
KFileItemList items;
|
|
for (int i = 0; i < itemDescriptions.size(); ++i) {
|
|
QString fileName = tempDir.path() + "/file" + QString::number(i);
|
|
switch (itemDescriptions[i].toLatin1()) {
|
|
case 'f': {
|
|
if (i == 1) { // 2nd file is html
|
|
fileName += QLatin1String(".html");
|
|
}
|
|
QFile file(fileName);
|
|
QVERIFY(file.open(QIODevice::WriteOnly));
|
|
if (i == 0) {
|
|
file.write("Hello");
|
|
} else if (i == 1) {
|
|
file.write("<html>");
|
|
} // i == 2: leave the file empty
|
|
file.close();
|
|
KFileItem item(QUrl::fromLocalFile(fileName), QString(), KFileItem::Unknown);
|
|
if (i == 0) {
|
|
QCOMPARE(item.mimetype(), "text/plain");
|
|
} else if (i == 1) {
|
|
QCOMPARE(item.mimetype(), "text/html");
|
|
} else if (i == 2) {
|
|
QCOMPARE(item.mimetype(), "application/x-zerosize");
|
|
}
|
|
items.push_back(std::move(item));
|
|
break;
|
|
}
|
|
case 'd':
|
|
QVERIFY(baseDir.mkdir(fileName));
|
|
items << KFileItem(QUrl::fromLocalFile(fileName), QString(), KFileItem::Unknown);
|
|
break;
|
|
case '/':
|
|
items << KFileItem(QUrl::fromLocalFile(QStringLiteral("/")), QString(), KFileItem::Unknown);
|
|
break;
|
|
case 'h':
|
|
items << KFileItem(QUrl(QStringLiteral("http://www.kde.org")), QString(), KFileItem::Unknown);
|
|
break;
|
|
default:
|
|
QVERIFY(false);
|
|
}
|
|
}
|
|
KFileItemListProperties props(items);
|
|
QCOMPARE(props.supportsReading(), expectedReading);
|
|
QCOMPARE(props.supportsDeleting(), expectedDeleting);
|
|
QCOMPARE(props.isLocal(), expectedIsLocal);
|
|
QCOMPARE(props.isDirectory(), expectedIsDirectory);
|
|
QCOMPARE(props.isFile(), expectedIsFile);
|
|
QCOMPARE(props.mimeType(), expectedMimeType);
|
|
QCOMPARE(props.mimeGroup(), expectedMimeGroup);
|
|
}
|
|
|
|
void KFileItemTest::testIconNameForUrl_data()
|
|
{
|
|
QTest::addColumn<QUrl>("url");
|
|
QTest::addColumn<QString>("expectedIcon");
|
|
|
|
QTest::newRow("root") << QUrl("file:/") << "inode-directory"; // the icon comes from KFileItem
|
|
if (QFile::exists(QStringLiteral("/tmp"))) {
|
|
QTest::newRow("subdir") << QUrl::fromLocalFile("/tmp") << "folder-temp";
|
|
}
|
|
|
|
QTest::newRow("home") << QUrl::fromLocalFile(QDir::homePath()) << "user-home";
|
|
const QString moviesPath = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation).constFirst();
|
|
if (QFileInfo::exists(moviesPath)) {
|
|
QTest::newRow("videos") << QUrl::fromLocalFile(moviesPath) << (moviesPath == QDir::homePath() ? "user-home" : "folder-videos");
|
|
}
|
|
|
|
QTest::newRow("empty") << QUrl() << "unknown";
|
|
QTest::newRow("relative") << QUrl("foo") << "unknown";
|
|
QTest::newRow("tilde") << QUrl("~") << "unknown";
|
|
|
|
QTest::newRow("unknownscheme folder") << QUrl("unknownscheme:/") << "inode-directory";
|
|
QTest::newRow("unknownscheme file") << QUrl("unknownscheme:/test") << "application-octet-stream";
|
|
|
|
QTest::newRow("trash:/ itself") << QUrl("trash:/") << "user-trash-full";
|
|
QTest::newRow("folder under trash:/") << QUrl("trash:/folder/") << "inode-directory";
|
|
QTest::newRow("file under trash:/") << QUrl("trash:/test") << "application-octet-stream";
|
|
QTest::newRow("image file under trash:/") << QUrl("trash:/test.png") << "image-png";
|
|
|
|
QTest::newRow("https scheme") << QUrl("https://kde.org/") << "text-html";
|
|
|
|
if (KProtocolInfo::isKnownProtocol("smb")) {
|
|
QTest::newRow("smb root") << QUrl("smb:/") << "network-workgroup";
|
|
QTest::newRow("smb unknown file") << QUrl("smb:/test") << "network-workgroup";
|
|
QTest::newRow("smb directory/") << QUrl("smb:/unknown/") << "inode-directory";
|
|
QTest::newRow("smb image file") << QUrl("smb:/test.png") << "image-png";
|
|
}
|
|
}
|
|
|
|
void KFileItemTest::testIconNameForUrl()
|
|
{
|
|
QFETCH(QUrl, url);
|
|
QFETCH(QString, expectedIcon);
|
|
|
|
if (KIO::iconNameForUrl(url) != expectedIcon) {
|
|
qDebug() << url;
|
|
QCOMPARE(KIO::iconNameForUrl(url), expectedIcon);
|
|
}
|
|
}
|
|
|
|
void KFileItemTest::testMimetypeForRemoteFolder()
|
|
{
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
QUrl url(QStringLiteral("smb://remoteFolder/foo"));
|
|
KFileItem fileItem(entry, url);
|
|
|
|
QCOMPARE(fileItem.mimetype(), QStringLiteral("inode/directory"));
|
|
}
|
|
|
|
void KFileItemTest::testMimetypeForRemoteFolderWithFileType()
|
|
{
|
|
QString udsMimeType = QStringLiteral("application/x-smb-workgroup");
|
|
QVERIFY2(QMimeDatabase().mimeTypeForName(udsMimeType).isValid(),
|
|
qPrintable(QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).join(':'))); // kcoreaddons installed? XDG_DATA_DIRS set?
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, udsMimeType);
|
|
|
|
QUrl url(QStringLiteral("smb://remoteFolder/foo"));
|
|
KFileItem fileItem(entry, url);
|
|
|
|
QCOMPARE(fileItem.mimetype(), udsMimeType);
|
|
}
|
|
|
|
void KFileItemTest::testCurrentMimetypeForRemoteFolder()
|
|
{
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
QUrl url(QStringLiteral("smb://remoteFolder/foo"));
|
|
KFileItem fileItem(entry, url);
|
|
|
|
QCOMPARE(fileItem.currentMimeType().name(), QStringLiteral("inode/directory"));
|
|
}
|
|
|
|
void KFileItemTest::testCurrentMimetypeForRemoteFolderWithFileType()
|
|
{
|
|
QString udsMimeType = QStringLiteral("application/x-smb-workgroup");
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_NAME, QStringLiteral("foo"));
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
entry.fastInsert(KIO::UDSEntry::UDS_MIME_TYPE, udsMimeType);
|
|
|
|
QUrl url(QStringLiteral("smb://remoteFolder/foo"));
|
|
KFileItem fileItem(entry, url);
|
|
|
|
QCOMPARE(fileItem.currentMimeType().name(), udsMimeType);
|
|
}
|
|
|
|
void KFileItemTest::testIconNameForCustomFolderIcons()
|
|
{
|
|
// Custom folder icons should be displayed (bug 350612)
|
|
|
|
const QString iconName = QStringLiteral("folder-music");
|
|
|
|
QTemporaryDir tempDir;
|
|
const QUrl url = QUrl::fromLocalFile(tempDir.path());
|
|
KDesktopFile cfg(tempDir.path() + QLatin1String("/.directory"));
|
|
cfg.desktopGroup().writeEntry("Icon", iconName);
|
|
cfg.sync();
|
|
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
KFileItem fileItem(entry, url);
|
|
|
|
QCOMPARE(fileItem.iconName(), iconName);
|
|
}
|
|
|
|
void KFileItemTest::testIconNameForStandardPath()
|
|
{
|
|
const QString iconName = QStringLiteral("folder-videos");
|
|
const QUrl url = QUrl::fromLocalFile(QDir::homePath() + QLatin1String("/Videos"));
|
|
QStandardPaths::setTestModeEnabled(true);
|
|
|
|
KIO::UDSEntry entry;
|
|
entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
|
|
KFileItem fileItem(entry, url);
|
|
|
|
QCOMPARE(fileItem.iconName(), iconName);
|
|
}
|
|
|
|
#ifndef Q_OS_WIN // user/group/other write permissions are not handled on windows
|
|
|
|
void KFileItemTest::testIsReadable_data()
|
|
{
|
|
QTest::addColumn<int>("mode");
|
|
QTest::addColumn<bool>("readable");
|
|
|
|
QTest::newRow("fully-readable") << 0444 << true;
|
|
QTest::newRow("user-readable") << 0400 << true;
|
|
QTest::newRow("user-readable2") << 0440 << true;
|
|
QTest::newRow("not-readable-by-us") << 0044 << false;
|
|
QTest::newRow("not-readable-by-us2") << 0004 << false;
|
|
QTest::newRow("not-readable-at-all") << 0000 << false;
|
|
}
|
|
|
|
void KFileItemTest::testIsReadable()
|
|
{
|
|
QFETCH(int, mode);
|
|
QFETCH(bool, readable);
|
|
|
|
QTemporaryFile file;
|
|
QVERIFY(file.open());
|
|
int ret = fchmod(file.handle(), (mode_t)mode);
|
|
QCOMPARE(ret, 0);
|
|
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
QCOMPARE(fileItem.isReadable(), readable);
|
|
|
|
QVERIFY(file.remove());
|
|
// still cached thanks to the cached internal udsentry
|
|
QCOMPARE(fileItem.isReadable(), readable);
|
|
}
|
|
|
|
void KFileItemTest::testIsWritable_data()
|
|
{
|
|
QTest::addColumn<int>("mode");
|
|
QTest::addColumn<bool>("writable");
|
|
|
|
QTest::newRow("fully-writable") << 0333 << true;
|
|
QTest::newRow("user-writable") << 0300 << true;
|
|
QTest::newRow("user-writable2") << 0330 << true;
|
|
QTest::newRow("not-writable-by-us") << 0033 << false;
|
|
QTest::newRow("not-writable-by-us2") << 0003 << false;
|
|
QTest::newRow("not-writable-at-all") << 0000 << false;
|
|
}
|
|
|
|
void KFileItemTest::testIsWritable()
|
|
{
|
|
QFETCH(int, mode);
|
|
QFETCH(bool, writable);
|
|
|
|
QTemporaryFile file;
|
|
QVERIFY(file.open());
|
|
int ret = fchmod(file.handle(), (mode_t)mode);
|
|
QCOMPARE(ret, 0);
|
|
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
QCOMPARE(fileItem.isWritable(), writable);
|
|
|
|
QVERIFY(file.remove());
|
|
// still cached thanks to the cached internal udsentry
|
|
QCOMPARE(fileItem.isWritable(), writable);
|
|
}
|
|
|
|
void KFileItemTest::testIsExecutable_data()
|
|
{
|
|
QTest::addColumn<int>("mode");
|
|
QTest::addColumn<bool>("executable");
|
|
|
|
QTest::newRow("fully-executable") << 0111 << true;
|
|
QTest::newRow("user-executable") << 0100 << true;
|
|
QTest::newRow("user-executable2") << 0110 << true;
|
|
QTest::newRow("not-executable-by-us") << 0011 << false;
|
|
QTest::newRow("not-executable-by-us2") << 0001 << false;
|
|
QTest::newRow("not-executable-at-all") << 0000 << false;
|
|
}
|
|
|
|
void KFileItemTest::testIsExecutable()
|
|
{
|
|
QFETCH(int, mode);
|
|
QFETCH(bool, executable);
|
|
|
|
QTemporaryFile file;
|
|
QVERIFY(file.open());
|
|
int ret = fchmod(file.handle(), (mode_t)mode);
|
|
QCOMPARE(ret, 0);
|
|
|
|
KFileItem fileItem(QUrl::fromLocalFile(file.fileName()));
|
|
QCOMPARE(fileItem.isExecutable(), executable);
|
|
|
|
QVERIFY(file.remove());
|
|
// still cached thanks to the cached internal udsentry
|
|
QCOMPARE(fileItem.isExecutable(), executable);
|
|
}
|
|
|
|
// Restore permissions so that the QTemporaryDir cleanup can happen (taken from tst_qsavefile.cpp)
|
|
class PermissionRestorer
|
|
{
|
|
Q_DISABLE_COPY(PermissionRestorer)
|
|
public:
|
|
explicit PermissionRestorer(const QString &path)
|
|
: m_path(path)
|
|
{
|
|
}
|
|
~PermissionRestorer()
|
|
{
|
|
restore();
|
|
}
|
|
|
|
inline void restore()
|
|
{
|
|
QFile file(m_path);
|
|
#ifdef Q_OS_UNIX
|
|
file.setPermissions(QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner));
|
|
#else
|
|
file.setPermissions(QFile::WriteOwner);
|
|
file.remove();
|
|
#endif
|
|
}
|
|
|
|
private:
|
|
const QString m_path;
|
|
};
|
|
|
|
void KFileItemTest::testNonWritableDirectory()
|
|
{
|
|
// Given a directory with a file in it
|
|
QTemporaryDir dir;
|
|
QVERIFY2(dir.isValid(), qPrintable(dir.errorString()));
|
|
QFile file(dir.path() + "/file1");
|
|
QVERIFY(file.open(QIODevice::WriteOnly));
|
|
QCOMPARE(file.write("Hello"), Q_INT64_C(5));
|
|
file.close();
|
|
// ... which is then made non-writable
|
|
QVERIFY(QFile(dir.path()).setPermissions(QFile::ReadOwner | QFile::ExeOwner));
|
|
PermissionRestorer permissionRestorer(dir.path());
|
|
|
|
// When using KFileItemListProperties on the file
|
|
const KFileItem item(QUrl::fromLocalFile(file.fileName()));
|
|
KFileItemListProperties props(KFileItemList{item});
|
|
|
|
// Then it should say moving is not supported
|
|
QVERIFY(!props.supportsMoving());
|
|
QVERIFY(props.supportsWriting()); // but we can write to the file itself
|
|
}
|
|
|
|
#endif // Q_OS_WIN
|
|
|
|
#include "moc_kfileitemtest.cpp"
|