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

0001 /*
0002  * SPDX-FileCopyrightText: 2018 boud <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #include "TestResourceModel.h"
0007 
0008 #include <simpletest.h>
0009 #include <QStandardPaths>
0010 #include <QDir>
0011 #include <QVersionNumber>
0012 #include <QDirIterator>
0013 #include <QSqlError>
0014 #include <QSqlQuery>
0015 #include <QTemporaryFile>
0016 #include <QtSql>
0017 
0018 #include <kconfig.h>
0019 #include <kconfiggroup.h>
0020 #include <ksharedconfig.h>
0021 
0022 #include <KisResourceCacheDb.h>
0023 #include <KisResourceLocator.h>
0024 #include <KisResourceModel.h>
0025 
0026 #include <DummyResource.h>
0027 #include <ResourceTestHelper.h>
0028 
0029 #ifndef FILES_DATA_DIR
0030 #error "FILES_DATA_DIR not set. A directory with the data used for testing installing resources"
0031 #endif
0032 
0033 
0034 void TestResourceModel::initTestCase()
0035 {
0036     ResourceTestHelper::initTestDb();
0037     ResourceTestHelper::createDummyLoaderRegistry();
0038 
0039     m_srcLocation = QString(FILES_DATA_DIR);
0040     QVERIFY2(QDir(m_srcLocation).exists(), m_srcLocation.toUtf8());
0041 
0042     m_dstLocation = ResourceTestHelper::filesDestDir();
0043     ResourceTestHelper::cleanDstLocation(m_dstLocation);
0044 
0045     KConfigGroup cfg(KSharedConfig::openConfig(), "");
0046     cfg.writeEntry(KisResourceLocator::resourceLocationKey, m_dstLocation);
0047 
0048     m_locator = KisResourceLocator::instance();
0049 
0050     if (!KisResourceCacheDb::initialize(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))) {
0051         qWarning() << "Could not initialize KisResourceCacheDb on" << QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
0052     }
0053     QVERIFY(KisResourceCacheDb::isValid());
0054 
0055     KisResourceLocator::LocatorError r = m_locator->initialize(m_srcLocation);
0056     if (!m_locator->errorMessages().isEmpty()) {
0057         qDebug() << m_locator->errorMessages();
0058     }
0059 
0060     QVERIFY(r == KisResourceLocator::LocatorError::Ok);
0061     QVERIFY(QDir(m_dstLocation).exists());
0062 }
0063 
0064 void TestResourceModel::testWithTagModelTester()
0065 {
0066     KisResourceModel model(m_resourceType);
0067     auto tester = new QAbstractItemModelTester(&model);
0068     Q_UNUSED(tester);
0069 }
0070 
0071 
0072 void TestResourceModel::testRowCount()
0073 {
0074     QSqlQuery q;
0075     QVERIFY(q.prepare("SELECT count(*)\n"
0076                       "FROM   resources\n"
0077                       ",      resource_types\n"
0078                       "WHERE  resources.resource_type_id = resource_types.id\n"
0079                       "AND    resource_types.name = :resource_type"));
0080     q.bindValue(":resource_type", m_resourceType);
0081     QVERIFY(q.exec());
0082     q.first();
0083     int rowCount = q.value(0).toInt();
0084     QVERIFY(rowCount == 3);
0085     KisResourceModel resourceModel(m_resourceType);
0086     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0087     QCOMPARE(resourceModel.rowCount(), rowCount);
0088 }
0089 
0090 void TestResourceModel::testData()
0091 {
0092     KisResourceModel resourceModel(m_resourceType);
0093     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0094 
0095     QStringList resourceNames;
0096 
0097     for (int i = 0; i < resourceModel.rowCount(); ++i)  {
0098         QVariant v = resourceModel.data(resourceModel.index(i, KisAbstractResourceModel::Name), Qt::DisplayRole);
0099         resourceNames << v.toString();
0100     }
0101 
0102     QVERIFY(resourceNames.contains("test0.kpp"));
0103     QVERIFY(resourceNames.contains("test1.kpp"));
0104     QVERIFY(resourceNames.contains("test2.kpp"));
0105 }
0106 
0107 
0108 void TestResourceModel::testResourceForIndex()
0109 {
0110     KisResourceModel resourceModel(m_resourceType);
0111     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0112 
0113     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(0, 0));
0114     QVERIFY(resource);
0115     QVERIFY(resource->resourceId() > -1);
0116 }
0117 
0118 void TestResourceModel::testIndexFromResource()
0119 {
0120     KisResourceModel resourceModel(m_resourceType);
0121     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0122 
0123     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(1, 0));
0124     QModelIndex idx = resourceModel.indexForResource(resource);
0125     QVERIFY(idx.row() == 1);
0126     QVERIFY(idx.column() == 0);
0127 }
0128 
0129 void TestResourceModel::testSetInactiveByIndex()
0130 {
0131     KisResourceModel resourceModel(m_resourceType);
0132     int resourceCount = resourceModel.rowCount();
0133     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(0, 0));
0134     bool r = resourceModel.setResourceInactive(resourceModel.index(0, 0));
0135     QVERIFY(r);
0136     QCOMPARE(resourceCount - 1, resourceModel.rowCount());
0137     QVERIFY(!resourceModel.indexForResource(resource).isValid());
0138     QVERIFY(!resourceModel.resourceForId(resource->resourceId()));
0139     QVERIFY(resourceModel.resourcesForName(resource->name()).isEmpty());
0140     // verify that all mapped resources are still reachable by id
0141     for (int i = 0; i < resourceCount - 1; i++) {
0142         KoResourceSP resource2 = resourceModel.resourceForIndex(resourceModel.index(i, 0));
0143         QVERIFY(resource2);
0144         QVERIFY(resourceModel.resourceForId(resource2->resourceId()));
0145     }
0146 }
0147 
0148 void TestResourceModel::testImportResourceFile()
0149 {
0150     KisResourceModel resourceModel(m_resourceType);
0151     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0152 
0153     QTemporaryFile f(QDir::tempPath() + "/testresourcemodel-testimportresourcefile-XXXXXX.kpp");
0154     f.open();
0155     f.write("0");
0156     f.close();
0157 
0158     int resourceCount = resourceModel.rowCount();
0159     bool r = resourceModel.importResourceFile(f.fileName(), false);
0160     QVERIFY(r);
0161     QCOMPARE(resourceModel.rowCount(), resourceCount + 1);
0162 }
0163 
0164 void TestResourceModel::testAddResource()
0165 {
0166     KisResourceModel resourceModel(m_resourceType);
0167     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0168 
0169     int resourceCount = resourceModel.rowCount();
0170     KoResourceSP resource(new DummyResource("dummy.kpp"));
0171     resource->setValid(true);
0172     bool r = resourceModel.addResource(resource);
0173     QVERIFY(r);
0174     QCOMPARE(resourceCount + 1, resourceModel.rowCount());
0175 }
0176 
0177 void TestResourceModel::testAddTemporaryResource()
0178 {
0179     KisResourceModel resourceModel(m_resourceType);
0180     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0181 
0182     int startResourceCount = resourceModel.rowCount();
0183     KoResourceSP resource(new DummyResource("temporaryResource.kpp"));
0184     resource->setValid(true);
0185     bool r = resourceModel.addResource(resource, "memory");
0186     QVERIFY(r);
0187     QCOMPARE(startResourceCount + 1, resourceModel.rowCount());
0188 }
0189 
0190 void TestResourceModel::testAddDuplicatedResource()
0191 {
0192     KisResourceModel resourceModel(m_resourceType);
0193     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0194 
0195     const int startResourceCount = resourceModel.rowCount();
0196 
0197     KoResourceSP resource(new DummyResource("duplicated_resource.kpp"));
0198     resource->setValid(true);
0199     bool r = resourceModel.addResource(resource); // first add to the folder storage
0200 
0201     QVERIFY(r);
0202     QCOMPARE(resourceModel.rowCount(), startResourceCount + 1);
0203 
0204     // Matching MD5, name and filename resources should be hidden -- BUG:445367
0205     // the copy of this resource has been added in testAddResource()
0206     resource.reset(new DummyResource("duplicated_resource.kpp"));
0207     resource->setValid(true);
0208     r = resourceModel.addResource(resource, "memory"); // then add to the temporary storage
0209 
0210     QVERIFY(r);
0211     QCOMPARE(resourceModel.rowCount(), startResourceCount + 1);
0212 }
0213 
0214 void TestResourceModel::testResourceForId()
0215 {
0216     KisResourceModel resourceModel(m_resourceType);
0217     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0218 
0219     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(0, 0));
0220     QVERIFY(!resource.isNull());
0221     KoResourceSP resource2 = resourceModel.resourceForId(resource->resourceId());
0222     QVERIFY(!resource2.isNull());
0223     QCOMPARE(resource, resource2);
0224 }
0225 
0226 void TestResourceModel::testResourceForName()
0227 {
0228     KisResourceModel resourceModel(m_resourceType);
0229     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0230 
0231     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(0, 0));
0232     QVERIFY(!resource.isNull());
0233     KoResourceSP resource2 = resourceModel.resourcesForName(resource->name()).first();
0234     QVERIFY(!resource2.isNull());
0235     QCOMPARE(resource, resource2);
0236 }
0237 
0238 void TestResourceModel::testResourceForFileName()
0239 {
0240     KisResourceModel resourceModel(m_resourceType);
0241     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0242 
0243     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(0, 0));
0244     QVERIFY(!resource.isNull());
0245     KoResourceSP resource2 = resourceModel.resourcesForFilename(resource->filename()).first();
0246     QVERIFY(!resource2.isNull());
0247     QCOMPARE(resource, resource2);
0248 }
0249 
0250 void TestResourceModel::testResourceForMD5()
0251 {
0252     KisResourceModel resourceModel(m_resourceType);
0253     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0254 
0255     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(0, 0));
0256     QVERIFY(!resource.isNull());
0257     QVector<KoResourceSP> v = resourceModel.resourcesForMD5(resource->md5Sum());
0258     KoResourceSP resource2 = v.first();
0259     QVERIFY(!resource2.isNull());
0260     QCOMPARE(resource->md5Sum(), resource2->md5Sum());
0261 }
0262 
0263 void TestResourceModel::testRenameResource()
0264 {
0265     KisResourceModel resourceModel(m_resourceType);
0266     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0267 
0268     KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(1, 0));
0269     QVERIFY(!resource.isNull());
0270     const QString name = resource->name();
0271     bool r = resourceModel.renameResource(resource, "A New Name");
0272     QVERIFY(r);
0273     QSqlQuery q;
0274     if (!q.prepare("SELECT name\n"
0275                    "FROM   resources\n"
0276                    "WHERE  id = :resource_id\n")) {
0277         qWarning() << "Could not prepare testRenameResource Query" << q.lastError();
0278     }
0279 
0280     q.bindValue(":resource_id", resource->resourceId());
0281 
0282     if (!q.exec()) {
0283         qWarning() << "Could not execute testRenameResource Query" << q.lastError();
0284     }
0285 
0286     q.first();
0287     QString newName = q.value(0).toString();
0288     QVERIFY(name != newName);
0289     QCOMPARE("A New Name", newName);
0290 }
0291 
0292 void TestResourceModel::testUpdateResource()
0293 {
0294     int resourceId;
0295     {
0296         KisResourceModel resourceModel(m_resourceType);
0297         resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0298 
0299         KoResourceSP resource = resourceModel.resourceForIndex(resourceModel.index(0, 0));
0300         QVERIFY(resource);
0301         resource.dynamicCast<DummyResource>()->setSomething("It's changed");
0302         resourceId = resource->resourceId();
0303         bool r = resourceModel.updateResource(resource);
0304         QVERIFY(r);
0305     }
0306 
0307     {
0308         // Check the resource itself
0309         KisResourceLocator::instance()->purge("");
0310         KoResourceSP resource = KisResourceLocator::instance()->resourceForId(resourceId);
0311 
0312         QVERIFY(resource);
0313         QCOMPARE(resource.dynamicCast<DummyResource>()->something(), "It's changed");
0314         QVERIFY(resource->resourceId() == resourceId);
0315 
0316         // Check the versions in the database
0317         QSqlQuery q;
0318         QVERIFY(q.prepare("SELECT count(*)\n"
0319                           "FROM   versioned_resources\n"
0320                           "WHERE  resource_id = :resource_id\n"));
0321         q.bindValue(":resource_id", resourceId);
0322         QVERIFY(q.exec());
0323         q.first();
0324         int rowCount = q.value(0).toInt();
0325         QCOMPARE(rowCount, 2);
0326     }
0327 }
0328 
0329 void TestResourceModel::testTwoExistingResourceModels()
0330 {
0331     KisResourceModel resourceModel(m_resourceType);
0332     resourceModel.setResourceFilter(KisResourceModel::ShowAllResources);
0333 
0334     KisResourceModel resourceModelCopy(m_resourceType);
0335     resourceModelCopy.setResourceFilter(KisResourceModel::ShowAllResources);
0336 
0337 
0338     int resourceCount = resourceModel.rowCount();
0339     KoResourceSP resource(new DummyResource("dummy_1.kpp"));
0340     resource->setValid(true);
0341 
0342 
0343     bool r = resourceModel.addResource(resource);
0344     QVERIFY(r);
0345 
0346 
0347     // it only works if you uncomment this line
0348     // but it should work without it
0349     // resourceModelCopy.invalidate();
0350 
0351     QCOMPARE(resourceModel.rowCount(), resourceModelCopy.rowCount());
0352     QCOMPARE(resourceCount + 1, resourceModel.rowCount());
0353     QCOMPARE(resourceCount + 1, resourceModelCopy.rowCount());
0354 }
0355 
0356 
0357 void TestResourceModel::cleanupTestCase()
0358 {
0359     ResourceTestHelper::rmTestDb();
0360     ResourceTestHelper::cleanDstLocation(m_dstLocation);
0361 }
0362 
0363 
0364 SIMPLE_TEST_MAIN(TestResourceModel)
0365