File indexing completed on 2025-01-05 04:55:02

0001 
0002 #include <QTest>
0003 #include <QDebug>
0004 #include <QSignalSpy>
0005 #include <sink/test.h>
0006 #include <sink/store.h>
0007 #include <sink/resourcecontrol.h>
0008 #include <KCalendarCore/Event>
0009 #include <KCalendarCore/ICalFormat>
0010 #include "mailtemplates.h"
0011 
0012 #include "inboundmodel.h"
0013 
0014 class InboundModelTest : public QObject
0015 {
0016     Q_OBJECT
0017 private slots:
0018 
0019     void initTestCase()
0020     {
0021         Sink::Test::initTest();
0022     }
0023 
0024     void testInboundModel()
0025     {
0026         Sink::ApplicationDomain::DummyResource::create("account1");
0027 
0028         using namespace Sink::ApplicationDomain;
0029         auto account = ApplicationDomainType::createEntity<SinkAccount>();
0030         VERIFYEXEC(Sink::Store::create(account));
0031 
0032         auto resource = Sink::ApplicationDomain::DummyResource::create(account.identifier());
0033         VERIFYEXEC(Sink::Store::create(resource));
0034 
0035         auto calendar1 = ApplicationDomainType::createEntity<Calendar>(resource.identifier());
0036         calendar1.setEnabled(true);
0037         VERIFYEXEC(Sink::Store::create(calendar1));
0038 
0039         const QDateTime start{{2018, 04, 17}, {6, 0, 0}};
0040         {
0041             auto event1 = ApplicationDomainType::createEntity<Event>(resource.identifier());
0042             auto calcoreEvent = QSharedPointer<KCalendarCore::Event>::create();
0043             calcoreEvent->setUid("event1");
0044             calcoreEvent->setSummary("summary1");
0045             calcoreEvent->setDescription("description");
0046             calcoreEvent->setDtStart(start);
0047             calcoreEvent->setDuration(3600);
0048             calcoreEvent->setAllDay(false);
0049             event1.setIcal(KCalendarCore::ICalFormat().toICalString(calcoreEvent).toUtf8());
0050             event1.setCalendar(calendar1);
0051             VERIFYEXEC(Sink::Store::create(event1));
0052         }
0053         {
0054             auto event2 = ApplicationDomainType::createEntity<Event>(resource.identifier());
0055             auto calcoreEvent = QSharedPointer<KCalendarCore::Event>::create();
0056             calcoreEvent->setUid("event2");
0057             calcoreEvent->setSummary("summary2");
0058             calcoreEvent->setDescription("description");
0059             calcoreEvent->setDtStart(start.addDays(1));
0060             calcoreEvent->setDuration(3600);
0061             calcoreEvent->setAllDay(false);
0062             calcoreEvent->recurrence()->setDaily(2);
0063             event2.setIcal(KCalendarCore::ICalFormat().toICalString(calcoreEvent).toUtf8());
0064             event2.setCalendar(calendar1);
0065             VERIFYEXEC(Sink::Store::create(event2));
0066         }
0067 
0068         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0069 
0070         InboundModel model;
0071 
0072         {
0073             QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0074             model.setCurrentDate(start);
0075             model.configure(
0076                 {}, // QSet<QString> &_senderBlacklist,
0077                 {}, // QSet<QString> &_toBlacklist,
0078                 {}, // QString &_senderNameContainsFilter,
0079                 {}, // QMap<QString, QString> &_perFolderMimeMessageWhitelistFilter,
0080                 {}, // QList<QRegularExpression> &_messageFilter,
0081                 {}, // QList<QString> &_folderSpecialPurposeBlacklist,
0082                 {}  // QList<QString> &_folderNameBlacklist,
0083             );
0084 
0085             QTest::qWait(200);
0086             QTRY_COMPARE(model.rowCount({}), 4);
0087             QCOMPARE(initialItemsLoadedSpy.count(), 1);
0088         }
0089 
0090         {
0091 
0092             auto calcoreEvent = QSharedPointer<KCalendarCore::Event>::create();
0093             calcoreEvent->setUid("event1");
0094             calcoreEvent->setSummary("summary1");
0095             calcoreEvent->setDescription("description");
0096             calcoreEvent->setDtStart(start);
0097             calcoreEvent->setDuration(7200);
0098             calcoreEvent->setAllDay(false);
0099 
0100             const auto event = model.index(3, 0, {}).data(model.roleNames().key("data")).toMap()["domainObject"].value<Sink::ApplicationDomain::Event::Ptr>();
0101             event->setIcal(KCalendarCore::ICalFormat().toICalString(calcoreEvent).toUtf8());
0102 
0103             QSignalSpy resetSpy(&model, &QAbstractItemModel::modelReset);
0104             QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
0105             QSignalSpy rowsRemovedSpy(&model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
0106             QSignalSpy dataChangedSpy(&model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector<int> &)));
0107             QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0108 
0109             VERIFYEXEC(Sink::Store::modify(*event));
0110             VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0111 
0112             QTest::qWait(200);
0113             QCOMPARE(resetSpy.count(), 0);
0114             QCOMPARE(rowsRemovedSpy.count(), 0);
0115             QCOMPARE(rowsInsertedSpy.count(), 0);
0116             QCOMPARE(dataChangedSpy.count(), 2);
0117             QCOMPARE(initialItemsLoadedSpy.count(), 0);
0118         }
0119 
0120 
0121         //Filter by date
0122         {
0123             QSignalSpy resetSpy(&model, &QAbstractItemModel::modelReset);
0124             QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
0125             QSignalSpy rowsRemovedSpy(&model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
0126             model.setCurrentDate(start.addSecs(3600));
0127 
0128             QTest::qWait(200);
0129             QCOMPARE(resetSpy.count(), 0);
0130             QCOMPARE(rowsRemovedSpy.count(), 1);
0131             QCOMPARE(rowsInsertedSpy.count(), 0);
0132         }
0133         {
0134             QSignalSpy resetSpy(&model, &QAbstractItemModel::modelReset);
0135             QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
0136             QSignalSpy rowsRemovedSpy(&model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
0137             model.setCurrentDate(start.addSecs(3600));
0138 
0139             QTest::qWait(200);
0140             QCOMPARE(resetSpy.count(), 0);
0141             QCOMPARE(rowsRemovedSpy.count(), 0);
0142             QCOMPARE(rowsInsertedSpy.count(), 0);
0143         }
0144 
0145         //Cleanup
0146         VERIFYEXEC(Sink::Store::remove(resource));
0147     }
0148 
0149     void testMailInbound()
0150     {
0151         using namespace Sink::ApplicationDomain;
0152         auto account = ApplicationDomainType::createEntity<SinkAccount>();
0153         VERIFYEXEC(Sink::Store::create(account));
0154 
0155         auto resource = Sink::ApplicationDomain::DummyResource::create(account.identifier());
0156         VERIFYEXEC(Sink::Store::create(resource));
0157 
0158         auto folder1 = ApplicationDomainType::createEntity<Folder>(resource.identifier());
0159         VERIFYEXEC(Sink::Store::create(folder1));
0160 
0161         auto folder2 = ApplicationDomainType::createEntity<Folder>(resource.identifier());
0162         VERIFYEXEC(Sink::Store::create(folder2));
0163 
0164 
0165         auto mail1 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0166         mail1.setFolder(folder1);
0167         KMime::Types::Mailbox from;
0168         from.fromUnicodeString("from@example.org");
0169         auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "Subject", "Body", false, {}, {}, {});
0170         mail1.setMimeMessage(message->encodedContent(true));
0171         VERIFYEXEC(Sink::Store::create(mail1));
0172 
0173         auto mail2 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0174         mail2.setFolder(folder2);
0175         VERIFYEXEC(Sink::Store::create(mail2));
0176 
0177         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0178 
0179 
0180         InboundModel model;
0181         QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0182         model.setCurrentDate({{2018, 04, 17}, {6, 0, 0}});
0183         model.configure(
0184             {}, // QSet<QString> &_senderBlacklist,
0185             {}, // QSet<QString> &_toBlacklist,
0186             {}, // QString &_senderNameContainsFilter,
0187             {}, // QMap<QString, QString> &_perFolderMimeMessageWhitelistFilter,
0188             {}, // QList<QRegularExpression> &_messageFilter,
0189             {}, // QList<QString> &_folderSpecialPurposeBlacklist,
0190             {}  // QList<QString> &_folderNameBlacklist,
0191         );
0192         model.setFilter({{"inbound", QVariant::fromValue(true)}});
0193 
0194         QTRY_COMPARE(initialItemsLoadedSpy.count(), 1);
0195         QCOMPARE(model.rowCount({}), 2);
0196 
0197         //Test move to trash
0198         {
0199             QSignalSpy resetSpy(&model, &QAbstractItemModel::modelReset);
0200             QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
0201             QSignalSpy rowsRemovedSpy(&model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
0202             QSignalSpy dataChangedSpy(&model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector<int> &)));
0203             QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0204 
0205             auto idx = model.index(0, 0, {});
0206             auto mail = idx.data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>();
0207             mail->setTrash(true);
0208 
0209             VERIFYEXEC(Sink::Store::modify(*mail));
0210             VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0211 
0212             QTRY_COMPARE(rowsRemovedSpy.count(), 1);
0213             QCOMPARE(resetSpy.count(), 0);
0214             QCOMPARE(rowsInsertedSpy.count(), 0);
0215             QCOMPARE(dataChangedSpy.count(), 0);
0216 
0217             QTRY_COMPARE(model.rowCount({}), 1);
0218         }
0219     }
0220 
0221     void testMailFolder()
0222     {
0223         using namespace Sink::ApplicationDomain;
0224         auto account = ApplicationDomainType::createEntity<SinkAccount>();
0225         VERIFYEXEC(Sink::Store::create(account));
0226 
0227         auto resource = Sink::ApplicationDomain::DummyResource::create(account.identifier());
0228         VERIFYEXEC(Sink::Store::create(resource));
0229 
0230         auto folder1 = ApplicationDomainType::createEntity<Folder>(resource.identifier());
0231         VERIFYEXEC(Sink::Store::create(folder1));
0232 
0233         auto folder2 = ApplicationDomainType::createEntity<Folder>(resource.identifier());
0234         VERIFYEXEC(Sink::Store::create(folder2));
0235 
0236         auto mail1 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0237         mail1.setFolder(folder1);
0238         KMime::Types::Mailbox from;
0239         from.fromUnicodeString("from@example.org");
0240         auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "Subject", "Body", false, {}, {}, {});
0241         mail1.setMimeMessage(message->encodedContent(true));
0242         VERIFYEXEC(Sink::Store::create(mail1));
0243 
0244         auto mail2 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0245         mail2.setFolder(folder2);
0246         VERIFYEXEC(Sink::Store::create(mail2));
0247 
0248         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0249 
0250 
0251         InboundModel model;
0252         QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0253         model.setFilter({{"folder", QVariant::fromValue(ApplicationDomainType::Ptr::create(folder1))}});
0254 
0255         QTRY_COMPARE(initialItemsLoadedSpy.count(), 1);
0256         QCOMPARE(model.rowCount({}), 1);
0257         {
0258             auto idx = model.index(0, 0, {});
0259             auto mail = idx.data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>();
0260             QVERIFY(mail);
0261             QVERIFY(!mail->getSubject().isEmpty());
0262         }
0263 
0264         //Test move to trash
0265         {
0266             QSignalSpy resetSpy(&model, &QAbstractItemModel::modelReset);
0267             QSignalSpy rowsInsertedSpy(&model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
0268             QSignalSpy rowsRemovedSpy(&model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
0269             QSignalSpy dataChangedSpy(&model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector<int> &)));
0270             QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0271 
0272             auto idx = model.index(0, 0, {});
0273             auto mail = idx.data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>();
0274             mail->setTrash(true);
0275 
0276             VERIFYEXEC(Sink::Store::modify(*mail));
0277             VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0278 
0279             QTRY_COMPARE(rowsRemovedSpy.count(), 1);
0280             QCOMPARE(resetSpy.count(), 0);
0281             QCOMPARE(rowsInsertedSpy.count(), 0);
0282             QCOMPARE(dataChangedSpy.count(), 0);
0283 
0284             QTRY_COMPARE(model.rowCount({}), 0);
0285         }
0286     }
0287 
0288     void testInboundSorting()
0289     {
0290         using namespace Sink::ApplicationDomain;
0291         auto account = ApplicationDomainType::createEntity<SinkAccount>();
0292         VERIFYEXEC(Sink::Store::create(account));
0293 
0294         auto resource = Sink::ApplicationDomain::DummyResource::create(account.identifier());
0295         VERIFYEXEC(Sink::Store::create(resource));
0296 
0297         auto folder1 = ApplicationDomainType::createEntity<Folder>(resource.identifier());
0298         VERIFYEXEC(Sink::Store::create(folder1));
0299 
0300         {
0301             auto mail1 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0302             mail1.setFolder(folder1);
0303             KMime::Types::Mailbox from;
0304             from.fromUnicodeString("from@example.org");
0305             auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "mail1", "testInboundSorting", false, {}, {}, {});
0306             message->date()->setDateTime(QDateTime::currentDateTime().addDays(-1));
0307             message->assemble();
0308             mail1.setMimeMessage(message->encodedContent(true));
0309             VERIFYEXEC(Sink::Store::create(mail1));
0310         }
0311 
0312         {
0313             auto mail2 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0314             mail2.setFolder(folder1);
0315             KMime::Types::Mailbox from;
0316             from.fromUnicodeString("from@example.org");
0317             auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "mail2", "testInboundSorting", false, {}, {}, {});
0318             message->date()->setDateTime(QDateTime::currentDateTime());
0319             message->assemble();
0320             qWarning() << message->encodedContent(true);
0321             mail2.setMimeMessage(message->encodedContent(true));
0322             VERIFYEXEC(Sink::Store::create(mail2));
0323         }
0324 
0325         {
0326             auto mail3 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0327             mail3.setFolder(folder1);
0328             KMime::Types::Mailbox from;
0329             from.fromUnicodeString("from@example.org");
0330             auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "mail3", "testInboundSorting", false, {}, {}, {});
0331             message->date()->setDateTime(QDateTime::currentDateTime().addDays(-2));
0332             message->assemble();
0333             qWarning() << message->encodedContent(true);
0334             mail3.setMimeMessage(message->encodedContent(true));
0335             VERIFYEXEC(Sink::Store::create(mail3));
0336         }
0337 
0338         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0339 
0340 
0341         InboundModel model;
0342         QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0343         model.setCurrentDate({{2018, 04, 17}, {6, 0, 0}});
0344         model.configure(
0345             {}, // QSet<QString> &_senderBlacklist,
0346             {}, // QSet<QString> &_toBlacklist,
0347             {}, // QString &_senderNameContainsFilter,
0348             {}, // QMap<QString, QString> &_perFolderMimeMessageWhitelistFilter,
0349             {}, // QList<QRegularExpression> &_messageFilter,
0350             {}, // QList<QString> &_folderSpecialPurposeBlacklist,
0351             {}  // QList<QString> &_folderNameBlacklist,
0352         );
0353         model.setFilter({
0354             {"inbound", true},
0355             {"string", "testInboundSorting"}
0356         });
0357 
0358         QTRY_COMPARE(initialItemsLoadedSpy.count(), 1);
0359         QCOMPARE(model.rowCount({}), 3);
0360         {
0361             //Sorted by date, not creation
0362             QCOMPARE(model.index(0, 0, {}).data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>()->getSubject(), QString{"mail2"});
0363             QCOMPARE(model.index(1, 0, {}).data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>()->getSubject(), QString{"mail1"});
0364             QCOMPARE(model.index(2, 0, {}).data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>()->getSubject(), QString{"mail3"});
0365         }
0366     }
0367 
0368     void testMailFolderSorting()
0369     {
0370         using namespace Sink::ApplicationDomain;
0371         auto account = ApplicationDomainType::createEntity<SinkAccount>();
0372         VERIFYEXEC(Sink::Store::create(account));
0373 
0374         auto resource = Sink::ApplicationDomain::DummyResource::create(account.identifier());
0375         VERIFYEXEC(Sink::Store::create(resource));
0376 
0377         auto folder1 = ApplicationDomainType::createEntity<Folder>(resource.identifier());
0378         VERIFYEXEC(Sink::Store::create(folder1));
0379 
0380         {
0381             auto mail1 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0382             mail1.setFolder(folder1);
0383             KMime::Types::Mailbox from;
0384             from.fromUnicodeString("from@example.org");
0385             auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "mail1", "Body", false, {}, {}, {});
0386             message->date()->setDateTime(QDateTime::currentDateTime().addDays(-1));
0387             message->assemble();
0388             mail1.setMimeMessage(message->encodedContent(true));
0389             VERIFYEXEC(Sink::Store::create(mail1));
0390         }
0391 
0392         {
0393             auto mail2 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0394             mail2.setFolder(folder1);
0395             KMime::Types::Mailbox from;
0396             from.fromUnicodeString("from@example.org");
0397             auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "mail2", "Body", false, {}, {}, {});
0398             message->date()->setDateTime(QDateTime::currentDateTime());
0399             message->assemble();
0400             qWarning() << message->encodedContent(true);
0401             mail2.setMimeMessage(message->encodedContent(true));
0402             VERIFYEXEC(Sink::Store::create(mail2));
0403         }
0404 
0405         {
0406             auto mail3 = ApplicationDomainType::createEntity<Mail>(resource.identifier());
0407             mail3.setFolder(folder1);
0408             KMime::Types::Mailbox from;
0409             from.fromUnicodeString("from@example.org");
0410             auto message = MailTemplates::createMessage({}, {"foo@test.com"}, {}, {}, from, "mail3", "Body", false, {}, {}, {});
0411             message->date()->setDateTime(QDateTime::currentDateTime().addDays(-2));
0412             message->assemble();
0413             qWarning() << message->encodedContent(true);
0414             mail3.setMimeMessage(message->encodedContent(true));
0415             VERIFYEXEC(Sink::Store::create(mail3));
0416         }
0417 
0418         VERIFYEXEC(Sink::ResourceControl::flushMessageQueue(resource.identifier()));
0419 
0420         InboundModel model;
0421         QSignalSpy initialItemsLoadedSpy(&model, &InboundModel::initialItemsLoaded);
0422         model.setFilter({{"folder", QVariant::fromValue(ApplicationDomainType::Ptr::create(folder1))}});
0423 
0424         QTRY_COMPARE(initialItemsLoadedSpy.count(), 1);
0425         QCOMPARE(model.rowCount({}), 3);
0426         {
0427             //Sorted by date, not creation
0428             QCOMPARE(model.index(0, 0, {}).data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>()->getSubject(), QString{"mail2"});
0429             QCOMPARE(model.index(1, 0, {}).data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>()->getSubject(), QString{"mail1"});
0430             QCOMPARE(model.index(2, 0, {}).data(model.roleNames().key("data")).toMap().value("mail").value<Mail::Ptr>()->getSubject(), QString{"mail3"});
0431         }
0432     }
0433 
0434 };
0435 
0436 QTEST_MAIN(InboundModelTest)
0437 #include "inboundmodeltest.moc"