1 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
3 This file is part of the Trojita Qt IMAP e-mail client,
4 http://trojita.flaska.net/
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of
9 the License or (at your option) version 3 or any later version
10 accepted by the membership of KDE e.V. (or its successor approved
11 by the membership of KDE e.V.), which shall act as a proxy
12 defined in Section 14 of version 3 of the license.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "test_Imap_CopyAndFlagOperations.h"
24 #include "Utils/FakeCapabilitiesInjector.h"
25 #include "Streams/FakeSocket.h"
26 #include "Imap/Model/ItemRoles.h"
27 #include "Imap/Model/MailboxTree.h"
28 #include "Imap/Model/MsgListModel.h"
29 #include "Imap/Model/ThreadingMsgListModel.h"
30 #include "Imap/Tasks/ObtainSynchronizedMailboxTask.h"
32 using namespace Imap::Mailbox
;
34 void CopyAndFlagTest::testMoveRfc3501()
36 helperMove(JUST_3501
);
39 void CopyAndFlagTest::testMoveUidPlus()
41 helperMove(HAS_UIDPLUS
);
44 void CopyAndFlagTest::testMoveRfcMove()
49 void CopyAndFlagTest::helperMove(const MoveFeatures serverFeatures
)
51 FakeCapabilitiesInjector
injector(model
);
52 switch (serverFeatures
) {
57 injector
.injectCapability(QStringLiteral("UIDPLUS"));
60 injector
.injectCapability(QStringLiteral("MOVE"));
64 // Push the data to the cache
68 for (uint i
= 1; i
<= existsA
; ++i
)
70 helperSyncAWithMessagesEmptyState();
72 helperVerifyUidMapA();
73 QString mailbox
= QStringLiteral("a");
74 QString del
= QStringLiteral("\\Deleted");
75 Q_FOREACH(const auto uid
, uidMapA
) {
76 // No message shall be marked as deleted
77 QVERIFY(!model
->cache()->msgFlags(mailbox
, uid
).contains(del
));
80 // FIXME: this API sucks rather hard; it will have to change to use indexes at some point, if only for sanity
81 auto aMailboxPtr
= dynamic_cast<TreeItemMailbox
*>(Model::realTreeItem(idxA
));
82 Q_ASSERT(aMailboxPtr
);
83 model
->copyMoveMessages(aMailboxPtr
, QStringLiteral("b"), Imap::Uids() << 2, MOVE
);
85 if (serverFeatures
== HAS_MOVE
) {
86 cClient(t
.mk("UID MOVE 2 b\r\n"));
87 cServer("* 2 EXPUNGE\r\n" + t
.last("OK moved\r\n"));
91 helperVerifyUidMapA();
92 Q_FOREACH(const auto uid
, uidMapA
) {
93 // None message shall be marked as deleted
94 QVERIFY(!model
->cache()->msgFlags(mailbox
, uid
).contains(del
));
98 cClient(t
.mk("UID COPY 2 b\r\n"));
99 cServer(t
.last("OK copied\r\n"));
100 cClient(t
.mk("UID STORE 2 +FLAGS.SILENT \\Deleted\r\n"));
101 cServer(t
.last("OK stored\r\n"));
102 QVERIFY(model
->cache()->msgFlags(mailbox
, 2).contains(del
));
103 if (serverFeatures
== HAS_UIDPLUS
) {
104 cClient(t
.mk("UID EXPUNGE 2\r\n"));
105 cServer("* 2 EXPUNGE\r\n" + t
.last("OK expunged\r\n"));
109 helperVerifyUidMapA();
110 Q_FOREACH(const auto uid
, uidMapA
) {
111 // None message shall be marked as deleted
112 QVERIFY(!model
->cache()->msgFlags(mailbox
, uid
).contains(del
));
120 void CopyAndFlagTest::testUpdateAllFlags()
122 // Push the data to the cache
126 for (uint i
= 1; i
<= existsA
; ++i
)
128 // cannot use helperSyncAWithMessagesEmptyState(), we want to have control over the flags
129 QCOMPARE(model
->rowCount(msgListA
), 0);
130 cClient(t
.mk("SELECT a\r\n"));
131 cServer("* 4 EXISTS\r\n"
132 "* OK [UIDVALIDITY 666] UIDs valid\r\n"
133 "* OK [UIDNEXT 5] Predicted next UID\r\n"
134 + t
.last("OK selected\r\n"));
135 cClient(t
.mk("UID SEARCH ALL\r\n"));
136 cServer("* SEARCH 3 4 2 1\r\n" + t
.last("OK search\r\n"));
137 cClient(t
.mk("FETCH 1:4 (FLAGS)\r\n"));
138 cServer("* 1 FETCH (FLAGS ())\r\n"
139 "* 2 FETCH (FLAGS (\\SEEN))\r\n"
140 "* 3 FETCH (FLAGS (\\Answered \\Seen))\r\n"
141 "* 4 FETCH (FLAGS (\\Answered))\r\n"
142 + t
.last("OK fetched\r\n"));
144 helperVerifyUidMapA();
145 QString mailbox
= QStringLiteral("a");
146 QString seen
= QStringLiteral("\\Seen");
147 QVERIFY(!msgListA
.child(0, 0).data(RoleMessageIsMarkedRead
).toBool());
148 QVERIFY(!model
->cache()->msgFlags(mailbox
, 1).contains(seen
));
149 QVERIFY(msgListA
.child(1, 0).data(RoleMessageIsMarkedRead
).toBool());
150 QVERIFY(model
->cache()->msgFlags(mailbox
, 2).contains(seen
));
151 QVERIFY(msgListA
.child(2, 0).data(RoleMessageIsMarkedRead
).toBool());
152 QVERIFY(model
->cache()->msgFlags(mailbox
, 3).contains(seen
));
153 QVERIFY(!msgListA
.child(3, 0).data(RoleMessageIsMarkedRead
).toBool());
154 QVERIFY(!model
->cache()->msgFlags(mailbox
, 4).contains(seen
));
156 // Mark all messages as read
157 model
->markMailboxAsRead(idxA
);
158 cClient(t
.mk("STORE 1:* +FLAGS.SILENT \\Seen\r\n"));
159 cServer(t
.last("OK stored\r\n"));
160 for (uint i
= 0; i
< existsA
; ++i
) {
161 QVERIFY(msgListA
.child(i
, 0).data(RoleMessageIsMarkedRead
).toBool());
162 QVERIFY(model
->cache()->msgFlags(mailbox
, uidMapA
[i
]).contains(seen
));
169 QTEST_GUILESS_MAIN(CopyAndFlagTest
)