X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/38c34eeca315c7be58e65d4d3fb72aaf7b866719..a1c9bc5595a21299dab9260c6a77c0561c95c8ba:/src/tests/viewpropertiestest.cpp diff --git a/src/tests/viewpropertiestest.cpp b/src/tests/viewpropertiestest.cpp index 7b30203d2..9252f17ba 100644 --- a/src/tests/viewpropertiestest.cpp +++ b/src/tests/viewpropertiestest.cpp @@ -8,6 +8,9 @@ #include "dolphin_generalsettings.h" #include "testdir.h" +#include + +#include #include class ViewPropertiesTest : public QObject @@ -20,7 +23,13 @@ private Q_SLOTS: void cleanup(); void testReadOnlyBehavior(); + void testReadOnlyDirectory(); void testAutoSave(); + void testParamMigrationToFileAttr(); + void testParamMigrationToFileAttrKeepDirectory(); + void testExtendedAttributeFull(); + void testUseAsDefaultViewSettings(); + void testUseAsCustomDefaultViewSettings(); private: bool m_globalViewProps; @@ -30,6 +39,9 @@ private: void ViewPropertiesTest::initTestCase() { QStandardPaths::setTestModeEnabled(true); + + GeneralSettings::self()->setViewPropsTimestamp(QDateTime::currentDateTime()); + QVERIFY(GeneralSettings::self()->save()); } void ViewPropertiesTest::init() @@ -73,6 +85,47 @@ void ViewPropertiesTest::testReadOnlyBehavior() QVERIFY(!QFile::exists(dotDirectoryFile)); } +void ViewPropertiesTest::testReadOnlyDirectory() +{ + const QUrl testDirUrl = m_testDir->url(); + const QString localFolder = testDirUrl.toLocalFile(); + const QString dotDirectoryFile = localFolder + "/.directory"; + QVERIFY(!QFile::exists(dotDirectoryFile)); + + // restrict write permissions + QVERIFY(QFile(localFolder).setPermissions(QFileDevice::ReadOwner)); + + QScopedPointer props(new ViewProperties(testDirUrl)); + const QString destinationDir = props->destinationDir(QStringLiteral("local")) + localFolder; + + QVERIFY(props->isAutoSaveEnabled()); + props->setSortRole("someNewSortRole"); + props.reset(); + + qDebug() << destinationDir; + QVERIFY(QDir(destinationDir).exists()); + + QVERIFY(!QFile::exists(dotDirectoryFile)); + KFileMetaData::UserMetaData metadata(localFolder); + const QString viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(viewProperties.isEmpty()); + + props.reset(new ViewProperties(testDirUrl)); + QVERIFY(props->isAutoSaveEnabled()); + QCOMPARE(props->sortRole(), "someNewSortRole"); + props.reset(); + + metadata = KFileMetaData::UserMetaData(destinationDir); + if (metadata.isSupported()) { + QVERIFY(metadata.hasAttribute("kde.fm.viewproperties#1")); + } else { + QVERIFY(QFile::exists(destinationDir + "/.directory")); + } + + // un-restrict write permissions + QFile(localFolder).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner); +} + void ViewPropertiesTest::testAutoSave() { QString dotDirectoryFile = m_testDir->url().toLocalFile() + "/.directory"; @@ -83,7 +136,259 @@ void ViewPropertiesTest::testAutoSave() props->setSortRole("someNewSortRole"); props.reset(); - QVERIFY(QFile::exists(dotDirectoryFile)); + KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile()); + if (metadata.isSupported()) { + auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(!viewProperties.isEmpty()); + QVERIFY(!QFile::exists(dotDirectoryFile)); + } else { + QVERIFY(QFile::exists(dotDirectoryFile)); + } +} + +void ViewPropertiesTest::testParamMigrationToFileAttr() +{ + QString dotDirectoryFilePath = m_testDir->url().toLocalFile() + "/.directory"; + QVERIFY(!QFile::exists(dotDirectoryFilePath)); + + const char *settingsContent = R"SETTINGS(" +[Dolphin] +Version=4 +ViewMode=1 +Timestamp=2023,12,29,10,44,15.793 +VisibleRoles=text,CustomizedDetails,Details_text,Details_modificationtime,Details_type + +[Settings] +HiddenFilesShown=true)SETTINGS"; + auto dotDirectoryFile = QFile(dotDirectoryFilePath); + QVERIFY(dotDirectoryFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)); + QTextStream out(&dotDirectoryFile); + out << settingsContent; + dotDirectoryFile.close(); + + KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile()); + { + QScopedPointer props(new ViewProperties(m_testDir->url())); + QCOMPARE(props->viewMode(), DolphinView::Mode::DetailsView); + QVERIFY(props->hiddenFilesShown()); + props->save(); + + if (metadata.isSupported()) { + auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(!viewProperties.isEmpty()); + QVERIFY(!QFile::exists(dotDirectoryFilePath)); + } else { + QVERIFY(QFile::exists(dotDirectoryFilePath)); + } + } + + ViewProperties props(m_testDir->url()); + QCOMPARE(props.viewMode(), DolphinView::Mode::DetailsView); + QVERIFY(props.hiddenFilesShown()); +} + +void ViewPropertiesTest::testParamMigrationToFileAttrKeepDirectory() +{ + QString dotDirectoryFilePath = m_testDir->url().toLocalFile() + "/.directory"; + QVERIFY(!QFile::exists(dotDirectoryFilePath)); + + const char *settingsContent = R"SETTINGS(" +[Dolphin] +Version=4 +ViewMode=1 +Timestamp=2023,12,29,10,44,15.793 +VisibleRoles=text,CustomizedDetails,Details_text,Details_modificationtime,Details_type + +[Settings] +HiddenFilesShown=true + +[Other] +ThoseShouldBeKept=true +)SETTINGS"; + auto dotDirectoryFile = QFile(dotDirectoryFilePath); + QVERIFY(dotDirectoryFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)); + QTextStream out(&dotDirectoryFile); + out << settingsContent; + dotDirectoryFile.close(); + + KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile()); + { + QScopedPointer props(new ViewProperties(m_testDir->url())); + QCOMPARE(props->viewMode(), DolphinView::Mode::DetailsView); + QVERIFY(props->hiddenFilesShown()); + props->save(); + + if (metadata.isSupported()) { + auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(!viewProperties.isEmpty()); + } + + QVERIFY(QFile::exists(dotDirectoryFilePath)); + KConfig directorySettings(dotDirectoryFilePath, KConfig::SimpleConfig); + QCOMPARE(directorySettings.groupList(), {"Other"}); + } + + ViewProperties props(m_testDir->url()); + QVERIFY(props.hiddenFilesShown()); + QCOMPARE(props.viewMode(), DolphinView::Mode::DetailsView); + + QVERIFY(QFile::exists(dotDirectoryFilePath)); +} + +void ViewPropertiesTest::testExtendedAttributeFull() +{ +#ifndef Q_OS_UNIX + QSKIP("Only unix is supported, for this test"); +#endif + QString dotDirectoryFile = m_testDir->url().toLocalFile() + "/.directory"; + QVERIFY(!QFile::exists(dotDirectoryFile)); + + KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile()); + if (!metadata.isSupported()) { + QSKIP("need extended attribute/filesystem metadata to be usefull"); + } + + QStorageInfo storageInfo(m_testDir->url().toLocalFile()); + auto blockSize = storageInfo.blockSize(); + + KFileMetaData::UserMetaData::Error result; + // write a close to block size theorical maximum size for attributes in Linux for ext4 + // and btrfs (4Kib typically) when ReiserFS/XFS allow XATTR_SIZE_MAX (64Kib) + result = metadata.setAttribute("data", QString(blockSize - 50, 'a')); + if (result != KFileMetaData::UserMetaData::NoSpace) { + QSKIP("File system supports metadata bigger than file system block size"); + } + + // write a close to 4k attribute, maximum size in Linux for ext4 + // so next writing the file metadata fails + result = metadata.setAttribute("data", QString(blockSize - 60, 'a')); + QCOMPARE(result, KFileMetaData::UserMetaData::NoError); + + QScopedPointer props(new ViewProperties(m_testDir->url())); + QVERIFY(props->isAutoSaveEnabled()); + props->setSortRole("someNewSortRole"); + props.reset(); + + if (metadata.isSupported()) { + auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(viewProperties.isEmpty()); + QVERIFY(QFile::exists(dotDirectoryFile)); + + QFile dotDirectory(dotDirectoryFile); + KConfig viewSettings(dotDirectoryFile, KConfig::SimpleConfig); + QCOMPARE(viewSettings.groupList(), {"Dolphin"}); + QCOMPARE(viewSettings.group("Dolphin").readEntry("SortRole"), "someNewSortRole"); + } else { + QVERIFY(QFile::exists(dotDirectoryFile)); + } +} + +void ViewPropertiesTest::testUseAsDefaultViewSettings() +{ + // Create a global viewproperties folder + QUrl globalPropertiesPath = + QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).append("/view_properties/").append(QStringLiteral("global"))); + QVERIFY(QDir().mkpath(globalPropertiesPath.toLocalFile())); + auto cleanupGlobalDir = qScopeGuard([globalPropertiesPath] { + QDir().rmdir(globalPropertiesPath.toLocalFile()); + }); + ViewProperties globalProps(globalPropertiesPath); + + // Check that theres no .directory file and metadata is supported + QString dotDirectoryFile = m_testDir->url().toLocalFile() + "/.directory"; + QVERIFY(!QFile::exists(dotDirectoryFile)); + KFileMetaData::UserMetaData testDirMetadata(m_testDir->url().toLocalFile()); + KFileMetaData::UserMetaData globalDirMetadata(globalPropertiesPath.toLocalFile()); + if (!testDirMetadata.isSupported()) { + QSKIP("need extended attribute/filesystem metadata to be usefull"); + } + + const auto newDefaultViewMode = DolphinView::Mode::DetailsView; + + // Equivalent of useAsDefault in ViewPropertiesDialog + // This sets the DetailsView as default viewMode + GeneralSettings::setGlobalViewProps(true); + globalProps.setViewMode(newDefaultViewMode); + globalProps.setDirProperties(globalProps); + globalProps.save(); + GeneralSettings::setGlobalViewProps(false); + + // Load default data + QScopedPointer globalDirProperties(new ViewProperties(globalPropertiesPath)); + auto defaultData = globalDirProperties.data(); + + // Load testdir data + QScopedPointer testDirProperties(new ViewProperties(m_testDir->url())); + auto testData = testDirProperties.data(); + + // Make sure globalDirProperties are not empty, so they will be used + auto globalDirPropString = globalDirMetadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(!globalDirPropString.isEmpty()); + + // Make sure testDirProperties is empty, so default values are used for it + auto testDirPropString = testDirMetadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(testDirPropString.isEmpty()); + + // Compare that default and new folder viewMode is the new default + QCOMPARE(defaultData->viewMode(), newDefaultViewMode); + QCOMPARE(testData->viewMode(), defaultData->viewMode()); +} + +void ViewPropertiesTest::testUseAsCustomDefaultViewSettings() +{ + // Create a global viewproperties folder + QUrl globalPropertiesPath = + QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).append("/view_properties/").append(QStringLiteral("global"))); + QVERIFY(QDir().mkpath(globalPropertiesPath.toLocalFile())); + auto cleanupGlobalDir = qScopeGuard([globalPropertiesPath] { + QDir().rmdir(globalPropertiesPath.toLocalFile()); + }); + ViewProperties globalProps(globalPropertiesPath); + + // Check that theres no .directory file and metadata is supported + QString dotDirectoryFile = m_testDir->url().toLocalFile() + "/.directory"; + QVERIFY(!QFile::exists(dotDirectoryFile)); + KFileMetaData::UserMetaData testDirMetadata(m_testDir->url().toLocalFile()); + KFileMetaData::UserMetaData globalDirMetadata(globalPropertiesPath.toLocalFile()); + if (!testDirMetadata.isSupported()) { + QSKIP("need extended attribute/filesystem metadata to be usefull"); + } + + // Equivalent of useAsDefault in ViewPropertiesDialog + // This sets the DetailsView as default viewMode + GeneralSettings::setGlobalViewProps(true); + globalProps.setViewMode(DolphinView::Mode::DetailsView); + globalProps.setDirProperties(globalProps); + globalProps.save(); + GeneralSettings::setGlobalViewProps(false); + + // Make sure globalDirProperties are not empty, so they will be used + auto globalDirPropString = globalDirMetadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(!globalDirPropString.isEmpty()); + + // Load default data + QScopedPointer globalDirProperties(new ViewProperties(globalPropertiesPath)); + auto defaultData = globalDirProperties.data(); + QCOMPARE(defaultData->viewMode(), DolphinView::Mode::DetailsView); + + // Load testdir data, set to icon, i.e default hardcoded, not current user default + QScopedPointer testDirProperties(new ViewProperties(m_testDir->url())); + testDirProperties->setViewMode(DolphinView::Mode::IconsView); + testDirProperties->save(); + + // testDirProperties is not default + auto testDirPropString = testDirMetadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(!testDirPropString.isEmpty()); + QCOMPARE(testDirProperties.data()->viewMode(), DolphinView::Mode::IconsView); + + // testDirProperties is now default + testDirProperties->setViewMode(DolphinView::Mode::DetailsView); + testDirProperties->save(); + + // no more metedata => the defaults settings are in effect for the folder + testDirPropString = testDirMetadata.attribute(QStringLiteral("kde.fm.viewproperties#1")); + QVERIFY(testDirPropString.isEmpty()); + QCOMPARE(testDirProperties.data()->viewMode(), DolphinView::Mode::DetailsView); } QTEST_GUILESS_MAIN(ViewPropertiesTest)