File indexing completed on 2025-01-05 04:58:37

0001 #include <QTest>
0002 
0003 #include <QString>
0004 #include <KMime/Message>
0005 #include <QTcpSocket>
0006 
0007 #include "../imapserverproxy.h"
0008 
0009 #include "log.h"
0010 #include "test.h"
0011 
0012 using namespace Imap;
0013 
0014 /**
0015  */
0016 class ImapServerProxyTest : public QObject
0017 {
0018     Q_OBJECT
0019 
0020     QTemporaryDir tempDir;
0021     QString targetPath;
0022 private slots:
0023     void initTestCase()
0024     {
0025         Sink::Test::initTest();
0026         QTcpSocket socket;
0027         socket.connectToHost("localhost", 143);
0028         QVERIFY(socket.waitForConnected(200));
0029         system("resetmailbox.sh");
0030     }
0031 
0032     void cleanup()
0033     {
0034     }
0035 
0036     void init()
0037     {
0038         qDebug();
0039         qDebug() << "-----------------------------------------";
0040         qDebug();
0041     }
0042 
0043     void testLogin()
0044     {
0045         ImapServerProxy imap("localhost", 143, Imap::EncryptionMode::NoEncryption);
0046         VERIFYEXEC(imap.login("doe", "doe"));
0047     }
0048 
0049     void testLoginFailure()
0050     {
0051         //Using a bogus ip instead of a bogus hostname avoids getting stuck in the hostname lookup
0052         ImapServerProxy imap("111.111.1.1", 143, Imap::EncryptionMode::NoEncryption);
0053         VERIFYEXEC_FAIL(imap.login("doe", "doe"));
0054     }
0055 
0056     void testFetchFolders()
0057     {
0058         QMap<QString, QString> expectedFolderAndParent {
0059             {"INBOX", ""},
0060             {"Drafts", ""},
0061             {"Trash", ""},
0062             {"test", ""}
0063         };
0064         ImapServerProxy imap("localhost", 143, Imap::EncryptionMode::NoEncryption);
0065         VERIFYEXEC(imap.login("doe", "doe"));
0066         QVector<Folder> list;
0067         VERIFYEXEC(imap.fetchFolders([&](const Folder &f){ list << f;}));
0068         for (const auto &f : list) {
0069             QVERIFY2(expectedFolderAndParent.contains(f.name()), QString{"Didn't expect folder %1"}.arg(f.name()).toUtf8());
0070             QCOMPARE(expectedFolderAndParent.value(f.name()), f.parentPath());
0071             expectedFolderAndParent.remove(f.name());
0072         }
0073         QVERIFY(expectedFolderAndParent.isEmpty());
0074 //examples/imapresource/tests/imapserverproxytest testFetchFolders
0075     }
0076 
0077     void testAppendMail()
0078     {
0079         ImapServerProxy imap("localhost", 143, Imap::EncryptionMode::NoEncryption);
0080         VERIFYEXEC(imap.login("doe", "doe"));
0081 
0082 
0083         auto mail = KMime::Message::Ptr::create();
0084         mail->from(true)->from7BitString("<doe@example.org>");
0085         mail->to(true)->from7BitString("<doe@example.org>");
0086         mail->subject(true)->from7BitString("subject");
0087         mail->setBody("Body");
0088         auto content = mail->encodedContent(true);
0089 
0090         KIMAP2::MessageFlags flags;
0091         flags << Imap::Flags::Seen;
0092         flags << Imap::Flags::Flagged;
0093         VERIFYEXEC(imap.append("INBOX.test", content, flags, QDateTime::currentDateTimeUtc()));
0094     }
0095 
0096     void testFetchMail()
0097     {
0098         ImapServerProxy imap("localhost", 143, Imap::EncryptionMode::NoEncryption);
0099         VERIFYEXEC(imap.login("doe", "doe"));
0100 
0101         KIMAP2::FetchJob::FetchScope scope;
0102         scope.mode = KIMAP2::FetchJob::FetchScope::Headers;
0103         int count = 0;
0104         auto job = imap.select("INBOX.test").then<void>(imap.fetch(KIMAP2::ImapSet::fromImapSequenceSet("1:*"), scope,
0105                     [&count](const KIMAP2::FetchJob::Result &) {
0106                         count++;
0107                     }));
0108 
0109         VERIFYEXEC(job);
0110         QCOMPARE(count, 1);
0111     }
0112 
0113     void testRemoveMail()
0114     {
0115         ImapServerProxy imap("localhost", 143, Imap::EncryptionMode::NoEncryption);
0116         VERIFYEXEC(imap.login("doe", "doe"));
0117         VERIFYEXEC(imap.remove("INBOX.test", "1:*"));
0118 
0119         KIMAP2::FetchJob::FetchScope scope;
0120         scope.mode = KIMAP2::FetchJob::FetchScope::Headers;
0121         int count = 0;
0122         auto job = imap.select("INBOX.test").then<void>(imap.fetch(KIMAP2::ImapSet::fromImapSequenceSet("1:*"), scope,
0123                     [&count](const KIMAP2::FetchJob::Result &) {
0124                         count++;
0125                     }));
0126 
0127         VERIFYEXEC(job);
0128         QCOMPARE(count, 0);
0129     }
0130 
0131     void testSessionCache()
0132     {
0133         Imap::SessionCache sessionCache;
0134         {
0135             //Using a bogus ip instead of a bogus hostname avoids getting stuck in the hostname lookup
0136             ImapServerProxy imap("111.111.1.1", 143, Imap::EncryptionMode::NoEncryption);
0137             VERIFYEXEC_FAIL(imap.login("doe", "doe"));
0138             VERIFYEXEC(imap.logout());
0139             QCOMPARE(sessionCache.size(), 0);
0140         }
0141         {
0142             ImapServerProxy imap("localhost", 143, Imap::EncryptionMode::NoEncryption, Imap::AuthenticationMode::Plain, &sessionCache);
0143             VERIFYEXEC(imap.login("doe", "doe"));
0144             QCOMPARE(sessionCache.size(), 0);
0145             VERIFYEXEC(imap.logout());
0146             QCOMPARE(sessionCache.size(), 1);
0147 
0148             auto cachedSession = sessionCache.getSession();
0149             QCOMPARE(cachedSession.isExpired(), false);
0150             QCOMPARE(cachedSession.isConnected(), true);
0151 
0152             cachedSession.mSession->close();
0153             QTest::qWait(1000);
0154             QCOMPARE(cachedSession.isConnected(), false);
0155 
0156             //TODO this timeout depends on Imap::CachedSession::mTimer
0157             QTest::qWait(30000);
0158             QCOMPARE(cachedSession.isExpired(), true);
0159         }
0160     }
0161 
0162     //TODO Find a way to deal with the below error:
0163     // A000029 NO Server ( s ) unavailable to complete operation .\n Sent command: EXAMINE\"INBOX\" (CONDSTORE)
0164     // We unfortunately don't really have a way to distinguish transient vs. terminal errors, but I suppose we shouldn't normally run into NO responses at all,
0165     // so perhaps just closing the socket makes sense?
0166     void testExamine()
0167     {
0168         Imap::SessionCache sessionCache;
0169         ImapServerProxy imap("localhost", 143, Imap::EncryptionMode::NoEncryption, Imap::AuthenticationMode::Plain, &sessionCache);
0170         VERIFYEXEC(imap.login("doe", "doe"));
0171 
0172         VERIFYEXEC(imap.examine("INBOX"));
0173         VERIFYEXEC_FAIL(imap.examine("INBOX.failure"));
0174 
0175         VERIFYEXEC(imap.examine("INBOX"));
0176     }
0177 };
0178 
0179 QTEST_MAIN(ImapServerProxyTest)
0180 #include "imapserverproxytest.moc"