File indexing completed on 2024-04-21 03:53:38

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2006 Jacob R Rideout <kde@jacobrideout.net>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kautosavefiletest.h"
0009 
0010 #include <QFile>
0011 #include <QTextStream>
0012 #include <QtAlgorithms>
0013 
0014 #include <QTemporaryFile>
0015 #include <kautosavefile.h>
0016 
0017 #include <QTest>
0018 
0019 QTEST_MAIN(KAutoSaveFileTest)
0020 
0021 void KAutoSaveFileTest::initTestCase()
0022 {
0023     QCoreApplication::instance()->setApplicationName(QLatin1String("qttest")); // TODO do this in qtestlib itself
0024 }
0025 
0026 void KAutoSaveFileTest::cleanupTestCase()
0027 {
0028     for (const QString &fileToRemove : std::as_const(filesToRemove)) {
0029         QFile::remove(fileToRemove);
0030     }
0031 }
0032 
0033 void KAutoSaveFileTest::test_readWrite()
0034 {
0035     QTemporaryFile file;
0036 
0037     QVERIFY(file.open());
0038 
0039     QUrl normalFile = QUrl::fromLocalFile(QFileInfo(file).absoluteFilePath());
0040 
0041     // Test basic functionality
0042     KAutoSaveFile saveFile(normalFile);
0043 
0044     QVERIFY(!QFile::exists(saveFile.fileName()));
0045     QVERIFY(saveFile.open(QIODevice::ReadWrite));
0046 
0047     QString inText = QString::fromLatin1("This is test data one.\n");
0048 
0049     {
0050         QTextStream ts(&saveFile);
0051         ts << inText;
0052         ts.flush();
0053     }
0054 
0055     saveFile.close();
0056 
0057     {
0058         QFile testReader(saveFile.fileName());
0059         testReader.open(QIODevice::ReadWrite);
0060         QTextStream ts(&testReader);
0061 
0062         QString outText = ts.readAll();
0063 
0064         QCOMPARE(outText, inText);
0065     }
0066 
0067     filesToRemove << file.fileName();
0068 }
0069 
0070 void KAutoSaveFileTest::test_fileNameMaxLength()
0071 {
0072     // In KAutoSaveFilePrivate::tempFile() the name of the kautosavefile that's going to be created
0073     // is concatanated in the form:
0074     // fileName + junk.truncated + protocol + _ + path.truncated + junk
0075     // see tempFile() for details.
0076     //
0077     // Make sure that the generated filename (e.g. as you would get from QUrl::fileName()) doesn't
0078     // exceed NAME_MAX (the maximum length allowed for filenames, see e.g. /usr/include/linux/limits.h)
0079     // otherwise the file can't be opened.
0080     //
0081     // see https://phabricator.kde.org/D24489
0082 
0083     QString s;
0084     s.fill(QLatin1Char('b'), 80);
0085     // create a long path that:
0086     // - exceeds NAME_MAX (255)
0087     // - is less than the maximum allowed path length, PATH_MAX (4096)
0088     //   see e.g. /usr/include/linux/limits.h
0089     const QString path = QDir::tempPath() + QLatin1Char('/') + s + QLatin1Char('/') + s + QLatin1Char('/') + s + QLatin1Char('/') + s;
0090 
0091     QFile file(path + QLatin1Char('/') + QLatin1String("testFile.txt"));
0092 
0093     QUrl normalFile = QUrl::fromLocalFile(file.fileName());
0094 
0095     KAutoSaveFile saveFile(normalFile);
0096 
0097     QVERIFY(!QFile::exists(saveFile.fileName()));
0098     QVERIFY(saveFile.open(QIODevice::ReadWrite));
0099 
0100     filesToRemove << file.fileName();
0101 }
0102 
0103 void KAutoSaveFileTest::test_fileStaleFiles()
0104 {
0105     QUrl normalFile = QUrl::fromLocalFile(QDir::temp().absoluteFilePath(QStringLiteral("test directory/tîst me.txt")));
0106 
0107     KAutoSaveFile saveFile(normalFile);
0108     QVERIFY(saveFile.open(QIODevice::ReadWrite));
0109     saveFile.write("testdata");
0110 
0111     // Make sure the stale file is found
0112 
0113     const auto listOfStaleFiles = saveFile.staleFiles(normalFile, QStringLiteral("qttest"));
0114     QVERIFY(listOfStaleFiles.count() == 1);
0115     saveFile.releaseLock();
0116     qDeleteAll(listOfStaleFiles);
0117 
0118     // Make sure the stale file is deleted
0119 
0120     QVERIFY(saveFile.staleFiles(normalFile, QStringLiteral("qttest")).isEmpty());
0121 }
0122 
0123 void KAutoSaveFileTest::test_applicationStaleFiles()
0124 {
0125     // TODO
0126 }
0127 
0128 void KAutoSaveFileTest::test_locking()
0129 {
0130     QUrl normalFile(QString::fromLatin1("fish://user@example.com/home/remote/test.txt"));
0131 
0132     KAutoSaveFile saveFile(normalFile);
0133 
0134     QVERIFY(!QFile::exists(saveFile.fileName()));
0135     QVERIFY(saveFile.open(QIODevice::ReadWrite));
0136 
0137     const QList<KAutoSaveFile *> staleFiles(KAutoSaveFile::staleFiles(normalFile));
0138 
0139     QVERIFY(!staleFiles.isEmpty());
0140 
0141     KAutoSaveFile *saveFile2 = staleFiles.at(0);
0142 
0143     const QString fn = saveFile2->fileName();
0144     // It looks like $XDG_DATA_HOME/stalefiles/qttest/test.txtXXXfish_%2Fhome%2FremoteXXXXXXX
0145     QVERIFY2(fn.contains(QLatin1String("stalefiles/qttest/test.txt")), qPrintable(fn));
0146     QVERIFY2(fn.contains(QLatin1String("fish_%2Fhome%2Fremote")), qPrintable(fn));
0147 
0148     QVERIFY(QFile::exists(saveFile2->fileName()));
0149     QVERIFY(!saveFile2->open(QIODevice::ReadWrite));
0150 
0151     saveFile.releaseLock();
0152 
0153     QVERIFY(saveFile2->open(QIODevice::ReadWrite));
0154 
0155     qDeleteAll(staleFiles);
0156 }
0157 
0158 #include "moc_kautosavefiletest.cpp"