File indexing completed on 2024-05-12 04:19:58

0001 /*
0002 Gwenview: an image viewer
0003 Copyright 2009 Aurélien Gâteau <agateau@kde.org>
0004 
0005 This program is free software; you can redistribute it and/or
0006 modify it under the terms of the GNU General Public License
0007 as published by the Free Software Foundation; either version 2
0008 of the License, or (at your option) any later version.
0009 
0010 This program is distributed in the hope that it will be useful,
0011 but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 GNU General Public License for more details.
0014 
0015 You should have received a copy of the GNU General Public License
0016 along with this program; if not, write to the Free Software
0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0018 
0019 */
0020 #include "importertest.h"
0021 
0022 // stdlib
0023 #include <sys/stat.h>
0024 
0025 // Qt
0026 #include <QDateTime>
0027 #include <QSignalSpy>
0028 #include <QTest>
0029 
0030 // KF
0031 
0032 // Local
0033 #include "../importer/filenameformater.h"
0034 #include "../importer/fileutils.h"
0035 #include "../importer/importer.h"
0036 #include "testutils.h"
0037 
0038 QTEST_MAIN(ImporterTest)
0039 
0040 using namespace Gwenview;
0041 
0042 void ImporterTest::init()
0043 {
0044     mDocumentList = QList<QUrl>() << urlForTestFile("import/pict0001.jpg") << urlForTestFile("import/pict0002.jpg") << urlForTestFile("import/pict0003.jpg");
0045 
0046     mTempDir = std::make_unique<QTemporaryDir>();
0047 }
0048 
0049 void ImporterTest::testContentsAreIdentical()
0050 {
0051     QVERIFY(!FileUtils::contentsAreIdentical(mDocumentList[0], mDocumentList[1]));
0052     QVERIFY(FileUtils::contentsAreIdentical(mDocumentList[0], mDocumentList[0]));
0053 
0054     QUrl url1 = mDocumentList[0];
0055     QUrl url2 = urlForTestOutputFile("foo");
0056 
0057     // Test on a copy of a file
0058     QFile::remove(url2.toLocalFile());
0059     QFile::copy(url1.toLocalFile(), url2.toLocalFile());
0060 
0061     QVERIFY(FileUtils::contentsAreIdentical(url1, url2));
0062 
0063     // Alter one byte of the copy and test again
0064     QFile file(url2.toLocalFile());
0065     QVERIFY(file.open(QIODevice::ReadOnly));
0066     QByteArray data = file.readAll();
0067     file.close();
0068     data[data.size() / 2] = 255 - data[data.size() / 2];
0069 
0070     file.open(QIODevice::WriteOnly);
0071     file.write(data);
0072     file.close();
0073 
0074     QVERIFY(!FileUtils::contentsAreIdentical(url1, url2));
0075 }
0076 
0077 void ImporterTest::testSuccessfulImport()
0078 {
0079     QUrl destUrl = QUrl::fromLocalFile(mTempDir->path() + "/foo");
0080 
0081     Importer importer(nullptr);
0082     QSignalSpy maximumChangedSpy(&importer, SIGNAL(maximumChanged(int)));
0083     QSignalSpy errorSpy(&importer, SIGNAL(error(QString)));
0084 
0085     QList<QUrl> list = mDocumentList;
0086 
0087     QEventLoop loop;
0088     connect(&importer, &Importer::importFinished, &loop, &QEventLoop::quit);
0089     importer.start(list, destUrl);
0090     loop.exec();
0091 
0092     QCOMPARE(maximumChangedSpy.count(), 1);
0093     QCOMPARE(maximumChangedSpy.takeFirst().at(0).toInt(), list.count() * 100);
0094     QCOMPARE(errorSpy.count(), 0);
0095 
0096     QCOMPARE(importer.importedUrlList().count(), list.count());
0097     QCOMPARE(importer.importedUrlList(), list);
0098     QCOMPARE(importer.skippedUrlList().count(), 0);
0099     QCOMPARE(importer.renamedCount(), 0);
0100 
0101     for (const QUrl &src : qAsConst(list)) {
0102         QUrl dst = destUrl;
0103         dst.setPath(dst.path() + '/' + src.fileName());
0104         QVERIFY(FileUtils::contentsAreIdentical(src, dst));
0105     }
0106 }
0107 
0108 void ImporterTest::testSuccessfulImportRemote()
0109 {
0110     // First test import from local to remote
0111     QUrl remoteUrl = setUpRemoteTestDir();
0112     if (!remoteUrl.isValid()) {
0113         QSKIP("Not running this test: failed to setup remote test dir.");
0114     }
0115 
0116     Importer importer(nullptr);
0117     QSignalSpy maximumChangedSpy(&importer, SIGNAL(maximumChanged(int)));
0118     QSignalSpy errorSpy(&importer, SIGNAL(error(QString)));
0119 
0120     QList<QUrl> list = mDocumentList;
0121 
0122     QEventLoop loop;
0123     connect(&importer, &Importer::importFinished, &loop, &QEventLoop::quit);
0124     importer.start(list, remoteUrl);
0125     loop.exec();
0126 
0127     QCOMPARE(maximumChangedSpy.count(), 1);
0128     QCOMPARE(maximumChangedSpy.takeFirst().at(0).toInt(), list.count() * 100);
0129     QCOMPARE(errorSpy.count(), 0);
0130 
0131     QCOMPARE(importer.importedUrlList().count(), list.count());
0132     QCOMPARE(importer.importedUrlList(), list);
0133     QCOMPARE(importer.skippedUrlList().count(), 0);
0134     QCOMPARE(importer.renamedCount(), 0);
0135 
0136     for (const QUrl &src : qAsConst(list)) {
0137         QUrl dst = remoteUrl;
0138         dst.setPath(dst.path() + '/' + src.fileName());
0139         QVERIFY(FileUtils::contentsAreIdentical(src, dst));
0140     }
0141 
0142     // Secondly test import from remote back to local
0143     QUrl localUrl = QUrl::fromLocalFile(mTempDir->path() + "/foo");
0144 
0145     importer.start(list, localUrl);
0146     loop.exec();
0147 
0148     QCOMPARE(maximumChangedSpy.count(), 1);
0149     QCOMPARE(maximumChangedSpy.takeFirst().at(0).toInt(), list.count() * 100);
0150     QCOMPARE(errorSpy.count(), 0);
0151 
0152     QCOMPARE(importer.importedUrlList().count(), list.count());
0153     QCOMPARE(importer.importedUrlList(), list);
0154     QCOMPARE(importer.skippedUrlList().count(), 0);
0155     QCOMPARE(importer.renamedCount(), 0);
0156 
0157     for (const QUrl &src : qAsConst(list)) {
0158         QUrl dst = localUrl;
0159         dst.setPath(dst.path() + '/' + src.fileName());
0160         QVERIFY(FileUtils::contentsAreIdentical(src, dst));
0161     }
0162 }
0163 
0164 void ImporterTest::testSkippedUrlList()
0165 {
0166     QUrl destUrl = QUrl::fromLocalFile(mTempDir->path() + "/foo");
0167 
0168     Importer importer(nullptr);
0169 
0170     QList<QUrl> list = mDocumentList.mid(0, 1);
0171 
0172     QEventLoop loop;
0173     connect(&importer, &Importer::importFinished, &loop, &QEventLoop::quit);
0174     importer.start(list, destUrl);
0175     loop.exec();
0176 
0177     QCOMPARE(importer.importedUrlList().count(), 1);
0178     QCOMPARE(importer.importedUrlList(), list);
0179 
0180     list = mDocumentList;
0181     QList<QUrl> expectedImportedList = mDocumentList.mid(1);
0182     QList<QUrl> expectedSkippedList = mDocumentList.mid(0, 1);
0183     importer.start(list, destUrl);
0184     loop.exec();
0185 
0186     QCOMPARE(importer.importedUrlList().count(), 2);
0187     QCOMPARE(importer.importedUrlList(), expectedImportedList);
0188     QCOMPARE(importer.skippedUrlList(), expectedSkippedList);
0189     QCOMPARE(importer.renamedCount(), 0);
0190 }
0191 
0192 void ImporterTest::testRenamedCount()
0193 {
0194     QUrl destUrl = QUrl::fromLocalFile(mTempDir->path() + "/foo");
0195 
0196     Importer importer(nullptr);
0197 
0198     QList<QUrl> list;
0199     list << mDocumentList.first();
0200 
0201     QEventLoop loop;
0202     connect(&importer, &Importer::importFinished, &loop, &QEventLoop::quit);
0203     importer.start(list, destUrl);
0204     loop.exec();
0205 
0206     QCOMPARE(importer.importedUrlList().count(), 1);
0207     QCOMPARE(importer.importedUrlList(), list);
0208 
0209     // Modify imported document so that next import does not skip it
0210     {
0211         QUrl url = destUrl;
0212         url.setPath(url.path() + '/' + mDocumentList.first().fileName());
0213         QFile file(url.toLocalFile());
0214         QVERIFY(file.open(QIODevice::Append));
0215         file.write("foo");
0216     }
0217 
0218     list = mDocumentList;
0219     importer.start(list, destUrl);
0220     loop.exec();
0221 
0222     QCOMPARE(importer.importedUrlList().count(), 3);
0223     QCOMPARE(importer.importedUrlList(), mDocumentList);
0224     QCOMPARE(importer.skippedUrlList().count(), 0);
0225     QCOMPARE(importer.renamedCount(), 1);
0226 }
0227 
0228 void ImporterTest::testFileNameFormater()
0229 {
0230     QFETCH(QString, fileName);
0231     QFETCH(QString, dateTime);
0232     QFETCH(QString, format);
0233     QFETCH(QString, expected);
0234 
0235     QUrl url = QUrl("file://foo/bar/" + fileName);
0236     FileNameFormater fileNameFormater(format);
0237     QCOMPARE(fileNameFormater.format(url, QDateTime::fromString(dateTime, Qt::ISODate)), expected);
0238 }
0239 
0240 #define NEW_ROW(fileName, dateTime, format, expected) QTest::newRow(fileName) << fileName << dateTime << format << expected
0241 void ImporterTest::testFileNameFormater_data()
0242 {
0243     QTest::addColumn<QString>("fileName");
0244     QTest::addColumn<QString>("dateTime");
0245     QTest::addColumn<QString>("format");
0246     QTest::addColumn<QString>("expected");
0247 
0248     NEW_ROW("PICT0001.JPG", "2009-10-24T22:50:49", "{date}_{time}.{ext}", "2009-10-24_22-50-49.JPG");
0249     NEW_ROW("PICT0001.JPG", "2009-10-24T22:50:49", "{date}_{time}.{ext.lower}", "2009-10-24_22-50-49.jpg");
0250     NEW_ROW("2009.10.24.JPG", "2009-10-24T22:50:49", "{date}_{time}.{ext.lower}", "2009-10-24_22-50-49.jpg");
0251     NEW_ROW("PICT0001.JPG", "2009-10-24T22:50:49", "{name}.{ext}", "PICT0001.JPG");
0252     NEW_ROW("PICT0001.JPG", "2009-10-24T22:50:49", "{name.lower}.{ext.lower}", "pict0001.jpg");
0253     NEW_ROW("iLikeCurlies", "2009-10-24T22:50:49", "{{{name}}", "{iLikeCurlies}");
0254     NEW_ROW("UnknownKeyword", "2009-10-24T22:50:49", "foo{unknown}bar", "foobar");
0255     NEW_ROW("MissingClosingCurly", "2009-10-24T22:50:49", "foo{date", "foo");
0256     NEW_ROW("PICT0001.JPG", "2009-10-24T22:50:49", "{date}/{name}.{ext}", "2009-10-24/PICT0001.JPG");
0257 }
0258 
0259 void ImporterTest::testAutoRenameFormat()
0260 {
0261     QStringList dates = QStringList() << "1979-02-23_10-20-00"
0262                                       << "2006-04-01_11-30-15"
0263                                       << "2009-10-01_21-15-27";
0264     QStringList dates2 = QStringList() << "1979-02-23/10-20-00"
0265                                        << "2006-04-01/11-30-15"
0266                                        << "2009-10-01/21-15-27";
0267     QCOMPARE(dates.count(), mDocumentList.count());
0268     QCOMPARE(dates2.count(), mDocumentList.count());
0269 
0270     QUrl destUrl = QUrl::fromLocalFile(mTempDir->path() + "/foo");
0271 
0272     Importer importer(nullptr);
0273     importer.setAutoRenameFormat("{date}_{time}.{ext}");
0274     QList<QUrl> list = mDocumentList;
0275 
0276     QEventLoop loop;
0277     connect(&importer, &Importer::importFinished, &loop, &QEventLoop::quit);
0278     importer.start(list, destUrl);
0279     loop.exec();
0280 
0281     QCOMPARE(importer.importedUrlList().count(), list.count());
0282     QCOMPARE(importer.importedUrlList(), list);
0283 
0284     for (int pos = 0; pos < dates.count(); ++pos) {
0285         QUrl src = list[pos];
0286         QUrl dst = destUrl;
0287         dst.setPath(dst.path() + '/' + dates[pos] + ".jpg");
0288         QVERIFY(FileUtils::contentsAreIdentical(src, dst));
0289     }
0290 
0291     // Test again with slashes in AutoRenameFormat
0292     importer.setAutoRenameFormat("{date}/{time}.{ext}");
0293     importer.start(list, destUrl);
0294     loop.exec();
0295 
0296     QCOMPARE(importer.importedUrlList().count(), list.count());
0297     QCOMPARE(importer.importedUrlList(), list);
0298 
0299     for (int pos = 0; pos < dates2.count(); ++pos) {
0300         QUrl src = list[pos];
0301         QUrl dst = destUrl;
0302         dst.setPath(dst.path() + '/' + dates2[pos] + ".jpg");
0303         QVERIFY(FileUtils::contentsAreIdentical(src, dst));
0304     }
0305 }
0306 
0307 void ImporterTest::testReadOnlyDestination()
0308 {
0309     QUrl destUrl = QUrl::fromLocalFile(mTempDir->path() + "/foo");
0310     chmod(QFile::encodeName(mTempDir->path()), 0555);
0311 
0312     Importer importer(nullptr);
0313     QSignalSpy errorSpy(&importer, SIGNAL(error(QString)));
0314     importer.start(mDocumentList, destUrl);
0315 
0316     QCOMPARE(errorSpy.count(), 1);
0317     QVERIFY(importer.importedUrlList().isEmpty());
0318 }
0319 
0320 #include "moc_importertest.cpp"