/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include "TestHarness.h" #include "nsCOMPtr.h" #include "msgCore.h" #include "nsImapProtocol.h" struct msgState { uint32_t uid; uint16_t flag; uint32_t index; }; char errorMsg[200]; const char* MainChecks(nsImapFlagAndUidState* flagState, struct msgState* expectedState, uint32_t numMessages, uint32_t expectedNumUnread) { // Verify that flag state matches the expected state. for (uint32_t i = 0; i < numMessages; i++) { uint32_t uid; uint16_t flag; flagState->GetUidOfMessage(expectedState[i].index, &uid); flagState->GetMessageFlags(expectedState[i].index, &flag); if (uid != expectedState[i].uid) { PR_snprintf(errorMsg, sizeof(errorMsg), "expected uid %d, got %d at index %d\n", expectedState[i].uid, uid, i); return errorMsg; } if (flag != expectedState[i].flag) { PR_snprintf(errorMsg, sizeof(errorMsg), "expected flag %d, got %d at index %d\n", expectedState[i].flag, flag, i); return errorMsg; } } int32_t numMsgsInFlagState; int32_t numUnread = 0; int32_t expectedMsgIndex = 0; flagState->GetNumberOfMessages(&numMsgsInFlagState); for (int32_t msgIndex = 0; msgIndex < numMsgsInFlagState; msgIndex++) { uint32_t uidOfMessage; flagState->GetUidOfMessage(msgIndex, &uidOfMessage); if (!uidOfMessage || uidOfMessage == nsMsgKey_None) continue; if (uidOfMessage != expectedState[expectedMsgIndex++].uid) { PR_snprintf( errorMsg, sizeof(errorMsg), "got a uid w/o a match in expected state, uid %d at index %d\n", uidOfMessage, msgIndex); return errorMsg; } imapMessageFlagsType flags; flagState->GetMessageFlags(msgIndex, &flags); if (!(flags & kImapMsgSeenFlag)) numUnread++; } if (numUnread != expectedNumUnread) { PR_snprintf(errorMsg, sizeof(errorMsg), "expected %d unread message, got %d\n", expectedNumUnread, numUnread); return errorMsg; } return nullptr; } // General note about return values: // return 1 for a setup or xpcom type failure, return 2 for a real test failure int main(int argc, char** argv) { ScopedXPCOM xpcom("TestImapFlagAndUidState.cpp"); if (xpcom.failed()) return 1; struct msgState msgState1[] = {{10, kImapMsgSeenFlag, 0}, {15, kImapMsgSeenFlag, 1}, {16, kImapMsgSeenFlag, 2}, {17, kImapMsgSeenFlag, 3}, {18, kImapMsgSeenFlag, 4}}; RefPtr flagState = new nsImapFlagAndUidState(10); int32_t numMsgs = sizeof(msgState1) / sizeof(msgState1[0]); for (int32_t i = 0; i < numMsgs; i++) flagState->AddUidFlagPair(msgState1[i].uid, msgState1[i].flag, msgState1[i].index); const char* error = MainChecks(flagState, msgState1, numMsgs, 0); if (error) { printf("TEST-UNEXPECTED-FAIL | %s | %s\n", __FILE__, error); return 1; } // Now reset all flagState->Reset(); // This tests adding some messages to a partial uid flag state, // i.e., CONDSTORE. struct msgState msgState2[] = {{68, kImapMsgSeenFlag, 69}, {71, kImapMsgSeenFlag, 70}, {73, kImapMsgSeenFlag, 71}}; numMsgs = sizeof(msgState2) / sizeof(msgState2[0]); for (int32_t i = 0; i < numMsgs; i++) flagState->AddUidFlagPair(msgState2[i].uid, msgState2[i].flag, msgState2[i].index); error = MainChecks(flagState, msgState2, numMsgs, 0); if (error) { printf("TEST-UNEXPECTED-FAIL | %s | %s\n", __FILE__, error); return 1; } // Reset all flagState->Reset(); // This tests generating a uid string from a non-sequential set of // messages where the first message is not in the flag state, but the // missing message from the sequence is in the set. I.e., we're // generating a uid string from 69,71, but only 70 and 71 are in // the flag state. struct msgState msgState3[] = {{10, kImapMsgSeenFlag, 0}, {69, kImapMsgSeenFlag, 1}, {70, kImapMsgSeenFlag, 2}, {71, kImapMsgSeenFlag, 3}}; flagState->SetPartialUIDFetch(false); numMsgs = sizeof(msgState3) / sizeof(msgState3[0]); for (int32_t i = 0; i < numMsgs; i++) flagState->AddUidFlagPair(msgState3[i].uid, msgState3[i].flag, msgState3[i].index); flagState->ExpungeByIndex(2); nsCString uidString; uint32_t msgUids[] = {69, 71}; uint32_t msgCount = 2; AllocateImapUidString(&msgUids[0], msgCount, flagState, uidString); if (!uidString.EqualsLiteral("71")) { printf("TEST-UNEXPECTED-FAIL | uid String is %s, not 71 | %s\n", uidString.get(), __FILE__); return -1; } // Reset all flagState->Reset(); // This tests the middle message missing from the flag state. struct msgState msgState4[] = {{10, kImapMsgSeenFlag, 0}, {69, kImapMsgSeenFlag, 1}, {70, kImapMsgSeenFlag, 2}, {71, kImapMsgSeenFlag, 3}, {73, kImapMsgSeenFlag, 4}}; flagState->SetPartialUIDFetch(false); numMsgs = sizeof(msgState4) / sizeof(msgState4[0]); for (int32_t i = 0; i < numMsgs; i++) flagState->AddUidFlagPair(msgState4[i].uid, msgState4[i].flag, msgState4[i].index); flagState->ExpungeByIndex(4); uint32_t msgUids2[] = {69, 71, 73}; msgCount = 3; nsCString uidString2; AllocateImapUidString(&msgUids2[0], msgCount, flagState, uidString2); if (!uidString2.EqualsLiteral("69,73")) { printf("TEST-UNEXPECTED-FAIL | uid String is %s, not 71 | %s\n", uidString.get(), __FILE__); return -1; } printf("TEST-PASS | %s | all tests passed\n", __FILE__); return 0; }