File indexing completed on 2024-12-22 04:52:57

0001 /*
0002  * This file is part of the KDE Akonadi Search Project
0003  * SPDX-FileCopyrightText: 2014 Christian Mollekopf <mollekopf@kolabsys.com>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006  *
0007  */
0008 
0009 #include <Akonadi/Collection>
0010 #include <QDir>
0011 #include <QTest>
0012 
0013 #include "../search/calendar/calendarsearchstore.h"
0014 #include "../search/contact/contactsearchstore.h"
0015 #include "../search/email/emailsearchstore.h"
0016 #include "calendarindexer.h"
0017 #include "contactindexer.h"
0018 #include "emailindexer.h"
0019 #include "query.h"
0020 
0021 Q_DECLARE_METATYPE(QSet<qint64>)
0022 Q_DECLARE_METATYPE(QList<qint64>)
0023 
0024 KMime::Message::Ptr readMailFromFile(const QString &mailFile)
0025 {
0026     QFile file(QLatin1StringView(MAIL_DATA_DIR) + QLatin1Char('/') + mailFile);
0027     file.open(QIODevice::ReadOnly);
0028     Q_ASSERT(file.isOpen());
0029     auto mailData = KMime::CRLFtoLF(file.readAll());
0030     KMime::Message::Ptr message(new KMime::Message);
0031     message->setContent(mailData);
0032     message->parse();
0033     return message;
0034 }
0035 
0036 class IndexerTest : public QObject
0037 {
0038     Q_OBJECT
0039 private:
0040     QString emailDir;
0041     QString emailContactsDir;
0042     QString contactsDir;
0043     QString calendarsDir;
0044     QString notesDir;
0045 
0046     bool removeDir(const QString &dirName)
0047     {
0048         bool result = true;
0049         QDir dir(dirName);
0050 
0051         if (dir.exists(dirName)) {
0052             const QFileInfoList infoDirs = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst);
0053             for (const QFileInfo &info : infoDirs) {
0054                 if (info.isDir()) {
0055                     result = removeDir(info.absoluteFilePath());
0056                 } else {
0057                     result = QFile::remove(info.absoluteFilePath());
0058                 }
0059 
0060                 if (!result) {
0061                     return result;
0062                 }
0063             }
0064             result = dir.rmdir(dirName);
0065         }
0066         return result;
0067     }
0068 
0069 private Q_SLOTS:
0070     void init()
0071     {
0072         emailDir = QDir::tempPath() + QLatin1StringView("/searchplugintest/email/");
0073         emailContactsDir = QDir::tempPath() + QLatin1StringView("/searchplugintest/emailcontacts/");
0074         contactsDir = QDir::tempPath() + QLatin1StringView("/searchplugintest/contacts/");
0075         notesDir = QDir::tempPath() + QStringLiteral("/searchplugintest/notes/");
0076         calendarsDir = QDir::tempPath() + QStringLiteral("/searchplugintest/calendars/");
0077 
0078         QDir dir;
0079         removeDir(emailDir);
0080         QVERIFY(dir.mkpath(emailDir));
0081         removeDir(emailContactsDir);
0082         QVERIFY(dir.mkpath(emailContactsDir));
0083         removeDir(contactsDir);
0084         QVERIFY(dir.mkpath(contactsDir));
0085         removeDir(notesDir);
0086         QVERIFY(dir.mkpath(notesDir));
0087         removeDir(calendarsDir);
0088         QVERIFY(dir.mkpath(calendarsDir));
0089 
0090         qDebug() << "indexing sample data";
0091         qDebug() << emailDir;
0092         qDebug() << emailContactsDir;
0093         qDebug() << notesDir;
0094         qDebug() << calendarsDir;
0095 
0096         //         EmailIndexer emailIndexer(emailDir, emailContactsDir);
0097         //         ContactIndexer contactIndexer(contactsDir);
0098 
0099         //         Akonadi::Search::EmailSearchStore *emailSearchStore = new Akonadi::Search::EmailSearchStore(this);
0100         //         emailSearchStore->setDbPath(emailDir);
0101         //         Akonadi::Search::ContactSearchStore *contactSearchStore = new Akonadi::Search::ContactSearchStore(this);
0102         //         contactSearchStore->setDbPath(contactsDir);
0103         //         Akonadi::Search::SearchStore::overrideSearchStores(QList<Akonadi::Search::SearchStore*>() << emailSearchStore << contactSearchStore);
0104     }
0105 
0106     QSet<qint64> getAllEmailItems()
0107     {
0108         QSet<qint64> resultSet;
0109 
0110         Akonadi::Search::Term term(Akonadi::Search::Term::Or);
0111         term.addSubTerm(Akonadi::Search::Term(QStringLiteral("collection"), QStringLiteral("1"), Akonadi::Search::Term::Equal));
0112         term.addSubTerm(Akonadi::Search::Term(QStringLiteral("collection"), QStringLiteral("2"), Akonadi::Search::Term::Equal));
0113         Akonadi::Search::Query query(term);
0114         query.setType(QStringLiteral("Email"));
0115 
0116         auto emailSearchStore = new Akonadi::Search::EmailSearchStore(this);
0117         emailSearchStore->setDbPath(emailDir);
0118         int res = emailSearchStore->exec(query);
0119         qDebug() << res;
0120         while (emailSearchStore->next(res)) {
0121             const int fid = Akonadi::Search::deserialize("akonadi", emailSearchStore->id(res));
0122             resultSet << fid;
0123         }
0124         qDebug() << resultSet;
0125         return resultSet;
0126     }
0127 
0128     QSet<qint64> getAllCalendarItems()
0129     {
0130         QSet<qint64> resultSet;
0131 
0132         Akonadi::Search::Term term(Akonadi::Search::Term::Or);
0133         term.addSubTerm(Akonadi::Search::Term(QStringLiteral("collection"), QStringLiteral("1"), Akonadi::Search::Term::Equal));
0134         term.addSubTerm(Akonadi::Search::Term(QStringLiteral("collection"), QStringLiteral("2"), Akonadi::Search::Term::Equal));
0135         Akonadi::Search::Query query(term);
0136         query.setType(QStringLiteral("Calendar"));
0137 
0138         auto calendarSearchStore = new Akonadi::Search::CalendarSearchStore(this);
0139         calendarSearchStore->setDbPath(calendarsDir);
0140         int res = calendarSearchStore->exec(query);
0141         qDebug() << res;
0142         while (calendarSearchStore->next(res)) {
0143             const int fid = Akonadi::Search::deserialize("akonadi", calendarSearchStore->id(res));
0144             resultSet << fid;
0145         }
0146         qDebug() << resultSet;
0147         return resultSet;
0148     }
0149 
0150     void testEmailRemoveByCollection()
0151     {
0152         EmailIndexer emailIndexer(emailDir, emailContactsDir);
0153         {
0154             KMime::Message::Ptr msg(new KMime::Message);
0155             msg->subject()->from7BitString("subject1");
0156             msg->assemble();
0157 
0158             Akonadi::Item item(KMime::Message::mimeType());
0159             item.setId(1);
0160             item.setPayload(msg);
0161             item.setParentCollection(Akonadi::Collection(1));
0162             emailIndexer.index(item);
0163         }
0164         {
0165             KMime::Message::Ptr msg(new KMime::Message);
0166             msg->subject()->from7BitString("subject2");
0167             msg->assemble();
0168 
0169             Akonadi::Item item(KMime::Message::mimeType());
0170             item.setId(2);
0171             item.setPayload(msg);
0172             item.setParentCollection(Akonadi::Collection(2));
0173             emailIndexer.index(item);
0174         }
0175         emailIndexer.commit();
0176         QCOMPARE(getAllEmailItems(), QSet<qint64>() << 1 << 2);
0177         emailIndexer.remove(Akonadi::Collection(2));
0178         emailIndexer.commit();
0179         QCOMPARE(getAllEmailItems(), QSet<qint64>() << 1);
0180     }
0181 
0182     void testHtmlOnly()
0183     {
0184         auto msg = readMailFromFile(QStringLiteral("htmlonly.mbox"));
0185 
0186         Akonadi::Item item(KMime::Message::mimeType());
0187         item.setId(1);
0188         item.setPayload(msg);
0189         item.setParentCollection(Akonadi::Collection(1));
0190 
0191         EmailIndexer emailIndexer(emailDir, emailContactsDir);
0192         emailIndexer.index(item);
0193         emailIndexer.commit();
0194         QCOMPARE(getAllEmailItems(), QSet<qint64>() << 1);
0195     }
0196 
0197     void testCalendarRemoveByCollection()
0198     {
0199         CalendarIndexer calendarIndexer(calendarsDir);
0200         {
0201             KCalendarCore::Event::Ptr event(new KCalendarCore::Event);
0202             event->setSummary(QStringLiteral("My Event 1"));
0203 
0204             Akonadi::Item item(KCalendarCore::Event::eventMimeType());
0205             item.setId(3);
0206             item.setPayload(event);
0207             item.setParentCollection(Akonadi::Collection(1));
0208             calendarIndexer.index(item);
0209         }
0210 
0211         {
0212             KCalendarCore::Event::Ptr event(new KCalendarCore::Event);
0213             event->setSummary(QStringLiteral("My Event 2"));
0214 
0215             Akonadi::Item item(KCalendarCore::Event::eventMimeType());
0216             item.setId(4);
0217             item.setPayload(event);
0218             item.setParentCollection(Akonadi::Collection(2));
0219             calendarIndexer.index(item);
0220         }
0221 
0222         calendarIndexer.commit();
0223         QCOMPARE(getAllCalendarItems(), QSet<qint64>() << 3 << 4);
0224 
0225         calendarIndexer.remove(Akonadi::Collection(2));
0226         calendarIndexer.commit();
0227         QCOMPARE(getAllCalendarItems(), QSet<qint64>() << 3);
0228     }
0229 
0230     void testAddCalendarWithAttendee()
0231     {
0232         CalendarIndexer calendarIndexer(calendarsDir);
0233         {
0234             KCalendarCore::Event::Ptr event(new KCalendarCore::Event);
0235             event->setSummary(QStringLiteral("My Event 1"));
0236             event->addAttendee(KCalendarCore::Attendee(QStringLiteral("John Doe"), QStringLiteral("john.doe@kmail.com")));
0237 
0238             Akonadi::Item item(KCalendarCore::Event::eventMimeType());
0239             item.setId(5);
0240             item.setPayload(event);
0241             item.setParentCollection(Akonadi::Collection(1));
0242             calendarIndexer.index(item);
0243         }
0244         calendarIndexer.commit();
0245 
0246         QSet<qint64> resultSet;
0247 
0248         const auto status = KCalendarCore::Attendee::PartStat::NeedsAction;
0249         Akonadi::Search::Term term(Akonadi::Search::Term::Or);
0250 
0251         Akonadi::Search::Term partStatusTerm(QStringLiteral("partstatus"),
0252                                              QString(QStringLiteral("john.doe@kmail.com") + QString::number(status)),
0253                                              Akonadi::Search::Term::Equal);
0254 
0255         term.addSubTerm(partStatusTerm);
0256 
0257         Akonadi::Search::Query query(term);
0258         query.setType(QStringLiteral("Calendar"));
0259 
0260         auto calendarSearchStore = new Akonadi::Search::CalendarSearchStore(this);
0261         calendarSearchStore->setDbPath(calendarsDir);
0262         int res = calendarSearchStore->exec(query);
0263         qDebug() << res;
0264         while (calendarSearchStore->next(res)) {
0265             const int fid = Akonadi::Search::deserialize("akonadi", calendarSearchStore->id(res));
0266             QCOMPARE(fid, 5);
0267         }
0268     }
0269 };
0270 
0271 QTEST_GUILESS_MAIN(IndexerTest)
0272 
0273 #include "indexertest.moc"