diff --git a/akonadi/tests/collectionjobtest.cpp b/akonadi/tests/collectionjobtest.cpp index 22b5a0422..f04e38b6f 100644 --- a/akonadi/tests/collectionjobtest.cpp +++ b/akonadi/tests/collectionjobtest.cpp @@ -1,541 +1,547 @@ /* Copyright (c) 2006 Volker Krause 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 #include "collectionjobtest.h" #include +#include "agentmanager.h" +#include "agentinstance.h" #include "cachepolicy.h" #include "collection.h" #include "collectioncreatejob.h" #include "collectiondeletejob.h" #include "collectionfetchjob.h" #include "collectionmodifyjob.h" #include "collectionselectjob.h" #include "collectionstatistics.h" #include "collectionstatisticsjob.h" #include "collectionpathresolver_p.h" #include "collectionutils_p.h" #include "control.h" #include "item.h" #include "kmime/messageparts.h" #include #include using namespace Akonadi; QTEST_AKONADIMAIN( CollectionJobTest, NoGUI ) void CollectionJobTest::initTestCase() { qRegisterMetaType(); Control::start(); + + // switch all resources offline to reduce interference from them + foreach ( Akonadi::AgentInstance agent, Akonadi::AgentManager::self()->instances() ) + agent.setIsOnline( false ); } static Collection findCol( const Collection::List &list, const QString &name ) { foreach ( const Collection &col, list ) if ( col.name() == name ) return col; return Collection(); } // list compare which ignores the order template static void compareLists( const QList &l1, const QList &l2 ) { QCOMPARE( l1.count(), l2.count() ); foreach ( const T entry, l1 ) { QVERIFY( l2.contains( entry ) ); } } template static T* extractAttribute( QList attrs ) { T dummy; foreach ( Attribute* attr, attrs ) { if ( attr->type() == dummy.type() ) return dynamic_cast( attr ); } return 0; } static Collection::Id res1ColId = 6; // -1; static Collection::Id res2ColId = 7; //-1; static Collection::Id res3ColId = -1; static Collection::Id searchColId = -1; void CollectionJobTest::testTopLevelList( ) { // non-recursive top-level list CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel ); QVERIFY( job->exec() ); Collection::List list = job->collections(); // check if everything is there and has the correct types and attributes QCOMPARE( list.count(), 4 ); Collection col; col = findCol( list, "res1" ); QVERIFY( col.isValid() ); res1ColId = col.id(); // for the next test QVERIFY( res1ColId > 0 ); QVERIFY( CollectionUtils::isResource( col ) ); QCOMPARE( col.parent(), Collection::root().id() ); QCOMPARE( col.resource(), QLatin1String("akonadi_knut_resource_0") ); QVERIFY( findCol( list, "res2" ).isValid() ); res2ColId = findCol( list, "res2" ).id(); QVERIFY( res2ColId > 0 ); QVERIFY( findCol( list, "res3" ).isValid() ); res3ColId = findCol( list, "res3" ).id(); QVERIFY( res3ColId > 0 ); col = findCol( list, "Search" ); searchColId = col.id(); QVERIFY( col.isValid() ); QVERIFY( CollectionUtils::isVirtualParent( col ) ); QCOMPARE( col.resource(), QLatin1String("akonadi_search_resource") ); } void CollectionJobTest::testFolderList( ) { // recursive list of physical folders CollectionFetchJob *job = new CollectionFetchJob( Collection( res1ColId ), CollectionFetchJob::Recursive ); QSignalSpy spy( job, SIGNAL(collectionsReceived(Akonadi::Collection::List)) ); QVERIFY( spy.isValid() ); QVERIFY( job->exec() ); Collection::List list = job->collections(); int count = 0; for ( int i = 0; i < spy.count(); ++i ) { Collection::List l = spy[i][0].value(); for ( int j = 0; j < l.count(); ++j ) { QVERIFY( list.count() > count + j ); QCOMPARE( list[count + j].id(), l[j].id() ); } count += l.count(); } QCOMPARE( count, list.count() ); // check if everything is there QCOMPARE( list.count(), 4 ); Collection col; QStringList contentTypes; col = findCol( list, "foo" ); QVERIFY( col.isValid() ); QCOMPARE( col.parent(), res1ColId ); QVERIFY( CollectionUtils::isFolder( col ) ); contentTypes << "message/rfc822" << "text/calendar" << "text/directory" << "application/octet-stream" << "inode/directory"; compareLists( col.contentMimeTypes(), contentTypes ); QVERIFY( findCol( list, "bar" ).isValid() ); QCOMPARE( findCol( list, "bar" ).parent(), col.id() ); QVERIFY( findCol( list, "bla" ).isValid() ); } void CollectionJobTest::testNonRecursiveFolderList( ) { CollectionFetchJob *job = new CollectionFetchJob( Collection( res1ColId ), CollectionFetchJob::Base ); QVERIFY( job->exec() ); Collection::List list = job->collections(); QCOMPARE( list.count(), 1 ); QVERIFY( findCol( list, "res1" ).isValid() ); } void CollectionJobTest::testEmptyFolderList( ) { CollectionFetchJob *job = new CollectionFetchJob( Collection( res3ColId ), CollectionFetchJob::FirstLevel ); QVERIFY( job->exec() ); Collection::List list = job->collections(); QCOMPARE( list.count(), 0 ); } void CollectionJobTest::testSearchFolderList( ) { CollectionFetchJob *job = new CollectionFetchJob( Collection( searchColId ), CollectionFetchJob::FirstLevel ); QVERIFY( job->exec() ); Collection::List list = job->collections(); QCOMPARE( list.count(), 0 ); } void CollectionJobTest::testResourceFolderList() { // non-existing resource CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::FirstLevel ); job->setResource( "i_dont_exist" ); QVERIFY( !job->exec() ); // recursive listing of all collections of an existing resource job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive ); job->setResource( "akonadi_knut_resource_0" ); QVERIFY( job->exec() ); Collection::List list = job->collections(); QCOMPARE( list.count(), 5 ); QVERIFY( findCol( list, "res1" ).isValid() ); QVERIFY( findCol( list, "foo" ).isValid() ); QVERIFY( findCol( list, "bar" ).isValid() ); QVERIFY( findCol( list, "bla" ).isValid() ); int fooId = findCol( list, "foo" ).id(); // limited listing of a resource job = new CollectionFetchJob( Collection( fooId ), CollectionFetchJob::Recursive ); job->setResource( "akonadi_knut_resource_0" ); QVERIFY( job->exec() ); list = job->collections(); QCOMPARE( list.count(), 3 ); QVERIFY( findCol( list, "bar" ).isValid() ); QVERIFY( findCol( list, "bla" ).isValid() ); } void CollectionJobTest::testCreateDeleteFolder_data() { QTest::addColumn("collection"); QTest::addColumn("creatable"); Collection col; QTest::newRow("empty") << col << false; col.setName( "new folder" ); col.setParent( res3ColId ); QTest::newRow("simple") << col << true; col.setParent( res3ColId ); col.setName( "foo" ); QTest::newRow( "existing in different resource" ) << col << true; col.setName( "mail folder" ); QStringList mimeTypes; mimeTypes << "inode/directory" << "message/rfc822"; col.setContentMimeTypes( mimeTypes ); col.setRemoteId( "remote id" ); CachePolicy policy; policy.setInheritFromParent( false ); policy.setIntervalCheckTime( 60 ); policy.setLocalParts( QStringList( MessagePart::Envelope ) ); policy.setSyncOnDemand( true ); policy.setCacheTimeout( 120 ); col.setCachePolicy( policy ); QTest::newRow( "complex" ) << col << true; col = Collection(); col.setName( "New Folder" ); col.setParent( searchColId ); QTest::newRow( "search folder" ) << col << false; col.setParent( res2ColId ); col.setName( "foo2" ); QTest::newRow( "already existing" ) << col << false; col.setName( "Bla" ); col.setParent( 2 ); QTest::newRow( "already existing with different case" ) << col << true; CollectionPathResolver *resolver = new CollectionPathResolver( "res2/foo2", this ); QVERIFY( resolver->exec() ); col.setParent( resolver->collection() ); col.setName( "new folder" ); QTest::newRow( "parent noinferior" ) << col << false; col.setParent( INT_MAX ); QTest::newRow( "missing parent" ) << col << false; } void CollectionJobTest::testCreateDeleteFolder() { QFETCH( Collection, collection ); QFETCH( bool, creatable ); CollectionCreateJob *createJob = new CollectionCreateJob( collection, this ); QCOMPARE( createJob->exec(), creatable ); if ( !creatable ) return; Collection createdCol = createJob->collection(); QVERIFY( createdCol.isValid() ); QCOMPARE( createdCol.name(), collection.name() ); QCOMPARE( createdCol.parent(), collection.parent() ); QCOMPARE( createdCol.remoteId(), collection.remoteId() ); QCOMPARE( createdCol.cachePolicy(), collection.cachePolicy() ); CollectionFetchJob *listJob = new CollectionFetchJob( Collection( collection.parent() ), CollectionFetchJob::FirstLevel, this ); QVERIFY( listJob->exec() ); Collection listedCol = findCol( listJob->collections(), collection.name() ); QCOMPARE( listedCol, createdCol ); QCOMPARE( listedCol.remoteId(), collection.remoteId() ); QCOMPARE( listedCol.cachePolicy(), collection.cachePolicy() ); // fetch parent to compare inherited collection properties Collection parentCol = Collection::root(); if ( collection.parent() > 0 ) { CollectionFetchJob *listJob = new CollectionFetchJob( Collection( collection.parent() ), CollectionFetchJob::Base, this ); QVERIFY( listJob->exec() ); QCOMPARE( listJob->collections().count(), 1 ); parentCol = listJob->collections().first(); } if ( collection.contentMimeTypes().isEmpty() ) compareLists( listedCol.contentMimeTypes(), parentCol.contentMimeTypes() ); else compareLists( listedCol.contentMimeTypes(), collection.contentMimeTypes() ); if ( collection.resource().isEmpty() ) QCOMPARE( listedCol.resource(), parentCol.resource() ); else QCOMPARE( listedCol.resource(), collection.resource() ); CollectionDeleteJob *delJob = new CollectionDeleteJob( createdCol, this ); QVERIFY( delJob->exec() ); listJob = new CollectionFetchJob( Collection( collection.parent() ), CollectionFetchJob::FirstLevel, this ); QVERIFY( listJob->exec() ); QVERIFY( !findCol( listJob->collections(), collection.name() ).isValid() ); } void CollectionJobTest::testIllegalDeleteFolder() { // non-existing folder CollectionDeleteJob *del = new CollectionDeleteJob( Collection( INT_MAX ), this ); QVERIFY( !del->exec() ); // root del = new CollectionDeleteJob( Collection::root(), this ); QVERIFY( !del->exec() ); } void CollectionJobTest::testStatistics() { // empty folder CollectionStatisticsJob *statistics = new CollectionStatisticsJob( Collection( res1ColId ), this ); QVERIFY( statistics->exec() ); CollectionStatistics s = statistics->statistics(); QCOMPARE( s.count(), 0ll ); QCOMPARE( s.unreadCount(), 0ll ); // folder with attributes and content CollectionPathResolver *resolver = new CollectionPathResolver( "res1/foo", this );; QVERIFY( resolver->exec() ); statistics = new CollectionStatisticsJob( Collection( resolver->collection() ), this ); QVERIFY( statistics->exec() ); s = statistics->statistics(); QCOMPARE( s.count(), 15ll ); QCOMPARE( s.unreadCount(), 14ll ); } void CollectionJobTest::testModify() { QStringList reference; reference << "text/calendar" << "text/directory" << "message/rfc822" << "application/octet-stream" << "inode/directory"; Collection col; CollectionFetchJob *ljob = new CollectionFetchJob( Collection( res1ColId ), CollectionFetchJob::FirstLevel ); QVERIFY( ljob->exec() ); col = findCol( ljob->collections(), "foo" ); QVERIFY( col.isValid() ); // test noop modify CollectionModifyJob *mod = new CollectionModifyJob( col, this ); QVERIFY( mod->exec() ); ljob = new CollectionFetchJob( col, CollectionFetchJob::Base, this ); QVERIFY( ljob->exec() ); QCOMPARE( ljob->collections().count(), 1 ); col = ljob->collections().first(); compareLists( col.contentMimeTypes(), reference ); // test clearing content types col.setContentMimeTypes( QStringList() ); mod = new CollectionModifyJob( col, this ); QVERIFY( mod->exec() ); ljob = new CollectionFetchJob( col, CollectionFetchJob::Base, this ); QVERIFY( ljob->exec() ); QCOMPARE( ljob->collections().count(), 1 ); col = ljob->collections().first(); QVERIFY( col.contentMimeTypes().isEmpty() ); // test setting contnet types col.setContentMimeTypes( reference ); mod = new CollectionModifyJob( col, this ); QVERIFY( mod->exec() ); ljob = new CollectionFetchJob( col, CollectionFetchJob::Base, this ); QVERIFY( ljob->exec() ); QCOMPARE( ljob->collections().count(), 1 ); col = ljob->collections().first(); compareLists( col.contentMimeTypes(), reference ); // renaming col.setName( "foo (renamed)" ); mod = new CollectionModifyJob( col, this ); QVERIFY( mod->exec() ); ljob = new CollectionFetchJob( col, CollectionFetchJob::Base, this ); QVERIFY( ljob->exec() ); QCOMPARE( ljob->collections().count(), 1 ); col = ljob->collections().first(); QCOMPARE( col.name(), QString( "foo (renamed)" ) ); col.setName( "foo" ); mod = new CollectionModifyJob( col, this ); QVERIFY( mod->exec() ); } void CollectionJobTest::testMove() { Collection col( res1ColId ); col.setParent( res2ColId ); CollectionModifyJob *mod = new CollectionModifyJob( col, this ); QVERIFY( mod->exec() ); CollectionFetchJob *ljob = new CollectionFetchJob( Collection( res2ColId ), CollectionFetchJob::Recursive ); QVERIFY( ljob->exec() ); Collection::List list = ljob->collections(); QCOMPARE( list.count(), 7 ); QVERIFY( findCol( list, "res1" ).isValid() ); QVERIFY( findCol( list, "foo" ).isValid() ); QVERIFY( findCol( list, "bar" ).isValid() ); QVERIFY( findCol( list, "bla" ).isValid() ); ljob = new CollectionFetchJob( Collection( res1ColId ), CollectionFetchJob::Base ); QVERIFY( ljob->exec() ); list = ljob->collections(); QCOMPARE( list.count(), 1 ); col = list.first(); QCOMPARE( col.name(), QLatin1String("res1") ); QCOMPARE( col.parent(), res2ColId ); // cleanup col.setParent( Collection::root() ); mod = new CollectionModifyJob( col, this ); QVERIFY( mod->exec() ); } void CollectionJobTest::testIllegalModify() { // non-existing collection Collection col( INT_MAX ); col.setParent( res1ColId ); CollectionModifyJob *mod = new CollectionModifyJob( col, this ); QVERIFY( !mod->exec() ); // rename to already existing name col = Collection( res1ColId ); col.setName( "res2" ); mod = new CollectionModifyJob( col, this ); QVERIFY( !mod->exec() ); // move to non-existing target col = Collection( res1ColId ); col.setParent( INT_MAX ); mod = new CollectionModifyJob( col, this ); QVERIFY( !mod->exec() ); // moving root col = Collection::root(); col.setParent( res1ColId ); mod = new CollectionModifyJob( col, this ); QVERIFY( !mod->exec() ); } void CollectionJobTest::testUtf8CollectionName() { QString folderName = QString::fromUtf8( "รค" ); // create collection Collection col; col.setParent( res3ColId ); col.setName( folderName ); CollectionCreateJob *create = new CollectionCreateJob( col, this ); QVERIFY( create->exec() ); col = create->collection(); QVERIFY( col.isValid() ); // list parent CollectionFetchJob *list = new CollectionFetchJob( Collection( res3ColId ), CollectionFetchJob::Recursive, this ); QVERIFY( list->exec() ); QCOMPARE( list->collections().count(), 1 ); QCOMPARE( col, list->collections().first() ); QCOMPARE( col.name(), folderName ); // modify collection col.setContentMimeTypes( QStringList( "message/rfc822'" ) ); CollectionModifyJob *modify = new CollectionModifyJob( col, this ); QVERIFY( modify->exec() ); // collection statistics CollectionStatisticsJob *statistics = new CollectionStatisticsJob( col, this ); QVERIFY( statistics->exec() ); CollectionStatistics s = statistics->statistics(); QCOMPARE( s.count(), 0ll ); QCOMPARE( s.unreadCount(), 0ll ); // delete collection CollectionDeleteJob *del = new CollectionDeleteJob( col, this ); QVERIFY( del->exec() ); } void CollectionJobTest::testMultiList() { Collection::List req; req << Collection( res1ColId ) << Collection( res2ColId ); CollectionFetchJob* job = new CollectionFetchJob( req, this ); QVERIFY( job->exec() ); Collection::List res; res = job->collections(); compareLists( res, req ); } void CollectionJobTest::testSelect() { CollectionPathResolver *resolver = new CollectionPathResolver( "res1/foo", this );; QVERIFY( resolver->exec() ); Collection col( resolver->collection() ); CollectionSelectJob *job = new CollectionSelectJob( col, this ); QVERIFY( job->exec() ); QCOMPARE( job->unseen(), -1 ); job = new CollectionSelectJob( col, this ); job->setRetrieveStatus( true ); QVERIFY( job->exec() ); QVERIFY( job->unseen() > -1 ); job = new CollectionSelectJob( Collection::root(), this ); QVERIFY( job->exec() ); job = new CollectionSelectJob( Collection( INT_MAX ), this ); QVERIFY( !job->exec() ); } #include "collectionjobtest.moc" diff --git a/akonadi/tests/itemstoretest.cpp b/akonadi/tests/itemstoretest.cpp index bc9ebe0d9..2ce853a77 100644 --- a/akonadi/tests/itemstoretest.cpp +++ b/akonadi/tests/itemstoretest.cpp @@ -1,348 +1,343 @@ /* Copyright (c) 2006 Volker Krause Copyright (c) 2007 Robert Zwerus 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 "control.h" #include "itemstoretest.h" #include "testattribute.h" +#include +#include #include #include #include #include #include #include #include #include #include +#include "test_utils.h" using namespace Akonadi; QTEST_AKONADIMAIN( ItemStoreTest, NoGUI ) static Collection res1_foo; static Collection res2; static Collection res3; void ItemStoreTest::initTestCase() { Control::start(); AttributeFactory::registerAttribute(); // get the collections we run the tests on - CollectionFetchJob *job = new CollectionFetchJob( Collection::root(), CollectionFetchJob::Recursive ); - QVERIFY( job->exec() ); - Collection::List list = job->collections(); - Collection res1; - foreach ( const Collection &col, list ) { - if ( col.name() == "res1" ) - res1 = col; - if ( col.name() == "res2" ) - res2 = col; - if ( col.name() == "res3" ) - res3 = col; - } - foreach ( const Collection &col, list ) { - if ( col.name() == "foo" && col.parent() == res1.id() ) - res1_foo = col; - } + res1_foo = Collection( collectionIdFromPath( "res1/foo" ) ); + QVERIFY( res1_foo.isValid() ); + res2 = Collection( collectionIdFromPath( "res2" ) ); + QVERIFY( res2.isValid() ); + res3 = Collection( collectionIdFromPath( "res3" ) ); + QVERIFY( res3.isValid() ); + + // switch all resources offline to reduce interference from them + foreach ( Akonadi::AgentInstance agent, Akonadi::AgentManager::self()->instances() ) + agent.setIsOnline( false ); } void ItemStoreTest::testFlagChange() { ItemFetchJob *fjob = new ItemFetchJob( Item( 1 ) ); QVERIFY( fjob->exec() ); QCOMPARE( fjob->items().count(), 1 ); Item item = fjob->items()[0]; // add a flag Item::Flags origFlags = item.flags(); Item::Flags expectedFlags = origFlags; expectedFlags.insert( "added_test_flag_1" ); item.setFlag( "added_test_flag_1" ); ItemModifyJob *sjob = new ItemModifyJob( item, this ); QVERIFY( sjob->exec() ); fjob = new ItemFetchJob( Item( 1 ) ); QVERIFY( fjob->exec() ); QCOMPARE( fjob->items().count(), 1 ); item = fjob->items()[0]; QCOMPARE( item.flags().count(), expectedFlags.count() ); Item::Flags diff = expectedFlags - item.flags(); QVERIFY( diff.isEmpty() ); // set flags expectedFlags.insert( "added_test_flag_2" ); item.setFlags( expectedFlags ); sjob = new ItemModifyJob( item, this ); QVERIFY( sjob->exec() ); fjob = new ItemFetchJob( Item( 1 ) ); QVERIFY( fjob->exec() ); QCOMPARE( fjob->items().count(), 1 ); item = fjob->items()[0]; QCOMPARE( item.flags().count(), expectedFlags.count() ); diff = expectedFlags - item.flags(); QVERIFY( diff.isEmpty() ); // remove a flag item.clearFlag( "added_test_flag_1" ); item.clearFlag( "added_test_flag_2" ); sjob = new ItemModifyJob( item, this ); QVERIFY( sjob->exec() ); fjob = new ItemFetchJob( Item( 1 ) ); QVERIFY( fjob->exec() ); QCOMPARE( fjob->items().count(), 1 ); item = fjob->items()[0]; QCOMPARE( item.flags().count(), origFlags.count() ); diff = origFlags - item.flags(); QVERIFY( diff.isEmpty() ); } void ItemStoreTest::testDataChange_data() { QTest::addColumn( "data" ); QTest::newRow( "empty" ) << QByteArray(); QTest::newRow( "nullbyte" ) << QByteArray("\0" ); QTest::newRow( "nullbyte2" ) << QByteArray( "\0X" ); QTest::newRow( "linebreaks" ) << QByteArray( "line1\nline2\n\rline3\rline4\r\n" ); QTest::newRow( "linebreaks2" ) << QByteArray( "line1\r\nline2\r\n\r\n" ); QTest::newRow( "linebreaks3" ) << QByteArray( "line1\nline2" ); QTest::newRow( "simple" ) << QByteArray( "testbody" ); } void ItemStoreTest::testDataChange() { QFETCH( QByteArray, data ); Item item; ItemFetchJob *prefetchjob = new ItemFetchJob( Item( 1 ) ); prefetchjob->exec(); item = prefetchjob->items()[0]; item.setMimeType( "application/octet-stream" ); item.setPayload( data ); QCOMPARE( item.payload(), data ); // delete data ItemModifyJob *sjob = new ItemModifyJob( item ); - sjob->disableRevisionCheck(); // resource unsets the dirty flag in the meantime QVERIFY( sjob->exec() ); ItemFetchJob *fjob = new ItemFetchJob( Item( 1 ) ); fjob->fetchScope().fetchFullPayload(); QVERIFY( fjob->exec() ); QCOMPARE( fjob->items().count(), 1 ); item = fjob->items()[0]; QVERIFY( item.hasPayload() ); QEXPECT_FAIL( "empty", "Item does not detect QByteArray() as loaded payload part", Continue ); QCOMPARE( item.payload(), data ); } void ItemStoreTest::testRemoteId_data() { QTest::addColumn( "rid" ); QTest::addColumn( "exprid" ); QTest::newRow( "set" ) << QString( "A" ) << QString( "A" ); QTest::newRow( "no-change" ) << QString() << QString( "A" ); QTest::newRow( "clear" ) << QString( "" ) << QString( "" ); QTest::newRow( "reset" ) << QString( "A" ) << QString( "A" ); } void ItemStoreTest::testRemoteId() { QFETCH( QString, rid ); QFETCH( QString, exprid ); ItemFetchJob *prefetchjob = new ItemFetchJob( Item( 1 ) ); prefetchjob->exec(); Item item = prefetchjob->items()[0]; item.setId( 1 ); item.setRemoteId( rid ); ItemModifyJob *store = new ItemModifyJob( item, this ); - store->disableRevisionCheck(); // resource unsets the dirty flag in the meantime QVERIFY( store->exec() ); ItemFetchJob *fetch = new ItemFetchJob( item, this ); QVERIFY( fetch->exec() ); QCOMPARE( fetch->items().count(), 1 ); item = fetch->items().at( 0 ); QCOMPARE( item.remoteId(), exprid ); } void ItemStoreTest::testMultiPart() { ItemFetchJob *prefetchjob = new ItemFetchJob( Item( 1 ) ); QVERIFY( prefetchjob->exec() ); QCOMPARE( prefetchjob->items().count(), 1 ); Item item = prefetchjob->items()[0]; item.setMimeType( "application/octet-stream" ); item.setPayload( "testmailbody" ); item.attribute( Item::AddIfMissing )->data = "extra"; // store item ItemModifyJob *sjob = new ItemModifyJob( item ); QVERIFY( sjob->exec() ); ItemFetchJob *fjob = new ItemFetchJob( Item( 1 ) ); fjob->fetchScope().fetchAttribute(); fjob->fetchScope().fetchFullPayload(); QVERIFY( fjob->exec() ); QCOMPARE( fjob->items().count(), 1 ); item = fjob->items()[0]; QVERIFY( item.hasPayload() ); QCOMPARE( item.payload(), QByteArray("testmailbody") ); QVERIFY( item.hasAttribute() ); QCOMPARE( item.attribute()->data, QByteArray("extra") ); // clean up item.removeAttribute( "EXTRA" ); sjob = new ItemModifyJob( item ); QVERIFY( sjob->exec() ); } void ItemStoreTest::testPartRemove() { ItemFetchJob *prefetchjob = new ItemFetchJob( Item( 2 ) ); prefetchjob->exec(); Item item = prefetchjob->items()[0]; item.setMimeType( "application/octet-stream" ); item.attribute( Item::AddIfMissing )->data = "extra"; // store item ItemModifyJob *sjob = new ItemModifyJob( item ); QVERIFY( sjob->exec() ); // fetch item and its parts (should be RFC822, HEAD and EXTRA) ItemFetchJob *fjob = new ItemFetchJob( Item( 2 ) ); fjob->fetchScope().fetchFullPayload(); fjob->fetchScope().fetchAllAttributes(); QVERIFY( fjob->exec() ); QCOMPARE( fjob->items().count(), 1 ); item = fjob->items()[0]; QCOMPARE( item.attributes().count(), 2 ); QVERIFY( item.hasAttribute() ); // remove a part item.removeAttribute(); sjob = new ItemModifyJob( item ); QVERIFY( sjob->exec() ); // fetch item again (should only have RFC822 and HEAD left) ItemFetchJob *fjob2 = new ItemFetchJob( Item( 2 ) ); fjob2->fetchScope().fetchFullPayload(); fjob2->fetchScope().fetchAllAttributes(); QVERIFY( fjob2->exec() ); QCOMPARE( fjob2->items().count(), 1 ); item = fjob2->items()[0]; QCOMPARE( item.attributes().count(), 1 ); QVERIFY( !item.hasAttribute() ); } void ItemStoreTest::testRevisionCheck() { // make sure we don't have any other collection selected // otherwise EXPUNGE doesn't work and will be triggered by // the following tests and mess up the monitor testing CollectionSelectJob *sel = new CollectionSelectJob( Collection::root(), this ); QVERIFY( sel->exec() ); // fetch same item twice Item ref( 2 ); ItemFetchJob *prefetchjob = new ItemFetchJob( ref ); QVERIFY( prefetchjob->exec() ); QCOMPARE( prefetchjob->items().count(), 1 ); Item item1 = prefetchjob->items()[0]; Item item2 = prefetchjob->items()[0]; // store first item unmodified ItemModifyJob *sjob = new ItemModifyJob( item1 ); QVERIFY( sjob->exec() ); // try to store second item ItemModifyJob *sjob2 = new ItemModifyJob( item2 ); item2.attribute( Item::AddIfMissing )->data = "extra"; QVERIFY( !sjob2->exec() ); // fetch same again prefetchjob = new ItemFetchJob( ref ); prefetchjob->exec(); item1 = prefetchjob->items()[0]; // delete item ItemDeleteJob *djob = new ItemDeleteJob( ref, this ); djob->exec(); // try to store it sjob = new ItemModifyJob( item1 ); QVERIFY( !sjob->exec() ); } void ItemStoreTest::testModificationTime() { Item item; item.setMimeType( "text/directory" ); QVERIFY( item.modificationTime().isNull() ); ItemCreateJob *job = new ItemCreateJob( item, res1_foo ); QVERIFY( job->exec() ); // The item should have a datetime set now. item = job->item(); QVERIFY( !item.modificationTime().isNull() ); QDateTime initialDateTime = item.modificationTime(); // Fetch the same item again. Item item2( item.id() ); ItemFetchJob *fjob = new ItemFetchJob( item2, this ); QVERIFY( fjob->exec() ); item2 = fjob->items().first(); QCOMPARE( initialDateTime, item2.modificationTime() ); // Lets wait 5 secs. QTest::qWait( 5000 ); // Modify the item item.attribute( Item::AddIfMissing )->data = "extra"; ItemModifyJob *mjob = new ItemModifyJob( item ); QVERIFY( mjob->exec() ); // The item should still have a datetime set and that date should be somewhere // after the initialDateTime. item = mjob->item(); QVERIFY( !item.modificationTime().isNull() ); QVERIFY( initialDateTime < item.modificationTime() ); // Fetch the item after modification. Item item3( item.id() ); ItemFetchJob *fjob2 = new ItemFetchJob( item3, this ); QVERIFY( fjob2->exec() ); // item3 should have the same modification time as item. item3 = fjob2->items().first(); QCOMPARE( item3.modificationTime(), item.modificationTime() ); // Clean up ItemDeleteJob *idjob = new ItemDeleteJob( item, this ); QVERIFY( idjob->exec() ); } #include "itemstoretest.moc" diff --git a/akonadi/tests/itemsynctest.cpp b/akonadi/tests/itemsynctest.cpp index 491522a1b..10bf61c21 100644 --- a/akonadi/tests/itemsynctest.cpp +++ b/akonadi/tests/itemsynctest.cpp @@ -1,167 +1,173 @@ /* Copyright (c) 2008 Volker Krause 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 "test_utils.h" +#include +#include #include #include #include #include #include #include #include #include #include using namespace Akonadi; Q_DECLARE_METATYPE( KJob* ) class ItemsyncTest : public QObject { Q_OBJECT private: Item::List fetchItems( const Collection &col ) { ItemFetchJob *fetch = new ItemFetchJob( col, this ); fetch->fetchScope().fetchFullPayload(); fetch->fetchScope().fetchAllAttributes(); Q_ASSERT( fetch->exec() ); Q_ASSERT( !fetch->items().isEmpty() ); return fetch->items(); } private slots: void initTestCase() { Control::start(); qRegisterMetaType(); + + // switch all resources offline to reduce interference from them + foreach ( Akonadi::AgentInstance agent, Akonadi::AgentManager::self()->instances() ) + agent.setIsOnline( false ); } void testFullSync() { const Collection col = Collection( collectionIdFromPath( "res1/foo" ) ); QVERIFY( col.isValid() ); Item::List origItems = fetchItems( col ); ItemSync* syncer = new ItemSync( col ); syncer->setFullSyncItems( origItems ); QVERIFY( syncer->exec() ); Item::List resultItems = fetchItems( col ); QCOMPARE( resultItems.count(), origItems.count() ); } void testFullStreamingSync() { const Collection col = Collection( collectionIdFromPath( "res1/foo" ) ); QVERIFY( col.isValid() ); Item::List origItems = fetchItems( col ); ItemSync* syncer = new ItemSync( col ); QSignalSpy spy( syncer, SIGNAL(result(KJob*)) ); QVERIFY( spy.isValid() ); syncer->setTotalItems( origItems.count() ); QTest::qWait( 10 ); QCOMPARE( spy.count(), 0 ); for ( int i = 0; i < origItems.count(); ++i ) { Item::List l; l << origItems[i]; syncer->setFullSyncItems( l ); if ( i < origItems.count() - 1 ) QTest::qWait( 10 ); // enter the event loop so itemsync actually can do something QCOMPARE( spy.count(), 0 ); } QTest::qWait( 1000 ); // let it finish its job QCOMPARE( spy.count(), 1 ); KJob *job = spy.at( 0 ).at( 0 ).value(); QVERIFY( job ); QCOMPARE( job->error(), 0 ); Item::List resultItems = fetchItems( col ); QCOMPARE( resultItems.count(), origItems.count() ); } void testIncrementalSync() { const Collection col = Collection( collectionIdFromPath( "res1/foo" ) ); QVERIFY( col.isValid() ); Item::List origItems = fetchItems( col ); ItemSync* syncer = new ItemSync( col ); syncer->setIncrementalSyncItems( origItems, Item::List() ); QVERIFY( syncer->exec() ); Item::List resultItems = fetchItems( col ); QCOMPARE( resultItems.count(), origItems.count() ); } void testIncrementalStreamingSync() { const Collection col = Collection( collectionIdFromPath( "res1/foo" ) ); QVERIFY( col.isValid() ); Item::List origItems = fetchItems( col ); ItemSync* syncer = new ItemSync( col ); QSignalSpy spy( syncer, SIGNAL(result(KJob*)) ); QVERIFY( spy.isValid() ); syncer->setStreamingEnabled( true ); QTest::qWait( 10 ); QCOMPARE( spy.count(), 0 ); for ( int i = 0; i < origItems.count(); ++i ) { Item::List l; l << origItems[i]; syncer->setIncrementalSyncItems( l, Item::List() ); if ( i < origItems.count() - 1 ) QTest::qWait( 10 ); // enter the event loop so itemsync actually can do something QCOMPARE( spy.count(), 0 ); } syncer->deliveryDone(); QTest::qWait( 1000 ); // let it finish its job QCOMPARE( spy.count(), 1 ); KJob *job = spy.at( 0 ).at( 0 ).value(); QVERIFY( job ); QCOMPARE( job->error(), 0 ); Item::List resultItems = fetchItems( col ); QCOMPARE( resultItems.count(), origItems.count() ); } void testEmptyIncrementalSync() { const Collection col = Collection( collectionIdFromPath( "res1/foo" ) ); QVERIFY( col.isValid() ); Item::List origItems = fetchItems( col ); ItemSync* syncer = new ItemSync( col ); syncer->setIncrementalSyncItems( Item::List(), Item::List() ); QVERIFY( syncer->exec() ); Item::List resultItems = fetchItems( col ); QCOMPARE( resultItems.count(), origItems.count() ); } }; QTEST_AKONADIMAIN( ItemsyncTest, NoGUI ) #include "itemsynctest.moc" diff --git a/akonadi/tests/monitortest.cpp b/akonadi/tests/monitortest.cpp index 81ce04a60..1115e8fdb 100644 --- a/akonadi/tests/monitortest.cpp +++ b/akonadi/tests/monitortest.cpp @@ -1,231 +1,236 @@ /* Copyright (c) 2006 Volker Krause 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 "monitortest.h" #include "test_utils.h" +#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Akonadi; QTEST_AKONADIMAIN( MonitorTest, NoGUI ) static Collection res3; Q_DECLARE_METATYPE(Akonadi::Collection::Id) void MonitorTest::initTestCase() { Control::start(); res3 = Collection( collectionIdFromPath( "res3" ) ); + + // switch all resources offline to reduce interference from them + foreach ( Akonadi::AgentInstance agent, Akonadi::AgentManager::self()->instances() ) + agent.setIsOnline( false ); } void MonitorTest::testMonitor_data() { QTest::addColumn( "fetchCol" ); QTest::newRow( "with collection fetching" ) << true; QTest::newRow( "without collection fetching" ) << false; } void MonitorTest::testMonitor() { QFETCH( bool, fetchCol ); Monitor *monitor = new Monitor( this ); monitor->setCollectionMonitored( Collection::root() ); monitor->fetchCollection( fetchCol ); monitor->itemFetchScope().fetchFullPayload(); // monitor signals qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); QSignalSpy caspy( monitor, SIGNAL(collectionAdded(Akonadi::Collection,Akonadi::Collection)) ); QSignalSpy cmspy( monitor, SIGNAL(collectionChanged(const Akonadi::Collection&)) ); QSignalSpy crspy( monitor, SIGNAL(collectionRemoved(const Akonadi::Collection&)) ); QSignalSpy csspy( monitor, SIGNAL(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)) ); QSignalSpy iaspy( monitor, SIGNAL(itemAdded(const Akonadi::Item&, const Akonadi::Collection&)) ); QSignalSpy imspy( monitor, SIGNAL(itemChanged(const Akonadi::Item&, const QSet&)) ); QSignalSpy irspy( monitor, SIGNAL(itemRemoved(const Akonadi::Item&)) ); QVERIFY( caspy.isValid() ); QVERIFY( cmspy.isValid() ); QVERIFY( crspy.isValid() ); QVERIFY( csspy.isValid() ); QVERIFY( iaspy.isValid() ); QVERIFY( imspy.isValid() ); QVERIFY( irspy.isValid() ); // create a collection Collection monitorCol; monitorCol.setParent( res3 ); monitorCol.setName( "monitor" ); CollectionCreateJob *create = new CollectionCreateJob( monitorCol, this ); QVERIFY( create->exec() ); monitorCol = create->collection(); QVERIFY( monitorCol.isValid() ); QTest::qWait(1000); // make sure the DBus signal has been processed QCOMPARE( caspy.count(), 1 ); QList arg = caspy.takeFirst(); Collection col = arg.at(0).value(); QCOMPARE( col, monitorCol ); if ( fetchCol ) QCOMPARE( col.name(), QString("monitor") ); Collection parent = arg.at(1).value(); QCOMPARE( parent, res3 ); QVERIFY( cmspy.isEmpty() ); QVERIFY( crspy.isEmpty() ); QVERIFY( csspy.isEmpty() ); QVERIFY( iaspy.isEmpty() ); QVERIFY( imspy.isEmpty() ); QVERIFY( irspy.isEmpty() ); // add an item Item newItem; newItem.setMimeType( "application/octet-stream" ); ItemCreateJob *append = new ItemCreateJob( newItem, monitorCol, this ); QVERIFY( append->exec() ); Item monitorRef = append->item(); QVERIFY( monitorRef.isValid() ); QTest::qWait(1000); QCOMPARE( csspy.count(), 1 ); arg = csspy.takeFirst(); QEXPECT_FAIL( "", "Don't know how to handle 'Akonadi::Collection::Id', use qRegisterMetaType to register it. <-- I did this, but it still doesn't work!", Continue ); QCOMPARE( arg.at(0).value(), monitorCol.id() ); QCOMPARE( iaspy.count(), 1 ); arg = iaspy.takeFirst(); Item item = arg.at( 0 ).value(); QCOMPARE( item, monitorRef ); QCOMPARE( item.mimeType(), QString::fromLatin1( "application/octet-stream" ) ); Collection collection = arg.at( 1 ).value(); QCOMPARE( collection.id(), monitorCol.id() ); QVERIFY( caspy.isEmpty() ); QVERIFY( cmspy.isEmpty() ); QVERIFY( crspy.isEmpty() ); - imspy.clear(); // can happen if the resource set the remoteId inbetween + QVERIFY( imspy.isEmpty() ); QVERIFY( irspy.isEmpty() ); // modify an item item.setPayload( "some new content" ); ItemModifyJob *store = new ItemModifyJob( item, this ); - store->disableRevisionCheck(); // resource might have set the remote id in the meantime QVERIFY( store->exec() ); QTest::qWait(1000); QCOMPARE( csspy.count(), 1 ); arg = csspy.takeFirst(); QEXPECT_FAIL( "", "Don't know how to handle 'Akonadi::Collection::Id', use qRegisterMetaType to register it. <-- I did this, but it still doesn't work!", Continue ); QCOMPARE( arg.at(0).value(), monitorCol.id() ); QCOMPARE( imspy.count(), 1 ); arg = imspy.takeFirst(); item = arg.at( 0 ).value(); QCOMPARE( monitorRef, item ); QCOMPARE( item.payload(), QByteArray( "some new content" ) ); QVERIFY( caspy.isEmpty() ); QVERIFY( cmspy.isEmpty() ); QVERIFY( crspy.isEmpty() ); QVERIFY( iaspy.isEmpty() ); QVERIFY( irspy.isEmpty() ); // delete an item ItemDeleteJob *del = new ItemDeleteJob( monitorRef, this ); QVERIFY( del->exec() ); QTest::qWait(1000); QCOMPARE( csspy.count(), 1 ); arg = csspy.takeFirst(); QEXPECT_FAIL( "", "Don't know how to handle 'Akonadi::Collection::Id', use qRegisterMetaType to register it. <-- I did this, but it still doesn't work!", Continue ); QCOMPARE( arg.at(0).value(), monitorCol.id() ); cmspy.clear(); QCOMPARE( irspy.count(), 1 ); arg = irspy.takeFirst(); Item ref = qvariant_cast( arg.at(0) ); QCOMPARE( monitorRef, ref ); QVERIFY( caspy.isEmpty() ); QVERIFY( cmspy.isEmpty() ); QVERIFY( crspy.isEmpty() ); QVERIFY( iaspy.isEmpty() ); QVERIFY( imspy.isEmpty() ); imspy.clear(); // modify a collection monitorCol.setName( "changed name" ); CollectionModifyJob *mod = new CollectionModifyJob( monitorCol, this ); QVERIFY( mod->exec() ); QTest::qWait(1000); QCOMPARE( cmspy.count(), 1 ); arg = cmspy.takeFirst(); col = arg.at(0).value(); QCOMPARE( col, monitorCol ); if ( fetchCol ) QCOMPARE( col.name(), QString("changed name") ); QVERIFY( caspy.isEmpty() ); QVERIFY( crspy.isEmpty() ); QVERIFY( csspy.isEmpty() ); QVERIFY( iaspy.isEmpty() ); QVERIFY( imspy.isEmpty() ); QVERIFY( irspy.isEmpty() ); // delete a collection CollectionDeleteJob *cdel = new CollectionDeleteJob( monitorCol, this ); QVERIFY( cdel->exec() ); QTest::qWait(1000); QCOMPARE( crspy.count(), 1 ); arg = crspy.takeFirst(); QCOMPARE( arg.at(0).value().id(), monitorCol.id() ); QVERIFY( caspy.isEmpty() ); QVERIFY( cmspy.isEmpty() ); QVERIFY( csspy.isEmpty() ); QVERIFY( iaspy.isEmpty() ); QVERIFY( imspy.isEmpty() ); QVERIFY( irspy.isEmpty() ); } #include "monitortest.moc" diff --git a/akonadi/tests/test_utils.h b/akonadi/tests/test_utils.h index becdc9b72..342606be4 100644 --- a/akonadi/tests/test_utils.h +++ b/akonadi/tests/test_utils.h @@ -1,36 +1,38 @@ /* Copyright (c) 2009 Volker Krause 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. */ #ifndef AKONADI_TEST_UTIL_H #define AKONADI_TEST_UTIL_H #include "collectionpathresolver_p.h" #include "qtest_akonadi.h" qint64 collectionIdFromPath( const QString &path ) { Akonadi::CollectionPathResolver *resolver = new Akonadi::CollectionPathResolver( path ); bool success = resolver->exec(); - if ( !success ) + if ( !success ) { qDebug() << "path resolution for " << path << " failed: " << resolver->errorText(); + return -1; + } qint64 id = resolver->collection(); return id; } #endif