ferencd@0: // ferencd@0: // VMime library (http://www.vmime.org) ferencd@0: // Copyright (C) 2002-2014 Vincent Richard ferencd@0: // ferencd@0: // This program is free software; you can redistribute it and/or ferencd@0: // modify it under the terms of the GNU General Public License as ferencd@0: // published by the Free Software Foundation; either version 3 of ferencd@0: // the License, or (at your option) any later version. ferencd@0: // ferencd@0: // This program is distributed in the hope that it will be useful, ferencd@0: // but WITHOUT ANY WARRANTY; without even the implied warranty of ferencd@0: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ferencd@0: // General Public License for more details. ferencd@0: // ferencd@0: // You should have received a copy of the GNU General Public License along ferencd@0: // with this program; if not, write to the Free Software Foundation, Inc., ferencd@0: // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ferencd@0: // ferencd@0: // Linking this library statically or dynamically with other modules is making ferencd@0: // a combined work based on this library. Thus, the terms and conditions of ferencd@0: // the GNU General Public License cover the whole combination. ferencd@0: // ferencd@0: ferencd@0: #include "tests/testUtils.hpp" ferencd@0: ferencd@0: #include "vmime/net/imap/IMAPUtils.hpp" ferencd@0: #include "vmime/net/imap/IMAPParser.hpp" ferencd@0: ferencd@0: ferencd@0: using namespace vmime::net::imap; ferencd@0: ferencd@0: ferencd@0: ferencd@0: VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) ferencd@0: ferencd@0: VMIME_TEST_LIST_BEGIN ferencd@0: VMIME_TEST(testQuoteString) ferencd@0: VMIME_TEST(testToModifiedUTF7) ferencd@0: VMIME_TEST(testFromModifiedUTF7) ferencd@0: VMIME_TEST(testConvertAddressList) ferencd@0: VMIME_TEST(testMessageFlagList) ferencd@0: VMIME_TEST(testDateTime) ferencd@0: VMIME_TEST(testPathToString) ferencd@0: VMIME_TEST(testStringToPath) ferencd@0: VMIME_TEST(testBuildFetchCommand) ferencd@0: VMIME_TEST_LIST_END ferencd@0: ferencd@0: ferencd@0: void testQuoteString() ferencd@0: { ferencd@0: VASSERT_EQ("unquoted", "ascii", IMAPUtils::quoteString("ascii")); ferencd@0: VASSERT_EQ("space", "\"ascii with space\"", IMAPUtils::quoteString("ascii with space")); ferencd@0: ferencd@0: VASSERT_EQ("special1", "\"(\"", IMAPUtils::quoteString("(")); ferencd@0: VASSERT_EQ("special2", "\")\"", IMAPUtils::quoteString(")")); ferencd@0: VASSERT_EQ("special3", "\"{\"", IMAPUtils::quoteString("{")); ferencd@0: VASSERT_EQ("special4", "\" \"", IMAPUtils::quoteString(" ")); ferencd@0: VASSERT_EQ("special5", "\"%\"", IMAPUtils::quoteString("%")); ferencd@0: VASSERT_EQ("special6", "\"*\"", IMAPUtils::quoteString("*")); ferencd@0: VASSERT_EQ("special7", "\"\\\"\"", IMAPUtils::quoteString("\"")); ferencd@0: VASSERT_EQ("special8", "\"\\\\\"", IMAPUtils::quoteString("\\")); ferencd@0: VASSERT_EQ("special9", "\"\x7f\"", IMAPUtils::quoteString("\x7f")); ferencd@0: ferencd@0: } ferencd@0: ferencd@0: void testToModifiedUTF7() ferencd@0: { ferencd@0: #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) ferencd@0: ferencd@0: // Example strings from RFC-1642 (modified for IMAP UTF-7) ferencd@0: VASSERT_EQ("1", "A&ImIDkQ-.", IMAPUtils::toModifiedUTF7('/', FC("A\xe2\x89\xa2\xce\x91."))); ferencd@0: VASSERT_EQ("2", "Hi Mum &Jjo-!", IMAPUtils::toModifiedUTF7('/', FC("Hi Mum \xe2\x98\xba!"))); ferencd@0: VASSERT_EQ("3", "&ZeVnLIqe-", IMAPUtils::toModifiedUTF7('/', FC("\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"))); ferencd@0: VASSERT_EQ("4", "Item 3 is &AKM- 1.", IMAPUtils::toModifiedUTF7('/', FC("Item 3 is \xc2\xa3 1."))); ferencd@0: ferencd@0: VASSERT_EQ("escape char", "&-", IMAPUtils::toModifiedUTF7('/', FC("&"))); ferencd@0: VASSERT_EQ("ascii", "plain ascii text", IMAPUtils::toModifiedUTF7('/', FC("plain ascii text"))); ferencd@0: VASSERT_EQ("special", "!\"#$%*+-;<=>@[]^_`{|}", IMAPUtils::toModifiedUTF7('/', FC("!\"#$%*+-;<=>@[]^_`{|}"))); ferencd@0: ferencd@0: #undef FC ferencd@0: } ferencd@0: ferencd@0: void testFromModifiedUTF7() ferencd@0: { ferencd@0: #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) ferencd@0: ferencd@0: // Example strings from RFC-1642 (modified for IMAP UTF-7) ferencd@0: VASSERT_EQ("1", FC("A\xe2\x89\xa2\xce\x91."), IMAPUtils::fromModifiedUTF7("A&ImIDkQ-.")); ferencd@0: VASSERT_EQ("2", FC("Hi Mum \xe2\x98\xba!"), IMAPUtils::fromModifiedUTF7("Hi Mum &Jjo-!")); ferencd@0: VASSERT_EQ("3", FC("\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"), IMAPUtils::fromModifiedUTF7("&ZeVnLIqe-")); ferencd@0: VASSERT_EQ("4", FC("Item 3 is \xc2\xa3 1."), IMAPUtils::fromModifiedUTF7("Item 3 is &AKM- 1.")); ferencd@0: ferencd@0: VASSERT_EQ("escape char", FC("&"), IMAPUtils::fromModifiedUTF7("&-")); ferencd@0: VASSERT_EQ("ascii", FC("plain ascii text"), IMAPUtils::fromModifiedUTF7("plain ascii text")); ferencd@0: VASSERT_EQ("special", FC("!\"#$%*+;<=>@[]^_`{|}"), IMAPUtils::fromModifiedUTF7("!\"#$%*+-;<=>@[]^_`{|}")); ferencd@0: ferencd@0: #undef FC ferencd@0: } ferencd@0: ferencd@0: void testConvertAddressList() ferencd@0: { ferencd@0: IMAPParser parser; ferencd@0: IMAPParser::address_list addrList; ferencd@0: ferencd@0: vmime::string line("((\"name\" NIL \"mailbox\" \"host\")(\"name2\" NIL \"mailbox2\" \"host2\"))"); ferencd@0: vmime::size_t pos = 0; ferencd@0: ferencd@0: VASSERT("parse", addrList.parseImpl(parser, line, &pos)); ferencd@0: ferencd@0: vmime::mailboxList mboxList; ferencd@0: IMAPUtils::convertAddressList(addrList, mboxList); ferencd@0: ferencd@0: VASSERT_EQ("mbox-count", 2, mboxList.getMailboxCount()); ferencd@0: VASSERT_EQ("mbox-1", "mailbox@host", mboxList.getMailboxAt(0)->getEmail().toString()); ferencd@0: VASSERT_EQ("mbox-1", "name", mboxList.getMailboxAt(0)->getName().getWholeBuffer()); ferencd@0: VASSERT_EQ("mbox-2", "mailbox2@host2", mboxList.getMailboxAt(1)->getEmail().toString()); ferencd@0: VASSERT_EQ("mbox-2", "name2", mboxList.getMailboxAt(1)->getName().getWholeBuffer()); ferencd@0: } ferencd@0: ferencd@0: void testMessageFlagList() ferencd@0: { ferencd@0: int flags = 0; ferencd@0: std::vector flagList; ferencd@0: ferencd@0: // Test each flag ferencd@0: flags = vmime::net::message::FLAG_REPLIED; ferencd@0: flagList = IMAPUtils::messageFlagList(flags); ferencd@0: VASSERT("replied", std::find(flagList.begin(), flagList.end(), "\\Answered") != flagList.end()); ferencd@0: ferencd@0: flags = vmime::net::message::FLAG_MARKED; ferencd@0: flagList = IMAPUtils::messageFlagList(flags); ferencd@0: VASSERT("marked", std::find(flagList.begin(), flagList.end(), "\\Flagged") != flagList.end()); ferencd@0: ferencd@0: flags = vmime::net::message::FLAG_DELETED; ferencd@0: flagList = IMAPUtils::messageFlagList(flags); ferencd@0: VASSERT("deleted", std::find(flagList.begin(), flagList.end(), "\\Deleted") != flagList.end()); ferencd@0: ferencd@0: flags = vmime::net::message::FLAG_SEEN; ferencd@0: flagList = IMAPUtils::messageFlagList(flags); ferencd@0: VASSERT("seen", std::find(flagList.begin(), flagList.end(), "\\Seen") != flagList.end()); ferencd@0: ferencd@0: flags = vmime::net::message::FLAG_DRAFT; ferencd@0: flagList = IMAPUtils::messageFlagList(flags); ferencd@0: VASSERT("draft", std::find(flagList.begin(), flagList.end(), "\\Draft") != flagList.end()); ferencd@0: ferencd@0: // Multiple flags ferencd@0: flags = vmime::net::message::FLAG_REPLIED; ferencd@0: flagList = IMAPUtils::messageFlagList(flags); ferencd@0: ferencd@0: VASSERT_EQ("1.size", 1, flagList.size()); ferencd@0: VASSERT("1.found", std::find(flagList.begin(), flagList.end(), "\\Answered") != flagList.end()); ferencd@0: ferencd@0: flags |= vmime::net::message::FLAG_SEEN; ferencd@0: flagList = IMAPUtils::messageFlagList(flags); ferencd@0: ferencd@0: VASSERT_EQ("2.size", 2, flagList.size()); ferencd@0: VASSERT("2.found1", std::find(flagList.begin(), flagList.end(), "\\Answered") != flagList.end()); ferencd@0: VASSERT("2.found2", std::find(flagList.begin(), flagList.end(), "\\Seen") != flagList.end()); ferencd@0: } ferencd@0: ferencd@0: void testDateTime() ferencd@0: { ferencd@0: vmime::datetime dt(2014, 3, 17, 23, 26, 22, vmime::datetime::GMT2); ferencd@0: VASSERT_EQ("datetime", "\"17-Mar-2014 23:26:22 +0200\"", IMAPUtils::dateTime(dt)); ferencd@0: } ferencd@0: ferencd@0: void testPathToString() ferencd@0: { ferencd@0: #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) ferencd@0: ferencd@0: vmime::net::folder::path path; ferencd@0: path /= FC("Hi Mum \xe2\x98\xba!"); ferencd@0: path /= FC("\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"); ferencd@0: ferencd@0: VASSERT_EQ("string", "Hi Mum &Jjo-!/&ZeVnLIqe-", IMAPUtils::pathToString('/', path)); ferencd@0: ferencd@0: #undef FC ferencd@0: } ferencd@0: ferencd@0: void testStringToPath() ferencd@0: { ferencd@0: #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) ferencd@0: ferencd@0: vmime::net::folder::path path = IMAPUtils::stringToPath('/', "Hi Mum &Jjo-!/&ZeVnLIqe-"); ferencd@0: ferencd@0: VASSERT_EQ("count", 2, path.getSize()); ferencd@0: VASSERT_EQ("component1", FC("Hi Mum \xe2\x98\xba!"), path[0]); ferencd@0: VASSERT_EQ("component2", FC("\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"), path[1]); ferencd@0: ferencd@0: #undef FC ferencd@0: } ferencd@0: ferencd@0: void testBuildFetchCommand() ferencd@0: { ferencd@0: vmime::shared_ptr cnt; ferencd@0: vmime::net::messageSet msgs = vmime::net::messageSet::byNumber(42); ferencd@0: ferencd@0: // SIZE ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = vmime::net::fetchAttributes::SIZE; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("size", "FETCH 42 RFC822.SIZE", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // FLAGS ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = vmime::net::fetchAttributes::FLAGS; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("flags", "FETCH 42 FLAGS", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // STRUCTURE ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = vmime::net::fetchAttributes::STRUCTURE; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("structure", "FETCH 42 BODYSTRUCTURE", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // UID ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = vmime::net::fetchAttributes::UID; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("uid", "FETCH 42 UID", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // ENVELOPE ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = vmime::net::fetchAttributes::ENVELOPE; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("envelope", "FETCH 42 ENVELOPE", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // CONTENT_INFO ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = vmime::net::fetchAttributes::CONTENT_INFO; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("content", "FETCH 42 BODY[HEADER.FIELDS (CONTENT_TYPE)]", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // IMPORTANCE ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = vmime::net::fetchAttributes::IMPORTANCE; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("importance", "FETCH 42 BODY[HEADER.FIELDS (IMPORTANCE X-PRIORITY)]", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // Any header attribute + full header should give RFC822.HEADER ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs; ferencd@0: attribs.add(vmime::net::fetchAttributes::ENVELOPE); ferencd@0: attribs.add(vmime::net::fetchAttributes::FULL_HEADER); ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("full-header", "FETCH 42 RFC822.HEADER", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // Test custom header ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs; ferencd@0: attribs.add("X-MyHeader"); ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("custom-header", "FETCH 42 BODY[HEADER.FIELDS (x-myheader)]", cmd->getText()); ferencd@0: } ferencd@0: ferencd@0: // Test multiple flags ferencd@0: { ferencd@0: vmime::net::fetchAttributes attribs = ferencd@0: vmime::net::fetchAttributes::UID | vmime::net::fetchAttributes::FLAGS; ferencd@0: ferencd@0: vmime::shared_ptr cmd = IMAPUtils::buildFetchCommand(cnt, msgs, attribs); ferencd@0: VASSERT_EQ("multiple", "FETCH 42 (FLAGS UID)", cmd->getText()); ferencd@0: } ferencd@0: } ferencd@0: ferencd@0: VMIME_TEST_SUITE_END