]> cloud.milkyroute.net Git - dolphin.git/blob - src/tests/viewpropertiestest.cpp
dolphinview: Update thumbnail on filename change
[dolphin.git] / src / tests / viewpropertiestest.cpp
1 /*
2 * SPDX-FileCopyrightText: 2012 Peter Penz <peter.penz19@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "views/viewproperties.h"
8 #include "dolphin_generalsettings.h"
9 #include "testdir.h"
10
11 #include <KFileMetaData/UserMetaData>
12
13 #include <QStorageInfo>
14 #include <QTest>
15
16 class ViewPropertiesTest : public QObject
17 {
18 Q_OBJECT
19
20 private Q_SLOTS:
21 void initTestCase();
22 void init();
23 void cleanup();
24
25 void testReadOnlyBehavior();
26 void testReadOnlyDirectory();
27 void testAutoSave();
28 void testParamMigrationToFileAttr();
29 void testParamMigrationToFileAttrKeepDirectory();
30 void testExtendedAttributeFull();
31 void testUseAsDefaultViewSettings();
32
33 private:
34 bool m_globalViewProps;
35 TestDir *m_testDir;
36 };
37
38 void ViewPropertiesTest::initTestCase()
39 {
40 QStandardPaths::setTestModeEnabled(true);
41
42 GeneralSettings::self()->setViewPropsTimestamp(QDateTime::currentDateTime());
43 QVERIFY(GeneralSettings::self()->save());
44 }
45
46 void ViewPropertiesTest::init()
47 {
48 m_globalViewProps = GeneralSettings::self()->globalViewProps();
49 GeneralSettings::self()->setGlobalViewProps(false);
50 GeneralSettings::self()->save();
51
52 // It is mandatory to create the test-directory inside the home-directory
53 // of the user: ViewProperties does not write inside directories
54 // outside the home-directory to prevent overwriting other user-settings
55 // in case if write-permissions are given.
56 m_testDir = new TestDir(QDir::homePath() + "/.viewPropertiesTest-");
57 }
58
59 void ViewPropertiesTest::cleanup()
60 {
61 delete m_testDir;
62 m_testDir = nullptr;
63
64 GeneralSettings::self()->setGlobalViewProps(m_globalViewProps);
65 GeneralSettings::self()->save();
66 }
67
68 /**
69 * Test whether only reading properties won't result in creating
70 * a .directory file when destructing the ViewProperties instance
71 * and autosaving is enabled.
72 */
73 void ViewPropertiesTest::testReadOnlyBehavior()
74 {
75 QString dotDirectoryFile = m_testDir->url().toLocalFile() + "/.directory";
76 QVERIFY(!QFile::exists(dotDirectoryFile));
77
78 QScopedPointer<ViewProperties> props(new ViewProperties(m_testDir->url()));
79 QVERIFY(props->isAutoSaveEnabled());
80 const QByteArray sortRole = props->sortRole();
81 Q_UNUSED(sortRole)
82 props.reset();
83
84 QVERIFY(!QFile::exists(dotDirectoryFile));
85 }
86
87 void ViewPropertiesTest::testReadOnlyDirectory()
88 {
89 const QUrl testDirUrl = m_testDir->url();
90 const QString localFolder = testDirUrl.toLocalFile();
91 const QString dotDirectoryFile = localFolder + "/.directory";
92 QVERIFY(!QFile::exists(dotDirectoryFile));
93
94 // restrict write permissions
95 QVERIFY(QFile(localFolder).setPermissions(QFileDevice::ReadOwner));
96
97 QScopedPointer<ViewProperties> props(new ViewProperties(testDirUrl));
98 const QString destinationDir = props->destinationDir(QStringLiteral("local")) + localFolder;
99
100 QVERIFY(props->isAutoSaveEnabled());
101 props->setSortRole("someNewSortRole");
102 props.reset();
103
104 qDebug() << destinationDir;
105 QVERIFY(QDir(destinationDir).exists());
106
107 QVERIFY(!QFile::exists(dotDirectoryFile));
108 KFileMetaData::UserMetaData metadata(localFolder);
109 const QString viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1"));
110 QVERIFY(viewProperties.isEmpty());
111
112 props.reset(new ViewProperties(testDirUrl));
113 QVERIFY(props->isAutoSaveEnabled());
114 QCOMPARE(props->sortRole(), "someNewSortRole");
115 props.reset();
116
117 metadata = KFileMetaData::UserMetaData(destinationDir);
118 if (metadata.isSupported()) {
119 QVERIFY(metadata.hasAttribute("kde.fm.viewproperties#1"));
120 } else {
121 QVERIFY(QFile::exists(destinationDir + "/.directory"));
122 }
123
124 // un-restrict write permissions
125 QFile(localFolder).setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner);
126 }
127
128 void ViewPropertiesTest::testAutoSave()
129 {
130 QString dotDirectoryFile = m_testDir->url().toLocalFile() + "/.directory";
131 QVERIFY(!QFile::exists(dotDirectoryFile));
132
133 QScopedPointer<ViewProperties> props(new ViewProperties(m_testDir->url()));
134 QVERIFY(props->isAutoSaveEnabled());
135 props->setSortRole("someNewSortRole");
136 props.reset();
137
138 KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile());
139 if (metadata.isSupported()) {
140 auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1"));
141 QVERIFY(!viewProperties.isEmpty());
142 QVERIFY(!QFile::exists(dotDirectoryFile));
143 } else {
144 QVERIFY(QFile::exists(dotDirectoryFile));
145 }
146 }
147
148 void ViewPropertiesTest::testParamMigrationToFileAttr()
149 {
150 QString dotDirectoryFilePath = m_testDir->url().toLocalFile() + "/.directory";
151 QVERIFY(!QFile::exists(dotDirectoryFilePath));
152
153 const char *settingsContent = R"SETTINGS("
154 [Dolphin]
155 Version=4
156 ViewMode=1
157 Timestamp=2023,12,29,10,44,15.793
158 VisibleRoles=text,CustomizedDetails,Details_text,Details_modificationtime,Details_type
159
160 [Settings]
161 HiddenFilesShown=true)SETTINGS";
162 auto dotDirectoryFile = QFile(dotDirectoryFilePath);
163 QVERIFY(dotDirectoryFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate));
164 QTextStream out(&dotDirectoryFile);
165 out << settingsContent;
166 dotDirectoryFile.close();
167
168 KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile());
169 {
170 QScopedPointer<ViewProperties> props(new ViewProperties(m_testDir->url()));
171 QCOMPARE(props->viewMode(), DolphinView::Mode::DetailsView);
172 QVERIFY(props->hiddenFilesShown());
173 props->save();
174
175 if (metadata.isSupported()) {
176 auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1"));
177 QVERIFY(!viewProperties.isEmpty());
178 QVERIFY(!QFile::exists(dotDirectoryFilePath));
179 } else {
180 QVERIFY(QFile::exists(dotDirectoryFilePath));
181 }
182 }
183
184 ViewProperties props(m_testDir->url());
185 QCOMPARE(props.viewMode(), DolphinView::Mode::DetailsView);
186 QVERIFY(props.hiddenFilesShown());
187 }
188
189 void ViewPropertiesTest::testParamMigrationToFileAttrKeepDirectory()
190 {
191 QString dotDirectoryFilePath = m_testDir->url().toLocalFile() + "/.directory";
192 QVERIFY(!QFile::exists(dotDirectoryFilePath));
193
194 const char *settingsContent = R"SETTINGS("
195 [Dolphin]
196 Version=4
197 ViewMode=1
198 Timestamp=2023,12,29,10,44,15.793
199 VisibleRoles=text,CustomizedDetails,Details_text,Details_modificationtime,Details_type
200
201 [Settings]
202 HiddenFilesShown=true
203
204 [Other]
205 ThoseShouldBeKept=true
206 )SETTINGS";
207 auto dotDirectoryFile = QFile(dotDirectoryFilePath);
208 QVERIFY(dotDirectoryFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate));
209 QTextStream out(&dotDirectoryFile);
210 out << settingsContent;
211 dotDirectoryFile.close();
212
213 KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile());
214 {
215 QScopedPointer<ViewProperties> props(new ViewProperties(m_testDir->url()));
216 QCOMPARE(props->viewMode(), DolphinView::Mode::DetailsView);
217 QVERIFY(props->hiddenFilesShown());
218 props->save();
219
220 if (metadata.isSupported()) {
221 auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1"));
222 QVERIFY(!viewProperties.isEmpty());
223 }
224
225 QVERIFY(QFile::exists(dotDirectoryFilePath));
226 KConfig directorySettings(dotDirectoryFilePath, KConfig::SimpleConfig);
227 QCOMPARE(directorySettings.groupList(), {"Other"});
228 }
229
230 ViewProperties props(m_testDir->url());
231 QVERIFY(props.hiddenFilesShown());
232 QCOMPARE(props.viewMode(), DolphinView::Mode::DetailsView);
233
234 QVERIFY(QFile::exists(dotDirectoryFilePath));
235 }
236
237 void ViewPropertiesTest::testExtendedAttributeFull()
238 {
239 #ifndef Q_OS_UNIX
240 QSKIP("Only unix is supported, for this test");
241 #endif
242 QString dotDirectoryFile = m_testDir->url().toLocalFile() + "/.directory";
243 QVERIFY(!QFile::exists(dotDirectoryFile));
244
245 KFileMetaData::UserMetaData metadata(m_testDir->url().toLocalFile());
246 if (!metadata.isSupported()) {
247 QSKIP("need extended attribute/filesystem metadata to be usefull");
248 }
249
250 QStorageInfo storageInfo(m_testDir->url().toLocalFile());
251 auto blockSize = storageInfo.blockSize();
252
253 KFileMetaData::UserMetaData::Error result;
254 // write a close to block size theorical maximum size for attributes in Linux for ext4
255 // and btrfs (4Kib typically) when ReiserFS/XFS allow XATTR_SIZE_MAX (64Kib)
256 result = metadata.setAttribute("data", QString(blockSize - 50, 'a'));
257 if (result != KFileMetaData::UserMetaData::NoSpace) {
258 QSKIP("File system supports metadata bigger than file system block size");
259 }
260
261 // write a close to 4k attribute, maximum size in Linux for ext4
262 // so next writing the file metadata fails
263 result = metadata.setAttribute("data", QString(blockSize - 60, 'a'));
264 QCOMPARE(result, KFileMetaData::UserMetaData::NoError);
265
266 QScopedPointer<ViewProperties> props(new ViewProperties(m_testDir->url()));
267 QVERIFY(props->isAutoSaveEnabled());
268 props->setSortRole("someNewSortRole");
269 props.reset();
270
271 if (metadata.isSupported()) {
272 auto viewProperties = metadata.attribute(QStringLiteral("kde.fm.viewproperties#1"));
273 QVERIFY(viewProperties.isEmpty());
274 QVERIFY(QFile::exists(dotDirectoryFile));
275
276 QFile dotDirectory(dotDirectoryFile);
277 KConfig viewSettings(dotDirectoryFile, KConfig::SimpleConfig);
278 QCOMPARE(viewSettings.groupList(), {"Dolphin"});
279 QCOMPARE(viewSettings.group("Dolphin").readEntry("SortRole"), "someNewSortRole");
280 } else {
281 QVERIFY(QFile::exists(dotDirectoryFile));
282 }
283 }
284
285 void ViewPropertiesTest::testUseAsDefaultViewSettings()
286 {
287 // Create new test directory for this test to make sure the settings are defaults
288 auto testDir = new TestDir(QDir::homePath() + "/.viewPropertiesTest-");
289 auto cleanupTestDir = qScopeGuard([testDir] {
290 delete testDir;
291 });
292
293 // Create a global viewproperties folder
294 QUrl globalPropertiesPath =
295 QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation).append("/view_properties/").append(QStringLiteral("global")));
296 QVERIFY(QDir().mkpath(globalPropertiesPath.toLocalFile()));
297 auto cleanupGlobalDir = qScopeGuard([globalPropertiesPath] {
298 QDir().rmdir(globalPropertiesPath.toLocalFile());
299 });
300 ViewProperties globalProps(globalPropertiesPath);
301
302 // Check that theres no .directory file and metadata is supported
303 QString dotDirectoryFile = testDir->url().toLocalFile() + "/.directory";
304 QVERIFY(!QFile::exists(dotDirectoryFile));
305 KFileMetaData::UserMetaData testDirMetadata(testDir->url().toLocalFile());
306 KFileMetaData::UserMetaData globalDirMetadata(globalPropertiesPath.toLocalFile());
307 if (!testDirMetadata.isSupported()) {
308 QSKIP("need extended attribute/filesystem metadata to be usefull");
309 }
310
311 const auto newDefaultViewMode = DolphinView::Mode::DetailsView;
312
313 // Equivalent of useAsDefault in ViewPropertiesDialog
314 // This sets the DetailsView as default viewMode
315 GeneralSettings::setGlobalViewProps(true);
316 globalProps.setViewMode(newDefaultViewMode);
317 globalProps.setDirProperties(globalProps);
318 globalProps.save();
319 GeneralSettings::setGlobalViewProps(false);
320
321 // Load default data
322 QScopedPointer<ViewProperties> globalDirProperties(new ViewProperties(globalPropertiesPath));
323 auto defaultData = globalDirProperties.data();
324
325 // Load testdir data
326 QScopedPointer<ViewProperties> testDirProperties(new ViewProperties(testDir->url()));
327 auto testData = testDirProperties.data();
328
329 // Make sure globalDirProperties are not empty, so they will be used
330 auto globalDirPropString = globalDirMetadata.attribute(QStringLiteral("kde.fm.viewproperties#1"));
331 QVERIFY(!globalDirPropString.isEmpty());
332
333 // Make sure testDirProperties is empty, so default values are used for it
334 auto testDirPropString = testDirMetadata.attribute(QStringLiteral("kde.fm.viewproperties#1"));
335 QVERIFY(testDirPropString.isEmpty());
336
337 // Compare that default and new folder viewMode is the new default
338 QCOMPARE(defaultData->viewMode(), newDefaultViewMode);
339 QCOMPARE(testData->viewMode(), defaultData->viewMode());
340 }
341
342 QTEST_GUILESS_MAIN(ViewPropertiesTest)
343
344 #include "viewpropertiestest.moc"