X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/c7a2e55df95c703749d05022458cb2362fa786bf..a1c9bc5595a21299dab9260c6a77c0561c95c8ba:/src/tests/viewpropertiestest.cpp diff --git a/src/tests/viewpropertiestest.cpp b/src/tests/viewpropertiestest.cpp index 114afdc33..9252f17ba 100644 --- a/src/tests/viewpropertiestest.cpp +++ b/src/tests/viewpropertiestest.cpp @@ -1,45 +1,49 @@ -/*************************************************************************** - * Copyright (C) 2012 by Peter Penz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2012 Peter Penz + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ -#include "dolphin_generalsettings.h" #include "views/viewproperties.h" +#include "dolphin_generalsettings.h" #include "testdir.h" +#include + +#include #include -#include class ViewPropertiesTest : public QObject { Q_OBJECT -private slots: +private Q_SLOTS: + void initTestCase(); void init(); void cleanup(); void testReadOnlyBehavior(); + void testReadOnlyDirectory(); void testAutoSave(); + void testParamMigrationToFileAttr(); + void testParamMigrationToFileAttrKeepDirectory(); + void testExtendedAttributeFull(); + void testUseAsDefaultViewSettings(); + void testUseAsCustomDefaultViewSettings(); private: bool m_globalViewProps; - TestDir* m_testDir; + TestDir *m_testDir; }; +void ViewPropertiesTest::initTestCase() +{ + QStandardPaths::setTestModeEnabled(true); + + GeneralSettings::self()->setViewPropsTimestamp(QDateTime::currentDateTime()); + QVERIFY(GeneralSettings::self()->save()); +} + void ViewPropertiesTest::init() { m_globalViewProps = GeneralSettings::self()->globalViewProps(); @@ -56,7 +60,7 @@ void ViewPropertiesTest::init() void ViewPropertiesTest::cleanup() { delete m_testDir; - m_testDir = 0; + m_testDir = nullptr; GeneralSettings::self()->setGlobalViewProps(m_globalViewProps); GeneralSettings::self()->save(); @@ -75,10 +79,51 @@ void ViewPropertiesTest::testReadOnlyBehavior() QScopedPointer props(new ViewProperties(m_testDir->url())); QVERIFY(props->isAutoSaveEnabled()); const QByteArray sortRole = props->sortRole(); - Q_UNUSED(sortRole); + Q_UNUSED(sortRole) + props.reset(); + + 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() @@ -91,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)