diff --git a/kimap/storejob.cpp b/kimap/storejob.cpp index ca068ec73..84da4efb2 100644 --- a/kimap/storejob.cpp +++ b/kimap/storejob.cpp @@ -1,179 +1,194 @@ /* Copyright (c) 2009 Kevin Ottens This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "storejob.h" +#include #include #include "job_p.h" #include "message_p.h" #include "session_p.h" namespace KIMAP { class StoreJobPrivate : public JobPrivate { public: StoreJobPrivate( Session *session, const QString& name ) : JobPrivate( session, name ) { } ~StoreJobPrivate() { } ImapSet set; bool uidBased; StoreJob::StoreMode mode; MessageFlags flags; QMap resultingFlags; }; } using namespace KIMAP; StoreJob::StoreJob( Session *session ) : Job( *new StoreJobPrivate(session, i18n("Store")) ) { Q_D(StoreJob); d->mode = SetFlags; } StoreJob::~StoreJob() { } void StoreJob::setSequenceSet( const ImapSet &set ) { Q_D(StoreJob); d->set = set; } ImapSet StoreJob::sequenceSet() const { Q_D(const StoreJob); return d->set; } void StoreJob::setUidBased(bool uidBased) { Q_D(StoreJob); d->uidBased = uidBased; } bool StoreJob::isUidBased() const { Q_D(const StoreJob); return d->uidBased; } void StoreJob::setFlags( const MessageFlags &flags ) { Q_D(StoreJob); d->flags = flags; } MessageFlags StoreJob::flags() const { Q_D(const StoreJob); return d->flags; } void StoreJob::setMode( StoreMode mode ) { Q_D(StoreJob); d->mode = mode; } StoreJob::StoreMode StoreJob::mode() const { Q_D(const StoreJob); return d->mode; } QMap StoreJob::resultingFlags() const { Q_D(const StoreJob); return d->resultingFlags; } void StoreJob::doStart() { Q_D(StoreJob); QByteArray parameters = d->set.toImapSequenceSet()+' '; switch ( d->mode ) { case SetFlags: parameters+= "FLAGS"; break; case AppendFlags: parameters+= "+FLAGS"; break; case RemoveFlags: parameters+= "-FLAGS"; break; } parameters+=" ("; foreach ( const QByteArray &flag, d->flags ) { parameters+=flag+' '; } if (!d->flags.isEmpty()) parameters.chop(1); parameters+=')'; qDebug("%s", parameters.constData()); QByteArray command = "STORE"; if ( d->uidBased ) { command = "UID "+command; } d->tag = d->sessionInternal()->sendCommand( command, parameters ); } void StoreJob::handleResponse( const Message &response ) { Q_D(StoreJob); if (handleErrorReplies(response) == NotHandled ) { if ( response.content.size() == 4 && response.content[2].toString()=="FETCH" && response.content[3].type()==Message::Part::List ) { int id = response.content[1].toString().toInt(); + qint64 uid = 0; + bool uidFound = false; + QList resultingFlags; + QList content = response.content[3].toList(); for ( QList::ConstIterator it = content.constBegin(); it!=content.constEnd(); ++it ) { QByteArray str = *it; ++it; if ( str=="FLAGS" ) { if ( (*it).startsWith('(') && (*it).endsWith(')') ) { QByteArray str = *it; str.chop(1); str.remove(0, 1); - d->resultingFlags[id] = str.split(' '); + resultingFlags = str.split(' '); } else { - d->resultingFlags[id] << *it; + resultingFlags << *it; } + } else if ( str=="UID" ) { + uid = it->toLongLong(&uidFound); } } + + if ( !d->uidBased ) { + d->resultingFlags[id] = resultingFlags; + } else if ( uidFound ) { + d->resultingFlags[uid] = resultingFlags; + } else { + kWarning() << "We asked for UID but the server didn't give it back, resultingFlags not stored."; + } } } } #include "storejob.moc" diff --git a/kimap/tests/CMakeLists.txt b/kimap/tests/CMakeLists.txt index bd1aee84e..9f69663c8 100644 --- a/kimap/tests/CMakeLists.txt +++ b/kimap/tests/CMakeLists.txt @@ -1,54 +1,55 @@ include_directories( ${CMAKE_SOURCE_DIR}/kimap ${Boost_INCLUDE_DIR}) set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) MACRO(KIMAP_UNIT_TESTS) FOREACH(_testname ${ARGN}) kde4_add_unit_test(${_testname} TESTNAME kimap-${_testname} NOGUI ${_testname}.cpp) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") target_link_libraries(${_testname} ${KDE4_KDECORE_LIBS} ${QT_QTTEST_LIBRARY} kimap kmime) ENDFOREACH(_testname) ENDMACRO(KIMAP_UNIT_TESTS) MACRO(KIMAP_EXECUTABLE_TESTS) FOREACH(_testname ${ARGN}) kde4_add_executable(${_testname} NOGUI TEST ${_testname}.cpp) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") target_link_libraries(${_testname} ${KDE4_KDECORE_LIBS} ${KDE4_KIO_LIBS} kimap kmime) ENDFOREACH(_testname) ENDMACRO(KIMAP_EXECUTABLE_TESTS) ### convenience macro MACRO(ADD_IMAPLIB_TEST _source) set(_test ${_source} fakeserver.cpp ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") get_filename_component(_name ${_source} NAME_WE) kde4_add_unit_test(${_name} TESTNAME kimap-${_name} ${_test}) target_link_libraries(${_name} kimap ${QT_QTTEST_LIBRARY} ${KDE4_KDECORE_LIBS} ${QT_QTGUI_LIBRARY} ${QT_QTNETWORK_LIBRARY} ) ENDMACRO(ADD_IMAPLIB_TEST) ### tests ADD_IMAPLIB_TEST(loginjobtest.cpp) ADD_IMAPLIB_TEST(logoutjobtest.cpp) ADD_IMAPLIB_TEST(capabilitiesjobtest.cpp) ADD_IMAPLIB_TEST(selectjobtest.cpp) ADD_IMAPLIB_TEST(createjobtest.cpp) ADD_IMAPLIB_TEST(deletejobtest.cpp) ADD_IMAPLIB_TEST(renamejobtest.cpp) ADD_IMAPLIB_TEST(subscribejobtest.cpp) ADD_IMAPLIB_TEST(unsubscribejobtest.cpp) ADD_IMAPLIB_TEST(listjobtest.cpp) +ADD_IMAPLIB_TEST(storejobtest.cpp) ########### automated tests ############### KIMAP_UNIT_TESTS( testrfccodecs testsession ) ########### manual tests ############### KIMAP_EXECUTABLE_TESTS( testimapserver ) diff --git a/kimap/tests/storejobtest.cpp b/kimap/tests/storejobtest.cpp new file mode 100644 index 000000000..8befcaa3b --- /dev/null +++ b/kimap/tests/storejobtest.cpp @@ -0,0 +1,90 @@ +/* + Copyright (C) 2009 Kevin Ottens + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include + +#include "fakeserver.h" +#include "kimap/session.h" +#include "kimap/storejob.h" + +#include +#include +#include + +Q_DECLARE_METATYPE(QList) + +class StoreJobTest: public QObject { + Q_OBJECT + +private Q_SLOTS: + +void testStore_data() { + QTest::addColumn( "uidBased" ); + QTest::addColumn( "id" ); + QTest::addColumn( "uid" ); + QTest::addColumn< QList >( "flags" ); + QTest::addColumn( "response" ); + + QStringList response; + response << "* 3 FETCH (FLAGS (\\Seen \\Foo) UID 1096)"; + response << "A000001 OK STORE completed"; + + QTest::newRow( "not uid based" ) << false << qint64(3) << qint64(1096) + << ( QList() << "\\Seen" << "\\Foo" ) + << response; + + QTest::newRow( "uid based" ) << true << qint64(3) << qint64(1096) + << ( QList() << "\\Seen" << "\\Foo" ) + << response; +} + +void testStore() +{ + FakeServer fakeServer; + fakeServer.start(); + KIMAP::Session session("127.0.0.1", 5989); + QFETCH( bool, uidBased ); + QFETCH( qint64, id ); + QFETCH( qint64, uid ); + QFETCH( QList, flags ); + QFETCH( QStringList, response ); + + fakeServer.setResponse( response ); + + KIMAP::StoreJob *job = new KIMAP::StoreJob(&session); + job->setUidBased( uidBased ); + job->setSequenceSet( KIMAP::ImapSet( uidBased ? uid : id ) ); + job->setFlags( flags ); + job->setMode( KIMAP::StoreJob::SetFlags ); + bool result = job->exec(); + QVERIFY(result); + if ( uidBased ) { + QVERIFY( job->resultingFlags().contains( uid ) ); + } else { + QVERIFY( job->resultingFlags().contains( id ) ); + } + + fakeServer.quit(); +} + + +}; + +QTEST_KDEMAIN( StoreJobTest, NoGUI ) + +#include "storejobtest.moc"