diff --git a/src/akonadi/akonadinoterepository.cpp b/src/akonadi/akonadinoterepository.cpp --- a/src/akonadi/akonadinoterepository.cpp +++ b/src/akonadi/akonadinoterepository.cpp @@ -89,16 +89,21 @@ Q_ASSERT(fetchCollectionJob->collections().size() > 0); const Akonadi::Collection::List collections = fetchCollectionJob->collections(); - Akonadi::Collection col = *std::find_if(collections.constBegin(), collections.constEnd(), - [] (const Akonadi::Collection &c) { + auto it = std::find_if(collections.constBegin(), collections.constEnd(), + [] (const Akonadi::Collection &c) { return (c.rights() & Akonadi::Collection::CanCreateItem) && (c.rights() & Akonadi::Collection::CanChangeItem) && (c.rights() & Akonadi::Collection::CanDeleteItem); }); - Q_ASSERT(col.isValid()); - auto createJob = m_storage->createItem(item, col); - job->addSubjob(createJob); - createJob->start(); + if (it == collections.constEnd()) { + job->emitError(tr("Could not find a collection to store the note into!")); + } else { + auto col = *it; + Q_ASSERT(col.isValid()); + auto createJob = m_storage->createItem(item, col); + job->addSubjob(createJob); + createJob->start(); + } }); return job; } diff --git a/src/akonadi/akonaditaskrepository.cpp b/src/akonadi/akonaditaskrepository.cpp --- a/src/akonadi/akonaditaskrepository.cpp +++ b/src/akonadi/akonaditaskrepository.cpp @@ -59,16 +59,21 @@ Q_ASSERT(fetchCollectionJob->collections().size() > 0); const Akonadi::Collection::List collections = fetchCollectionJob->collections(); - Akonadi::Collection col = *std::find_if(collections.constBegin(), collections.constEnd(), - [] (const Akonadi::Collection &c) { + auto it = std::find_if(collections.constBegin(), collections.constEnd(), + [] (const Akonadi::Collection &c) { return (c.rights() & Akonadi::Collection::CanCreateItem) && (c.rights() & Akonadi::Collection::CanChangeItem) && (c.rights() & Akonadi::Collection::CanDeleteItem); }); - Q_ASSERT(col.isValid()); - auto createJob = m_storage->createItem(item, col); - job->addSubjob(createJob); - createJob->start(); + if (it == collections.constEnd()) { + job->emitError(tr("Could not find a collection to store the task into!")); + } else { + auto col = *it; + Q_ASSERT(col.isValid()); + auto createJob = m_storage->createItem(item, col); + job->addSubjob(createJob); + createJob->start(); + } }); return job; } diff --git a/tests/units/akonadi/akonadinoterepositorytest.cpp b/tests/units/akonadi/akonadinoterepositorytest.cpp --- a/tests/units/akonadi/akonadinoterepositorytest.cpp +++ b/tests/units/akonadi/akonadinoterepositorytest.cpp @@ -126,6 +126,49 @@ QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(item, col3).exactly(1)); } + void shouldEmitErrorIfNoFallbackCollectionIsFound() + { + // GIVEN + + // A few collections + auto col1 = Akonadi::Collection(42); + col1.setRights(Akonadi::Collection::ReadOnly); + auto col2 = Akonadi::Collection(43); + col2.setRights(Akonadi::Collection::ReadOnly); + auto col3 = Akonadi::Collection(44); + col3.setRights(Akonadi::Collection::ReadOnly); + auto collectionFetchJob = new Testlib::AkonadiFakeCollectionFetchJob; + collectionFetchJob->setCollections(Akonadi::Collection::List() << col1 << col2 << col3); + + // A task and its corresponding item not existing in storage yet + Akonadi::Item item; + Domain::Note::Ptr note(new Domain::Note); + + // Storage mock returning the create job and with no default collection + Utils::MockObject storageMock; + storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().thenReturn(Akonadi::Collection()); + storageMock(&Akonadi::StorageInterface::fetchCollections).when(Akonadi::Collection::root(), + Akonadi::StorageInterface::Recursive, + Akonadi::StorageInterface::Notes) + .thenReturn(collectionFetchJob); + + // Serializer mock returning the item for the task + Utils::MockObject serializerMock; + serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).thenReturn(item); + + // WHEN + QScopedPointer repository(new Akonadi::NoteRepository(storageMock.getInstance(), + serializerMock.getInstance())); + auto job = repository->create(note); + job->exec(); + + // THEN + QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromNote).when(note).exactly(1)); + QVERIFY(storageMock(&Akonadi::StorageInterface::defaultNoteCollection).when().exactly(1)); + QVERIFY(job->error()); + QVERIFY(!job->errorText().isEmpty()); + } + void shouldCreateNewItemsInTag() { // GIVEN diff --git a/tests/units/akonadi/akonaditaskrepositorytest.cpp b/tests/units/akonadi/akonaditaskrepositorytest.cpp --- a/tests/units/akonadi/akonaditaskrepositorytest.cpp +++ b/tests/units/akonadi/akonaditaskrepositorytest.cpp @@ -137,6 +137,50 @@ QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(item, col3).exactly(1)); } + void shouldEmitErrorIfNoFallbackCollectionIsFound() + { + // GIVEN + + // A few collections + auto col1 = Akonadi::Collection(42); + col1.setRights(Akonadi::Collection::ReadOnly); + auto col2 = Akonadi::Collection(43); + col2.setRights(Akonadi::Collection::ReadOnly); + auto col3 = Akonadi::Collection(44); + col3.setRights(Akonadi::Collection::ReadOnly); + auto collectionFetchJob = new Testlib::AkonadiFakeCollectionFetchJob; + collectionFetchJob->setCollections(Akonadi::Collection::List() << col1 << col2 << col3); + + // A task and its corresponding item not existing in storage yet + Akonadi::Item item; + Domain::Task::Ptr task(new Domain::Task); + + // Storage mock returning the create job and with no default collection + Utils::MockObject storageMock; + storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().thenReturn(Akonadi::Collection()); + storageMock(&Akonadi::StorageInterface::fetchCollections).when(Akonadi::Collection::root(), + Akonadi::StorageInterface::Recursive, + Akonadi::StorageInterface::Tasks) + .thenReturn(collectionFetchJob); + + // Serializer mock returning the item for the task + Utils::MockObject serializerMock; + serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).thenReturn(item); + + // WHEN + QScopedPointer repository(new Akonadi::TaskRepository(storageMock.getInstance(), + serializerMock.getInstance(), + Akonadi::MessagingInterface::Ptr())); + auto job = repository->create(task); + job->exec(); + + // THEN + QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1)); + QVERIFY(storageMock(&Akonadi::StorageInterface::defaultTaskCollection).when().exactly(1)); + QVERIFY(job->error()); + QVERIFY(!job->errorText().isEmpty()); + } + void shouldCreateNewChildrenInParentCollection() { // GIVEN