File indexing completed on 2024-12-22 04:12:00

0001 /*
0002  * SPDX-FileCopyrightText: 2018 boud <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #ifndef RESOURCETESTHELPER_H
0007 #define RESOURCETESTHELPER_H
0008 
0009 #include <QImageReader>
0010 #include <QDir>
0011 #include <QStandardPaths>
0012 #include <QDirIterator>
0013 
0014 #include <KisMimeDatabase.h>
0015 #include <KisResourceLoaderRegistry.h>
0016 
0017 #include <KisResourceCacheDb.h>
0018 #include "KisResourceTypes.h"
0019 #include <DummyResource.h>
0020 #include <KisStoragePlugin.h>
0021 #include <simpletest.h>
0022 #include "kis_debug.h"
0023 
0024 #ifndef FILES_DATA_DIR
0025 #error "FILES_DATA_DIR not set. A directory with the data used for testing installing resources"
0026 #endif
0027 
0028 namespace ResourceTestHelper {
0029 
0030 const QString &filesDestDir() {
0031     static const QString s_path = QDir::cleanPath(
0032             QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/testdest") + '/';
0033     return s_path;
0034 }
0035 
0036 void rmTestDb() {
0037     QDir dbLocation(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
0038     QFile(dbLocation.path() + "/" + KisResourceCacheDb::resourceCacheDbFilename).remove();
0039     dbLocation.rmpath(dbLocation.path());
0040 }
0041 
0042 
0043 class KisDummyResourceLoader : public KisResourceLoaderBase {
0044 public:
0045     KisDummyResourceLoader(const QString &id, const QString &folder, const QString &name, const QStringList &mimetypes)
0046         : KisResourceLoaderBase(id, folder, name, mimetypes)
0047     {
0048     }
0049 
0050     virtual KoResourceSP create(const QString &name)
0051     {
0052         QSharedPointer<DummyResource> resource = QSharedPointer<DummyResource>::create(name, resourceType());
0053         return resource;
0054     }
0055 };
0056 
0057 void createDummyLoaderRegistry() {
0058 
0059     KisResourceLoaderRegistry *reg = KisResourceLoaderRegistry::instance();
0060     reg->add(new KisDummyResourceLoader(ResourceType::PaintOpPresets, ResourceType::PaintOpPresets,  i18n("Brush presets"), QStringList() << "application/x-krita-paintoppreset"));
0061     reg->add(new KisDummyResourceLoader(ResourceSubType::GbrBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush"));
0062     reg->add(new KisDummyResourceLoader(ResourceSubType::GihBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush-animated"));
0063     reg->add(new KisDummyResourceLoader(ResourceSubType::SvgBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/svg+xml"));
0064     reg->add(new KisDummyResourceLoader(ResourceSubType::PngBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/png"));
0065     reg->add(new KisDummyResourceLoader(ResourceSubType::SegmentedGradients, ResourceType::Gradients, i18n("Gradients"), QStringList() << "application/x-gimp-gradient"));
0066     reg->add(new KisDummyResourceLoader(ResourceSubType::StopGradients, ResourceType::Gradients, i18n("Gradients"), QStringList() << "image/svg+xml"));
0067     reg->add(new KisDummyResourceLoader(ResourceType::Palettes, ResourceType::Palettes, i18n("Palettes"),
0068                                         QStringList() << KisMimeDatabase::mimeTypeForSuffix("kpl")
0069                                         << KisMimeDatabase::mimeTypeForSuffix("gpl")
0070                                         << KisMimeDatabase::mimeTypeForSuffix("pal")
0071                                         << KisMimeDatabase::mimeTypeForSuffix("act")
0072                                         << KisMimeDatabase::mimeTypeForSuffix("aco")
0073                                         << KisMimeDatabase::mimeTypeForSuffix("css")
0074                                         << KisMimeDatabase::mimeTypeForSuffix("colors")
0075                                         << KisMimeDatabase::mimeTypeForSuffix("xml")
0076                                         << KisMimeDatabase::mimeTypeForSuffix("sbz")));
0077 
0078     QList<QByteArray> src = QImageReader::supportedMimeTypes();
0079     QStringList allImageMimes;
0080     Q_FOREACH(const QByteArray ba, src) {
0081         allImageMimes << QString::fromUtf8(ba);
0082     }
0083     allImageMimes << KisMimeDatabase::mimeTypeForSuffix("pat");
0084 
0085     reg->add(new KisDummyResourceLoader(ResourceType::Patterns, ResourceType::Patterns, i18n("Patterns"), allImageMimes));
0086     reg->add(new KisDummyResourceLoader(ResourceType::Workspaces, ResourceType::Workspaces, i18n("Workspaces"), QStringList() << "application/x-krita-workspace"));
0087     reg->add(new KisDummyResourceLoader(ResourceType::Symbols, ResourceType::Symbols, i18n("SVG symbol libraries"), QStringList() << "image/svg+xml"));
0088     reg->add(new KisDummyResourceLoader(ResourceType::WindowLayouts, ResourceType::WindowLayouts, i18n("Window layouts"), QStringList() << "application/x-krita-windowlayout"));
0089     reg->add(new KisDummyResourceLoader(ResourceType::Sessions, ResourceType::Sessions, i18n("Sessions"), QStringList() << "application/x-krita-session"));
0090     reg->add(new KisDummyResourceLoader(ResourceType::GamutMasks, ResourceType::GamutMasks, i18n("Gamut masks"), QStringList() << "application/x-krita-gamutmask"));
0091 
0092 }
0093 
0094 bool cleanDstLocation(const QString &dstLocation)
0095 {
0096     if (QDir(dstLocation).exists()) {
0097         {
0098             QDirIterator iter(dstLocation, QStringList() << "*", QDir::Files, QDirIterator::Subdirectories);
0099             while (iter.hasNext()) {
0100                 iter.next();
0101                 QFile f(iter.filePath());
0102                 f.remove();
0103                 //qDebug() << (r ? "Removed" : "Failed to remove") << iter.filePath();
0104             }
0105         }
0106         {
0107             QDirIterator iter(dstLocation, QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
0108             while (iter.hasNext()) {
0109                 iter.next();
0110                 QDir(iter.filePath()).rmdir(iter.filePath());
0111                 //qDebug() << (r ? "Removed" : "Failed to remove") << iter.filePath();
0112             }
0113         }
0114 
0115         return QDir().rmpath(dstLocation);
0116     }
0117     return true;
0118 }
0119 
0120 void initTestDb()
0121 {
0122     rmTestDb();
0123     cleanDstLocation(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
0124 }
0125 
0126 void overrideResourceVersion(KoResourceSP resource, int version)
0127 {
0128     resource->setVersion(version);
0129 }
0130 
0131 void testVersionedStorage(KisStoragePlugin &storage, const QString &resourceType, const QString &resourceUrl, const QString &optionalFolderCheck = QString())
0132 {
0133     const QFileInfo fileInfo(resourceUrl);
0134 
0135     auto verifyFileExists = [optionalFolderCheck, resourceType] (KoResourceSP res) {
0136         if (optionalFolderCheck.isEmpty()) return;
0137 
0138         const QString filePath = optionalFolderCheck + "/" + resourceType + "/" + res->filename();
0139 
0140         if (!QFileInfo(filePath).exists()) {
0141             qWarning() << "Couldn't find a file in the resource storage:";
0142             qWarning() << "    " << ppVar(res->filename());
0143             qWarning() << "    " << ppVar(optionalFolderCheck);
0144             qWarning() << "    " << ppVar(filePath);
0145         }
0146 
0147         QVERIFY(QFileInfo(filePath).exists());
0148     };
0149 
0150     KoResourceSP res1 = storage.resource(resourceUrl);
0151     QCOMPARE(res1->filename(), fileInfo.fileName()); // filenames are not URLs
0152     QCOMPARE(res1->version(), -1); // storages don't work with versions
0153     QCOMPARE(res1->valid(), true);
0154 
0155     const QString originalSomething = res1.dynamicCast<DummyResource>()->something();
0156 
0157     KoResourceSP res2 = storage.resource(resourceUrl);
0158     QCOMPARE(res2->filename(), fileInfo.fileName());
0159     QCOMPARE(res2->version(), -1); // storages don't work with versions
0160     QCOMPARE(res2->valid(), true);
0161 
0162     QVERIFY(res1 != res2);
0163 
0164     res2.dynamicCast<DummyResource>()->setSomething("It's changed");
0165     QCOMPARE(res1.dynamicCast<DummyResource>()->something(), originalSomething);
0166     QCOMPARE(res2.dynamicCast<DummyResource>()->something(), "It's changed");
0167 
0168     KoResourceSP res3 = storage.resource(resourceUrl);
0169     QCOMPARE(res3->filename(), fileInfo.fileName());
0170     QCOMPARE(res3->version(), -1); // storages don't work with versions
0171     QCOMPARE(res3->valid(), true);
0172     QCOMPARE(res3.dynamicCast<DummyResource>()->something(), originalSomething);
0173 
0174     const QString versionedName = fileInfo.baseName() + ".0001." + fileInfo.suffix();
0175 
0176     storage.saveAsNewVersion(resourceType, res2);
0177     QCOMPARE(res2->filename(), versionedName);
0178     QCOMPARE(res2->version(), -1); // storages don't work with versions
0179     QCOMPARE(res2->valid(), true);
0180     verifyFileExists(res2);
0181 
0182     KoResourceSP res4 = storage.resource(resourceType + "/" + versionedName);
0183     QCOMPARE(res4->filename(), versionedName);
0184     QCOMPARE(res4->version(), -1); // storages don't work with versions
0185     QCOMPARE(res4->valid(), true);
0186     QCOMPARE(res4.dynamicCast<DummyResource>()->something(), "It's changed");
0187     verifyFileExists(res4);
0188 
0189     overrideResourceVersion(res4, 10000);
0190     storage.saveAsNewVersion(resourceType, res4);
0191     QCOMPARE(res4->filename(), fileInfo.baseName() + ".10000." + fileInfo.suffix());
0192     verifyFileExists(res4);
0193 
0194     overrideResourceVersion(res4, -1);
0195     const QString versionedName2 = fileInfo.baseName() + ".10001." + fileInfo.suffix();
0196 
0197     storage.saveAsNewVersion(resourceType, res4);
0198     QCOMPARE(res4->filename(), versionedName2);
0199     QCOMPARE(res4->version(), -1); // storages don't work with versions
0200     QCOMPARE(res4->valid(), true);
0201     verifyFileExists(res4);
0202 }
0203 
0204 void testVersionedStorageIterator(KisStoragePlugin &storage, const QString &resourceType, const QString &resourceUrl)
0205 {
0206     const QString basename = QFileInfo(resourceUrl).baseName();
0207 
0208     QSharedPointer<KisResourceStorage::ResourceIterator> iter = storage.resources(resourceType);
0209     QVERIFY(iter->hasNext());
0210     int count = 0;
0211     int numVersions = 0;
0212     while (iter->hasNext()) {
0213         iter->next();
0214 
0215         //qDebug() << iter->url() << ppVar(iter->guessedVersion()) << ppVar(iter->lastModified());
0216 
0217         if (iter->url().contains(basename)) {
0218 
0219             // because of versioning, the URL should have been changed
0220             QVERIFY(iter->url() != resourceUrl);
0221 
0222             //qDebug() << iter->url() << ppVar(iter->guessedVersion()) << ppVar(iter->lastModified());
0223 
0224             count++;
0225 
0226             auto verIt = iter->versions();
0227             while (verIt->hasNext()) {
0228                 verIt->next();
0229 
0230                 qDebug() << verIt->url() << ppVar(verIt->guessedVersion());
0231                 numVersions++;
0232                 QVERIFY(verIt->url().contains(basename));
0233             }
0234         }
0235 
0236         KoResourceSP res = iter->resource();
0237         QVERIFY(res);
0238     }
0239 
0240     QCOMPARE(count, 1);
0241     QCOMPARE(numVersions, 4);
0242 };
0243 
0244 }
0245 
0246 #endif // RESOURCETESTHELPER_H