File indexing completed on 2024-04-28 05:45:19

0001 /*
0002  * SPDX-FileCopyrightText: 2019 Ismael Asensio <isma.af@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "search/dolphinquery.h"
0008 
0009 #include <QTest>
0010 
0011 #include <QJsonDocument>
0012 #include <QJsonObject>
0013 #include <QStandardPaths>
0014 #include <QStringList>
0015 #include <QUrl>
0016 #include <QUrlQuery>
0017 
0018 class DolphinQueryTest : public QObject
0019 {
0020     Q_OBJECT
0021 
0022 private Q_SLOTS:
0023     void initTestCase();
0024     void testBalooSearchParsing_data();
0025     void testBalooSearchParsing();
0026 };
0027 
0028 /**
0029  * Helper function to compose the baloo query URL used for searching
0030  */
0031 QUrl balooQueryUrl(const QString &searchString)
0032 {
0033     const QJsonObject jsonObject{{"searchString", searchString}};
0034 
0035     const QJsonDocument doc(jsonObject);
0036     const QString queryString = QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
0037 
0038     QUrlQuery urlQuery;
0039     urlQuery.addQueryItem(QStringLiteral("json"), queryString);
0040 
0041     QUrl searchUrl;
0042     searchUrl.setScheme(QLatin1String("baloosearch"));
0043     searchUrl.setQuery(urlQuery);
0044 
0045     return searchUrl;
0046 }
0047 
0048 void DolphinQueryTest::initTestCase()
0049 {
0050     QStandardPaths::setTestModeEnabled(true);
0051 }
0052 
0053 /**
0054  * Defines the parameters for the test cases in testBalooSearchParsing()
0055  */
0056 void DolphinQueryTest::testBalooSearchParsing_data()
0057 {
0058     QTest::addColumn<QUrl>("searchUrl");
0059     QTest::addColumn<QString>("expectedText");
0060     QTest::addColumn<QStringList>("expectedTerms");
0061     QTest::addColumn<bool>("hasContent");
0062     QTest::addColumn<bool>("hasFileName");
0063 
0064     const QString text = QStringLiteral("abc");
0065     const QString textS = QStringLiteral("abc xyz");
0066     const QString textQ = QStringLiteral("\"abc xyz\"");
0067     const QString textM = QStringLiteral("\"abc xyz\" tuv");
0068 
0069     const QString filename = QStringLiteral("filename:\"%1\"").arg(text);
0070     const QString filenameS = QStringLiteral("filename:\"%1\"").arg(textS);
0071     const QString filenameQ = QStringLiteral("filename:\"%1\"").arg(textQ);
0072     const QString filenameM = QStringLiteral("filename:\"%1\"").arg(textM);
0073 
0074     const QString rating = QStringLiteral("rating>=2");
0075     const QString modified = QStringLiteral("modified>=2019-08-07");
0076 
0077     const QString tag = QStringLiteral("tag:tagA");
0078     const QString tagS = QStringLiteral("tag:\"tagB with spaces\""); // in search url
0079     const QString tagR = QStringLiteral("tag:tagB with spaces"); // in result term
0080 
0081     // Test for "Content"
0082     QTest::newRow("content") << balooQueryUrl(text) << text << QStringList() << true << false;
0083     QTest::newRow("content/space") << balooQueryUrl(textS) << textS << QStringList() << true << false;
0084     QTest::newRow("content/quoted") << balooQueryUrl(textQ) << textS << QStringList() << true << false;
0085     QTest::newRow("content/empty") << balooQueryUrl("") << "" << QStringList() << false << false;
0086     QTest::newRow("content/single_quote") << balooQueryUrl("\"") << "\"" << QStringList() << true << false;
0087     QTest::newRow("content/double_quote") << balooQueryUrl("\"\"") << "" << QStringList() << false << false;
0088 
0089     // Test for "FileName"
0090     QTest::newRow("filename") << balooQueryUrl(filename) << text << QStringList() << false << true;
0091     QTest::newRow("filename/space") << balooQueryUrl(filenameS) << textS << QStringList() << false << true;
0092     QTest::newRow("filename/quoted") << balooQueryUrl(filenameQ) << textQ << QStringList() << false << true;
0093     QTest::newRow("filename/mixed") << balooQueryUrl(filenameM) << textM << QStringList() << false << true;
0094     QTest::newRow("filename/empty") << balooQueryUrl("filename:") << "" << QStringList() << false << false;
0095     QTest::newRow("filename/single_quote") << balooQueryUrl("filename:\"") << "\"" << QStringList() << false << true;
0096     QTest::newRow("filename/double_quote") << balooQueryUrl("filename:\"\"") << "" << QStringList() << false << false;
0097 
0098     // Combined content and filename search
0099     QTest::newRow("content+filename") << balooQueryUrl(text + " " + filename) << text + " " + filename << QStringList() << true << true;
0100 
0101     QTest::newRow("content+filename/quoted") << balooQueryUrl(textQ + " " + filenameQ) << textS + " " + filenameQ << QStringList() << true << true;
0102 
0103     // Test for rating
0104     QTest::newRow("rating") << balooQueryUrl(rating) << "" << QStringList({rating}) << false << false;
0105     QTest::newRow("rating+content") << balooQueryUrl(rating + " " + text) << text << QStringList({rating}) << true << false;
0106     QTest::newRow("rating+filename") << balooQueryUrl(rating + " " + filename) << text << QStringList({rating}) << false << true;
0107 
0108     // Test for modified date
0109     QTest::newRow("modified") << balooQueryUrl(modified) << "" << QStringList({modified}) << false << false;
0110     QTest::newRow("modified+content") << balooQueryUrl(modified + " " + text) << text << QStringList({modified}) << true << false;
0111     QTest::newRow("modified+filename") << balooQueryUrl(modified + " " + filename) << text << QStringList({modified}) << false << true;
0112 
0113     // Test for tags
0114     QTest::newRow("tag") << balooQueryUrl(tag) << "" << QStringList({tag}) << false << false;
0115     QTest::newRow("tag/space") << balooQueryUrl(tagS) << "" << QStringList({tagR}) << false << false;
0116     QTest::newRow("tag/double") << balooQueryUrl(tag + " " + tagS) << "" << QStringList({tag, tagR}) << false << false;
0117     QTest::newRow("tag+content") << balooQueryUrl(tag + " " + text) << text << QStringList({tag}) << true << false;
0118     QTest::newRow("tag+filename") << balooQueryUrl(tag + " " + filename) << text << QStringList({tag}) << false << true;
0119 
0120     // Combined search terms
0121     QTest::newRow("searchTerms") << balooQueryUrl(rating + " AND " + modified + " AND " + tag + " AND " + tagS) << ""
0122                                  << QStringList({modified, rating, tag, tagR}) << false << false;
0123 
0124     QTest::newRow("searchTerms+content") << balooQueryUrl(rating + " AND " + modified + " " + text + " " + tag + " AND " + tagS) << text
0125                                          << QStringList({modified, rating, tag, tagR}) << true << false;
0126 
0127     QTest::newRow("searchTerms+filename") << balooQueryUrl(rating + " AND " + modified + " " + filename + " " + tag + " AND " + tagS) << text
0128                                           << QStringList({modified, rating, tag, tagR}) << false << true;
0129 
0130     QTest::newRow("allTerms") << balooQueryUrl(text + " " + filename + " " + rating + " AND " + modified + " AND " + tag) << text + " " + filename
0131                               << QStringList({modified, rating, tag}) << true << true;
0132 
0133     QTest::newRow("allTerms/space") << balooQueryUrl(textS + " " + filenameS + " " + rating + " AND " + modified + " AND " + tagS) << textS + " " + filenameS
0134                                     << QStringList({modified, rating, tagR}) << true << true;
0135 
0136     // Test tags:/ URL scheme
0137     const auto tagUrl = [](const QString &tag) {
0138         return QUrl(QStringLiteral("tags:/%1/").arg(tag));
0139     };
0140     const auto tagTerms = [](const QString &tag) {
0141         return QStringList{QStringLiteral("tag:%1").arg(tag)};
0142     };
0143 
0144     QTest::newRow("tagsUrl") << tagUrl("tagA") << "" << tagTerms("tagA") << false << false;
0145     QTest::newRow("tagsUrl/space") << tagUrl("tagB with spaces") << "" << tagTerms("tagB with spaces") << false << false;
0146     QTest::newRow("tagsUrl/hash") << tagUrl("tagC#hash") << "" << tagTerms("tagC#hash") << false << false;
0147     QTest::newRow("tagsUrl/slash") << tagUrl("tagD/with/slash") << "" << tagTerms("tagD/with/slash") << false << false;
0148 }
0149 
0150 /**
0151  * The test verifies whether the different terms search URL (e.g. "baloosearch:/") are
0152  * properly handled by the searchbox, and only "user" or filename terms are added to the
0153  * text bar of the searchbox.
0154  */
0155 void DolphinQueryTest::testBalooSearchParsing()
0156 {
0157     QFETCH(QUrl, searchUrl);
0158     QFETCH(QString, expectedText);
0159     QFETCH(QStringList, expectedTerms);
0160     QFETCH(bool, hasContent);
0161     QFETCH(bool, hasFileName);
0162 
0163     const DolphinQuery query = DolphinQuery::fromSearchUrl(searchUrl);
0164 
0165     // Checkt that the URL is supported
0166     QVERIFY(DolphinQuery::supportsScheme(searchUrl.scheme()));
0167 
0168     // Check for parsed text (would be displayed on the input search bar)
0169     QCOMPARE(query.text(), expectedText);
0170 
0171     // Check for parsed search terms (would be displayed by the facetsWidget)
0172     QStringList searchTerms = query.searchTerms();
0173     searchTerms.sort();
0174 
0175     QCOMPARE(searchTerms.count(), expectedTerms.count());
0176     for (int i = 0; i < expectedTerms.count(); i++) {
0177         QCOMPARE(searchTerms.at(i), expectedTerms.at(i));
0178     }
0179 
0180     // Check for filename and content detection
0181     QCOMPARE(query.hasContentSearch(), hasContent);
0182     QCOMPARE(query.hasFileName(), hasFileName);
0183 }
0184 
0185 QTEST_MAIN(DolphinQueryTest)
0186 
0187 #include "dolphinquerytest.moc"