File indexing completed on 2024-11-24 04:53:30
0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> 0002 0003 This file is part of the Trojita Qt IMAP e-mail client, 0004 http://trojita.flaska.net/ 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License as 0008 published by the Free Software Foundation; either version 2 of 0009 the License or (at your option) version 3 or any later version 0010 accepted by the membership of KDE e.V. (or its successor approved 0011 by the membership of KDE e.V.), which shall act as a proxy 0012 defined in Section 14 of version 3 of the license. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #include "test_Imap_CopyAndFlagOperations.h" 0024 #include "Utils/FakeCapabilitiesInjector.h" 0025 #include "Streams/FakeSocket.h" 0026 #include "Imap/Model/ItemRoles.h" 0027 #include "Imap/Model/MailboxTree.h" 0028 #include "Imap/Model/MsgListModel.h" 0029 #include "Imap/Model/ThreadingMsgListModel.h" 0030 #include "Imap/Tasks/ObtainSynchronizedMailboxTask.h" 0031 0032 using namespace Imap::Mailbox; 0033 0034 void CopyAndFlagTest::testMoveRfc3501() 0035 { 0036 helperMove(JUST_3501); 0037 } 0038 0039 void CopyAndFlagTest::testMoveUidPlus() 0040 { 0041 helperMove(HAS_UIDPLUS); 0042 } 0043 0044 void CopyAndFlagTest::testMoveRfcMove() 0045 { 0046 helperMove(HAS_MOVE); 0047 } 0048 0049 void CopyAndFlagTest::helperMove(const MoveFeatures serverFeatures) 0050 { 0051 FakeCapabilitiesInjector injector(model); 0052 switch (serverFeatures) { 0053 case JUST_3501: 0054 // nothing is needed 0055 break; 0056 case HAS_UIDPLUS: 0057 injector.injectCapability(QStringLiteral("UIDPLUS")); 0058 break; 0059 case HAS_MOVE: 0060 injector.injectCapability(QStringLiteral("MOVE")); 0061 break; 0062 } 0063 0064 // Push the data to the cache 0065 existsA = 3; 0066 uidNextA = 5; 0067 uidValidityA = 666; 0068 for (uint i = 1; i <= existsA; ++i) 0069 uidMapA << i; 0070 helperSyncAWithMessagesEmptyState(); 0071 helperCheckCache(); 0072 helperVerifyUidMapA(); 0073 QString mailbox = QStringLiteral("a"); 0074 QString del = QStringLiteral("\\Deleted"); 0075 Q_FOREACH(const auto uid, uidMapA) { 0076 // No message shall be marked as deleted 0077 QVERIFY(!model->cache()->msgFlags(mailbox, uid).contains(del)); 0078 } 0079 0080 // FIXME: this API sucks rather hard; it will have to change to use indexes at some point, if only for sanity 0081 auto aMailboxPtr = dynamic_cast<TreeItemMailbox *>(Model::realTreeItem(idxA)); 0082 Q_ASSERT(aMailboxPtr); 0083 model->copyMoveMessages(aMailboxPtr, QStringLiteral("b"), Imap::Uids() << 2, MOVE); 0084 0085 if (serverFeatures == HAS_MOVE) { 0086 cClient(t.mk("UID MOVE 2 b\r\n")); 0087 cServer("* 2 EXPUNGE\r\n" + t.last("OK moved\r\n")); 0088 --existsA; 0089 uidMapA.remove(1); 0090 helperCheckCache(); 0091 helperVerifyUidMapA(); 0092 Q_FOREACH(const auto uid, uidMapA) { 0093 // None message shall be marked as deleted 0094 QVERIFY(!model->cache()->msgFlags(mailbox, uid).contains(del)); 0095 } 0096 cEmpty(); 0097 } else { 0098 cClient(t.mk("UID COPY 2 b\r\n")); 0099 cServer(t.last("OK copied\r\n")); 0100 cClient(t.mk("UID STORE 2 +FLAGS.SILENT \\Deleted\r\n")); 0101 cServer(t.last("OK stored\r\n")); 0102 QVERIFY(model->cache()->msgFlags(mailbox, 2).contains(del)); 0103 if (serverFeatures == HAS_UIDPLUS) { 0104 cClient(t.mk("UID EXPUNGE 2\r\n")); 0105 cServer("* 2 EXPUNGE\r\n" + t.last("OK expunged\r\n")); 0106 --existsA; 0107 uidMapA.remove(1); 0108 helperCheckCache(); 0109 helperVerifyUidMapA(); 0110 Q_FOREACH(const auto uid, uidMapA) { 0111 // None message shall be marked as deleted 0112 QVERIFY(!model->cache()->msgFlags(mailbox, uid).contains(del)); 0113 } 0114 } 0115 cEmpty(); 0116 } 0117 justKeepTask(); 0118 } 0119 0120 void CopyAndFlagTest::testUpdateAllFlags() 0121 { 0122 // Push the data to the cache 0123 existsA = 4; 0124 uidNextA = 5; 0125 uidValidityA = 666; 0126 for (uint i = 1; i <= existsA; ++i) 0127 uidMapA << i; 0128 // cannot use helperSyncAWithMessagesEmptyState(), we want to have control over the flags 0129 QCOMPARE(model->rowCount(msgListA), 0); 0130 cClient(t.mk("SELECT a\r\n")); 0131 cServer("* 4 EXISTS\r\n" 0132 "* OK [UIDVALIDITY 666] UIDs valid\r\n" 0133 "* OK [UIDNEXT 5] Predicted next UID\r\n" 0134 + t.last("OK selected\r\n")); 0135 cClient(t.mk("UID SEARCH ALL\r\n")); 0136 cServer("* SEARCH 3 4 2 1\r\n" + t.last("OK search\r\n")); 0137 cClient(t.mk("FETCH 1:4 (FLAGS)\r\n")); 0138 cServer("* 1 FETCH (FLAGS ())\r\n" 0139 "* 2 FETCH (FLAGS (\\SEEN))\r\n" 0140 "* 3 FETCH (FLAGS (\\Answered \\Seen))\r\n" 0141 "* 4 FETCH (FLAGS (\\Answered))\r\n" 0142 + t.last("OK fetched\r\n")); 0143 helperCheckCache(); 0144 helperVerifyUidMapA(); 0145 QString mailbox = QStringLiteral("a"); 0146 QString seen = QStringLiteral("\\Seen"); 0147 QVERIFY(!msgListA.model()->index(0, 0, msgListA).data(RoleMessageIsMarkedRead).toBool()); 0148 QVERIFY(!model->cache()->msgFlags(mailbox, 1).contains(seen)); 0149 QVERIFY(msgListA.model()->index(1, 0, msgListA).data(RoleMessageIsMarkedRead).toBool()); 0150 QVERIFY(model->cache()->msgFlags(mailbox, 2).contains(seen)); 0151 QVERIFY(msgListA.model()->index(2, 0, msgListA).data(RoleMessageIsMarkedRead).toBool()); 0152 QVERIFY(model->cache()->msgFlags(mailbox, 3).contains(seen)); 0153 QVERIFY(!msgListA.model()->index(3, 0, msgListA).data(RoleMessageIsMarkedRead).toBool()); 0154 QVERIFY(!model->cache()->msgFlags(mailbox, 4).contains(seen)); 0155 0156 // Mark all messages as read 0157 model->markMailboxAsRead(idxA); 0158 cClient(t.mk("STORE 1:* +FLAGS.SILENT \\Seen\r\n")); 0159 cServer(t.last("OK stored\r\n")); 0160 for (uint i = 0; i < existsA; ++i) { 0161 QVERIFY(msgListA.model()->index(i, 0, msgListA).data(RoleMessageIsMarkedRead).toBool()); 0162 QVERIFY(model->cache()->msgFlags(mailbox, uidMapA[i]).contains(seen)); 0163 } 0164 0165 cEmpty(); 0166 justKeepTask(); 0167 } 0168 0169 QTEST_GUILESS_MAIN(CopyAndFlagTest)