diff --git a/CMakeLists.txt b/CMakeLists.txt index aa7f3f3..279be17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,87 +1,94 @@ cmake_minimum_required(VERSION 2.8.12) project(Akonadi-Calendar) # ECM setup set(KF5_VERSION "5.28.0") find_package(ECM ${KF5_VERSION} CONFIG REQUIRED) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) include(GenerateExportHeader) include(ECMGenerateHeaders) include(ECMGeneratePriFile) include(ECMPackageConfigHelpers) include(ECMSetupVersion) include(FeatureSummary) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMQtDeclareLoggingCategory) set(PIM_VERSION "5.4.3") set(AKONADICALENDAR_LIB_VERSION ${PIM_VERSION}) set(CALENDARCORE_LIB_VERSION "5.4.3") set(AKONADICONTACT_LIB_VERSION "5.4.3") set(AKONADI_LIB_VERSION "5.4.3") set(MAILTRANSPORT_LIB_VERSION "5.4.3") set(KCONTACTS_LIB_VERSION "5.4.3") set(CALENDARUTILS_LIB_VERSION "5.4.3") set(IDENTITYMANAGEMENT_LIB_VERSION "5.4.3") ecm_setup_version(${AKONADICALENDAR_LIB_VERSION} VARIABLE_PREFIX AKONADICALENDAR VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/akonadi-calendar_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5AkonadiCalendarConfigVersion.cmake" SOVERSION 5 ) configure_file(akonadi-calendar-version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/src/akonadi-calendar-version.h @ONLY) ########### Find packages ########### find_package(KF5KIO ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Wallet ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5Codecs ${KF5_VERSION} CONFIG REQUIRED) find_package(KF5MailTransport ${MAILTRANSPORT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Contacts ${KCONTACTS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5IdentityManagement ${IDENTITYMANAGEMENT_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarCore ${CALENDARCORE_LIB_VERSION} CONFIG REQUIRED) find_package(KF5CalendarUtils ${CALENDARUTILS_LIB_VERSION} CONFIG REQUIRED) find_package(KF5Akonadi ${AKONADI_LIB_VERSION} CONFIG REQUIRED) find_package(KF5AkonadiContact ${AKONADICONTACT_LIB_VERSION} CONFIG REQUIRED) ########### Targets ########### add_definitions(-DTRANSLATION_DOMAIN=\"libakonadi-calendar5\") add_definitions("-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII") + +# TODO: switch to more standard approach for export-class-if-building-autotests once the tests pass +set( PLEASE_TEST_INVITATIONS FALSE) +if ( PLEASE_TEST_INVITATIONS ) + add_definitions( -DPLEASE_TEST_INVITATIONS ) +endif() + add_subdirectory(src) if (BUILD_TESTING) add_subdirectory(autotests) endif () ########### CMake Config Files ########### set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5AkonadiCalendar") ecm_configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5AkonadiCalendarConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5AkonadiCalendarConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5AkonadiCalendarConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5AkonadiCalendarConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT KF5AkonadiCalendarTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5AkonadiCalendarTargets.cmake NAMESPACE KF5::) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/akonadi-calendar_version.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel ) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 54d2860..e8e018a 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -1,31 +1,32 @@ include(ECMMarkAsTest) set(QT_REQUIRED_VERSION "5.6.0") find_package(Qt5Test ${QT_REQUIRED_VERSION} CONFIG REQUIRED) set( KDEPIMLIBS_RUN_ISOLATED_TESTS TRUE ) set( PREVIOUS_EXEC_OUTPUT_PATH ../../tests ) set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) add_definitions(-DITIP_DATA_DIR="\\"${CMAKE_CURRENT_SOURCE_DIR}/itip_data\\"" ) set(common_sources unittestbase.cpp helper.cpp ${Akonadi-Calendar_BINARY_DIR}/src/akonadicalendar_debug.cpp ${Akonadi-Calendar_SOURCE_DIR}/src/utils_p.cpp) +set(common_libs "KF5::AkonadiCalendar;KF5::CalendarCore;KF5::Mime;KF5::IdentityManagement;KF5::AkonadiWidgets") # the tests need the ical resource, which we might not have at this point (e.g. on the CI) find_program(AKONADI_ICAL_RESOURCE NAMES akonadi_ical_resource) if (AKONADI_ICAL_RESOURCE) -add_akonadi_isolated_test_advanced( historytest.cpp "${common_sources}" "KF5::AkonadiCalendar;KF5::CalendarCore;KF5::Mime;KF5::IdentityManagement;KF5::AkonadiWidgets") +add_akonadi_isolated_test_advanced( historytest.cpp "${common_sources}" "${common_libs}") add_akonadi_isolated_test_advanced( incidencechangertest.cpp "" "KF5::AkonadiCalendar" ) add_akonadi_isolated_test_advanced( calendarbasetest.cpp "" "KF5::AkonadiCalendar" ) add_akonadi_isolated_test_advanced( fetchjobcalendartest.cpp "" "KF5::AkonadiCalendar" ) add_akonadi_isolated_test_advanced( etmcalendartest.cpp "" "KF5::AkonadiCalendar" ) if ( PLEASE_TEST_INVITATIONS ) - add_akonadi_isolated_test_advanced( itiphandlertest.cpp "${common_sources}" "") - add_akonadi_isolated_test_advanced( mailclienttest.cpp "" "KF5::AkonadiCalendar") + add_akonadi_isolated_test_advanced( itiphandlertest.cpp "${common_sources}" "${common_libs};KF5::MailTransport") + add_akonadi_isolated_test_advanced( mailclienttest.cpp "" "KF5::AkonadiCalendar;KF5::Mime;KF5::MailTransport;KF5::IdentityManagement") endif() endif() diff --git a/autotests/itiphandlertest.cpp b/autotests/itiphandlertest.cpp index 799ff23..f67afc9 100644 --- a/autotests/itiphandlertest.cpp +++ b/autotests/itiphandlertest.cpp @@ -1,738 +1,738 @@ /* Copyright (c) 2013 Sérgio Martins 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 "itiphandlertest.h" #include "helper.h" -#include "../mailclient_p.h" -#include "../fetchjobcalendar.h" -#include "../utils_p.h" +#include "mailclient_p.h" +#include "fetchjobcalendar.h" +#include "utils_p.h" #include #include #include #include #include #include #include #include #include #include using namespace Akonadi; using namespace KCalCore; Q_DECLARE_METATYPE(Akonadi::IncidenceChanger::InvitationPolicy) Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(Akonadi::ITIPHandler::Result) Q_DECLARE_METATYPE(KCalCore::Attendee::PartStat) Q_DECLARE_METATYPE(QList) static const char *s_ourEmail = "unittests@dev.nul"; // change also in kdepimlibs/akonadi/calendar/tests/unittestenv/kdehome/share/config static const char *s_outEmail2 = "identity2@kde.org"; class FakeMessageQueueJob : public MailTransport::MessageQueueJob { public: explicit FakeMessageQueueJob(QObject *parent = Q_NULLPTR) : MailTransport::MessageQueueJob(parent) { } virtual void start() { UnitTestResult unitTestResult; unitTestResult.message = message(); unitTestResult.from = addressAttribute().from(); unitTestResult.to = addressAttribute().to(); unitTestResult.cc = addressAttribute().cc(); unitTestResult.bcc = addressAttribute().bcc(); unitTestResult.transportId = transportAttribute().transportId(); FakeMessageQueueJob::sUnitTestResults << unitTestResult; setError(Akonadi::MailClient::ResultSuccess); setErrorText(QString()); emitResult(); } static UnitTestResult::List sUnitTestResults; }; UnitTestResult::List FakeMessageQueueJob::sUnitTestResults; class FakeITIPHandlerComponentFactory : public ITIPHandlerComponentFactory { public: FakeITIPHandlerComponentFactory(QObject *parent = Q_NULLPTR) : ITIPHandlerComponentFactory(parent) { } virtual MailTransport::MessageQueueJob *createMessageQueueJob(const KCalCore::IncidenceBase::Ptr &incidence, const KIdentityManagement::Identity &identity, QObject *parent = 0) { Q_UNUSED(incidence); Q_UNUSED(identity); return new FakeMessageQueueJob(parent); } }; void ITIPHandlerTest::initTestCase() { AkonadiTest::checkTestIsIsolated(); m_pendingItipMessageSignal = 0; m_pendingIncidenceChangerSignal = 0; m_itipHandler = 0; m_cancelExpected = false; m_changer = new IncidenceChanger(new FakeITIPHandlerComponentFactory(this), this); m_changer->setHistoryEnabled(false); m_changer->setGroupwareCommunication(true); m_changer->setInvitationPolicy(IncidenceChanger::InvitationPolicySend); // don't show dialogs connect(m_changer, SIGNAL(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)), SLOT(onCreateFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString))); connect(m_changer, SIGNAL(deleteFinished(int,QVector,Akonadi::IncidenceChanger::ResultCode,QString)), SLOT(onDeleteFinished(int,QVector,Akonadi::IncidenceChanger::ResultCode,QString))); connect(m_changer, SIGNAL(modifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)), SLOT(onModifyFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString))); } void ITIPHandlerTest::testProcessITIPMessage_data() { QTest::addColumn("data_filename"); QTest::addColumn("action"); QTest::addColumn("receiver"); QTest::addColumn("incidenceUid"); // uid of incidence in invitation QTest::addColumn("expectedResult"); QTest::addColumn("expectedNumIncidences"); QTest::addColumn("expectedPartStat"); QString data_filename; QString action = QStringLiteral("accepted"); QString incidenceUid = QStringLiteral("uosj936i6arrtl9c2i5r2mfuvg"); QString receiver = QLatin1String(s_ourEmail); Akonadi::ITIPHandler::Result expectedResult; int expectedNumIncidences = 0; KCalCore::Attendee::PartStat expectedPartStat; //---------------------------------------------------------------------------------------------- // Someone invited us to an event, and we accept expectedResult = ITIPHandler::ResultSuccess; data_filename = QStringLiteral("invited_us"); expectedNumIncidences = 1; expectedPartStat = KCalCore::Attendee::Accepted; action = QStringLiteral("accepted"); QTest::newRow("invited us1") << data_filename << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Someone invited us to an event, and we accept conditionally expectedResult = ITIPHandler::ResultSuccess; data_filename = QStringLiteral("invited_us"); expectedNumIncidences = 1; expectedPartStat = KCalCore::Attendee::Tentative; action = QStringLiteral("tentative"); QTest::newRow("invited us2") << data_filename << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Someone invited us to an event, we delegate it expectedResult = ITIPHandler::ResultSuccess; data_filename = QStringLiteral("invited_us"); // The e-mail to the delegate is sent by kmail's text_calendar.cpp expectedNumIncidences = 1; expectedPartStat = KCalCore::Attendee::Delegated; action = QStringLiteral("delegated"); QTest::newRow("invited us3") << data_filename << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Process a CANCEL without having the incidence in our calendar. // itiphandler should return success and not error expectedResult = ITIPHandler::ResultSuccess; data_filename = QStringLiteral("invited_us"); expectedNumIncidences = 0; action = QStringLiteral("cancel"); QTest::newRow("invited us4") << data_filename << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Process a REQUEST without having the incidence in our calendar. // itiphandler should return success and add the rquest to a calendar expectedResult = ITIPHandler::ResultSuccess; data_filename = QLatin1String("invited_us"); expectedNumIncidences = 1; expectedPartStat = KCalCore::Attendee::NeedsAction; action = QLatin1String("request"); QTest::newRow("invited us5") << data_filename << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Here we're testing an error case, where data is null. expectedResult = ITIPHandler::ResultError; expectedNumIncidences = 0; action = QStringLiteral("accepted"); QTest::newRow("invalid data") << QString() << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Testing invalid action expectedResult = ITIPHandler::ResultError; data_filename = QStringLiteral("invitation_us"); expectedNumIncidences = 0; action = QStringLiteral("accepted"); QTest::newRow("invalid action") << data_filename << QString() << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Test bug 235749 expectedResult = ITIPHandler::ResultSuccess; data_filename = QStringLiteral("bug235749"); expectedNumIncidences = 1; expectedPartStat = KCalCore::Attendee::Accepted; action = QStringLiteral("accepted"); incidenceUid = QStringLiteral("b6f0466a-8877-49d0-a4fc-8ee18ffd8e07"); // Don't change, hardcoded in data file QTest::newRow("bug 235749") << data_filename << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- // Test counterproposal without a UI delegat set expectedResult = ITIPHandler::ResultError; data_filename = QStringLiteral("invited_us"); expectedNumIncidences = 0; expectedPartStat = KCalCore::Attendee::Accepted; action = QStringLiteral("counter"); incidenceUid = QStringLiteral("b6f0466a-8877-49d0-a4fc-8ee18ffd8e07"); QTest::newRow("counter error") << data_filename << action << receiver << incidenceUid << expectedResult << expectedNumIncidences << expectedPartStat; //---------------------------------------------------------------------------------------------- } void ITIPHandlerTest::testProcessITIPMessage() { QFETCH(QString, data_filename); QFETCH(QString, action); QFETCH(QString, receiver); QFETCH(QString, incidenceUid); QFETCH(Akonadi::ITIPHandler::Result, expectedResult); QFETCH(int, expectedNumIncidences); QFETCH(KCalCore::Attendee::PartStat, expectedPartStat); FakeMessageQueueJob::sUnitTestResults.clear(); createITIPHandler(); m_expectedResult = expectedResult; QString iCalData = icalData(data_filename); Akonadi::Item::List items; processItip(iCalData, receiver, action, expectedNumIncidences, items); if (expectedNumIncidences == 1) { KCalCore::Incidence::Ptr incidence = items.first().payload(); QVERIFY(incidence); QCOMPARE(incidence->schedulingID(), incidenceUid); QVERIFY(incidence->schedulingID() != incidence->uid()); KCalCore::Attendee::Ptr me = ourAttendee(incidence); QVERIFY(me); QCOMPARE(me->status(), expectedPartStat); } cleanup(); } void ITIPHandlerTest::testProcessITIPMessages_data() { QTest::addColumn("invitation_filenames"); // filename to create incidence (inputs) QTest::addColumn("expected_filename"); // filename with expected data (reference) QTest::addColumn("actions"); // we must specify the METHOD. This is an ITipHandler API workaround, not sure why we must pass it as argument since it's already inside the icaldata. QStringList invitation_filenames; QString expected_filename; QStringList actions; actions << QStringLiteral("accepted") << QStringLiteral("accepted"); //---------------------------------------------------------------------------------------------- // Someone invited us to an event, we accept, then organizer changes event, and we record update: invitation_filenames.clear(); invitation_filenames << QStringLiteral("invited_us") << QStringLiteral("invited_us_update01"); expected_filename = QStringLiteral("expected_data/update1"); QTest::newRow("accept update") << invitation_filenames << expected_filename << actions; //---------------------------------------------------------------------------------------------- // Someone invited us to an event, we accept, then organizer changes event, and we record update: invitation_filenames.clear(); invitation_filenames << QStringLiteral("invited_us") << QStringLiteral("invited_us_daily_update01"); expected_filename = QStringLiteral("expected_data/update2"); QTest::newRow("accept recurringupdate") << invitation_filenames << expected_filename << actions; //---------------------------------------------------------------------------------------------- // We accept a recurring event, then the organizer changes the summary to the second instance (RECID) expected_filename = QStringLiteral("expected_data/update3"); invitation_filenames.clear(); invitation_filenames << QStringLiteral("invited_us_daily") << QStringLiteral("invited_us_daily_update_recid01"); QTest::newRow("accept recid update") << invitation_filenames << expected_filename << actions; //---------------------------------------------------------------------------------------------- // We accept a recurring event, then we accept a CANCEL with recuring-id. // The result is that a exception with status CANCELLED should be created, and our main incidence // should not be touched invitation_filenames.clear(); invitation_filenames << QStringLiteral("invited_us_daily") << QStringLiteral("invited_us_daily_cancel_recid01"); expected_filename = QStringLiteral("expected_data/cancel1"); actions << QStringLiteral("accepted") << QStringLiteral("cancel"); QTest::newRow("accept recid cancel") << invitation_filenames << expected_filename << actions; //---------------------------------------------------------------------------------------------- } void ITIPHandlerTest::testProcessITIPMessages() { QFETCH(QStringList, invitation_filenames); QFETCH(QString, expected_filename); QFETCH(QStringList, actions); const QString receiver = QLatin1String(s_ourEmail); FakeMessageQueueJob::sUnitTestResults.clear(); createITIPHandler(); m_expectedResult = Akonadi::ITIPHandler::ResultSuccess; for (int i = 0; i < invitation_filenames.count(); i++) { // First accept the invitation that creates the incidence: QString iCalData = icalData(invitation_filenames.at(i)); Item::List items; qDebug() << "Processing " << invitation_filenames.at(i); processItip(iCalData, receiver, actions.at(i), -1, items); } QString expectedICalData = icalData(expected_filename); KCalCore::MemoryCalendar::Ptr expectedCalendar = KCalCore::MemoryCalendar::Ptr(new KCalCore::MemoryCalendar(KDateTime::UTC)); KCalCore::ICalFormat format; format.fromString(expectedCalendar, expectedICalData); compareCalendars(expectedCalendar); // Here's where the cool and complex comparations are done cleanup(); } void ITIPHandlerTest::testProcessITIPMessageCancel_data() { QTest::addColumn("creation_data_filename"); // filename to create incidence QTest::addColumn("cancel_data_filename"); // filename with incidence cancelation QTest::addColumn("incidenceUid"); // uid of incidence in invitation QString creation_data_filename; QString cancel_data_filename; QString incidenceUid = QStringLiteral("uosj936i6arrtl9c2i5r2mfuvg"); //---------------------------------------------------------------------------------------------- // Someone invited us to an event, we accept, then organizer cancels event creation_data_filename = QStringLiteral("invited_us"); cancel_data_filename = QStringLiteral("invited_us_cancel01"); QTest::newRow("cancel1") << creation_data_filename << cancel_data_filename << incidenceUid; //---------------------------------------------------------------------------------------------- // Someone invited us to daily event, we accept, then organizer cancels the whole recurrence series creation_data_filename = QStringLiteral("invited_us_daily"); cancel_data_filename = QStringLiteral("invited_us_daily_cancel01"); QTest::newRow("cancel_daily") << creation_data_filename << cancel_data_filename << incidenceUid; //---------------------------------------------------------------------------------------------- } void ITIPHandlerTest::testProcessITIPMessageCancel() { QFETCH(QString, creation_data_filename); QFETCH(QString, cancel_data_filename); QFETCH(QString, incidenceUid); const QString receiver = QLatin1String(s_ourEmail); FakeMessageQueueJob::sUnitTestResults.clear(); createITIPHandler(); m_expectedResult = Akonadi::ITIPHandler::ResultSuccess; // First accept the invitation that creates the incidence: QString iCalData = icalData(creation_data_filename); Item::List items; processItip(iCalData, receiver, QStringLiteral("accepted"), 1, items); KCalCore::Incidence::Ptr incidence = items.first().payload(); QVERIFY(incidence); // good, now accept the invitation that has the CANCEL iCalData = icalData(cancel_data_filename); processItip(iCalData, receiver, QStringLiteral("accepted"), 0, items); } void ITIPHandlerTest::testOutgoingInvitations_data() { QTest::addColumn("item"); // existing incidence that will be target of creation, deletion or modification QTest::addColumn("changeType"); // creation, deletion, modification QTest::addColumn("expectedEmailCount"); QTest::addColumn("invitationPolicy"); QTest::addColumn("userCancels"); const bool userDoesntCancel = false; const bool userCancels = true; Akonadi::Item item; KCalCore::Incidence::Ptr incidence; IncidenceChanger::ChangeType changeType; const IncidenceChanger::InvitationPolicy invitationPolicyAsk = IncidenceChanger::InvitationPolicyAsk; const IncidenceChanger::InvitationPolicy invitationPolicySend = IncidenceChanger::InvitationPolicySend; const IncidenceChanger::InvitationPolicy invitationPolicyDontSend = IncidenceChanger::InvitationPolicyDontSend; int expectedEmailCount = 0; Q_UNUSED(invitationPolicyAsk); const QString ourEmail = QLatin1String(s_ourEmail); const Attendee::Ptr us = Attendee::Ptr(new Attendee(QString(), ourEmail)); const Attendee::Ptr mia = Attendee::Ptr(new Attendee(QStringLiteral("Mia Wallace"), QStringLiteral("mia@dev.nul"))); const Attendee::Ptr vincent = Attendee::Ptr(new Attendee(QStringLiteral("Vincent"), QStringLiteral("vincent@dev.nul"))); const Attendee::Ptr jules = Attendee::Ptr(new Attendee(QStringLiteral("Jules"), QStringLiteral("jules@dev.nul"))); const QString uid = QStringLiteral("random-uid-123"); //---------------------------------------------------------------------------------------------- // Creation. We are organizer. We invite another person. changeType = IncidenceChanger::ChangeTypeCreate; item = generateIncidence(uid, /**organizer=*/ourEmail); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); expectedEmailCount = 1; QTest::newRow("Creation. We organize.") << item << changeType << expectedEmailCount << invitationPolicySend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // Creation. We are organizer. We invite another person. But we choose not to send invitation e-mail. changeType = IncidenceChanger::ChangeTypeCreate; item = generateIncidence(uid, /**organizer=*/ourEmail); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); expectedEmailCount = 0; QTest::newRow("Creation. We organize.2") << item << changeType << expectedEmailCount << invitationPolicyDontSend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We delete an event that we organized, and has attendees, that will be notified. changeType = IncidenceChanger::ChangeTypeDelete; item = generateIncidence(uid, /**organizer=*/ourEmail); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); expectedEmailCount = 1; QTest::newRow("Deletion. We organized.") << item << changeType << expectedEmailCount << invitationPolicySend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We delete an event that we organized, and has attendees. We won't send e-mail notifications. changeType = IncidenceChanger::ChangeTypeDelete; item = generateIncidence(uid, /**organizer=*/ourEmail); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); expectedEmailCount = 0; QTest::newRow("Deletion. We organized.2") << item << changeType << expectedEmailCount << invitationPolicyDontSend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We delete an event that we organized, and has attendees, who will be notified. changeType = IncidenceChanger::ChangeTypeModify; item = generateIncidence(uid, /**organizer=*/ourEmail); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); expectedEmailCount = 1; QTest::newRow("Modification. We organizd.") << item << changeType << expectedEmailCount << invitationPolicySend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We delete an event that we organized, and has attendees, who wont be notified. changeType = IncidenceChanger::ChangeTypeModify; item = generateIncidence(uid, /**organizer=*/ourEmail); incidence = item.payload(); incidence->addAttendee(vincent); // TODO: test that all attendees got the e-mail incidence->addAttendee(jules); expectedEmailCount = 0; QTest::newRow("Modification. We organizd.2") << item << changeType << expectedEmailCount << invitationPolicyDontSend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We delete an event which we're not the organizer of. Organizer gets REPLY with PartState=Declined changeType = IncidenceChanger::ChangeTypeDelete; item = generateIncidence(uid, /**organizer=*/mia->email()); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); us->setStatus(Attendee::Accepted); // TODO: Test without accepted status incidence->addAttendee(us); // TODO: test that attendees didn't receive the REPLY expectedEmailCount = 1; // REPLY is always sent, there are no dialogs to control this. Dialogs only control REQUEST and CANCEL. Bug or feature ? QTest::newRow("Deletion. We didnt organize.") << item << changeType << expectedEmailCount << invitationPolicyDontSend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We delete an event which we're not the organizer of. Organizer gets REPLY with PartState=Declined changeType = IncidenceChanger::ChangeTypeDelete; item = generateIncidence(uid, /**organizer=*/mia->email()); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); // TODO: test that attendees didn't receive the REPLY us->setStatus(Attendee::Accepted); // TODO: Test without accepted status incidence->addAttendee(us); expectedEmailCount = 1; QTest::newRow("Deletion. We didnt organize.2") << item << changeType << expectedEmailCount << invitationPolicySend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We modified an event which we're not the organizer of. And, when the "do you really want to modify", we choose "yes". changeType = IncidenceChanger::ChangeTypeModify; item = generateIncidence(uid, /**organizer=*/mia->email()); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); us->setStatus(Attendee::Accepted); incidence->addAttendee(us); expectedEmailCount = 0; QTest::newRow("Modification. We didnt organize") << item << changeType << expectedEmailCount << invitationPolicySend << userDoesntCancel; //---------------------------------------------------------------------------------------------- // We modified an event which we're not the organizer of. And, when the "do you really want to modify", we choose "no". changeType = IncidenceChanger::ChangeTypeModify; item = generateIncidence(uid, /**organizer=*/mia->email()); incidence = item.payload(); incidence->addAttendee(vincent); incidence->addAttendee(jules); us->setStatus(Attendee::Accepted); incidence->addAttendee(us); expectedEmailCount = 0; QTest::newRow("Modification. We didnt organize.2") << item << changeType << expectedEmailCount << invitationPolicyDontSend << userCancels; //---------------------------------------------------------------------------------------------- } void ITIPHandlerTest::testOutgoingInvitations() { QFETCH(Akonadi::Item, item); QFETCH(IncidenceChanger::ChangeType, changeType); QFETCH(int, expectedEmailCount); QFETCH(IncidenceChanger::InvitationPolicy, invitationPolicy); QFETCH(bool, userCancels); KCalCore::Incidence::Ptr incidence = item.payload(); m_pendingIncidenceChangerSignal = 1; FakeMessageQueueJob::sUnitTestResults.clear(); m_changer->setInvitationPolicy(invitationPolicy); m_cancelExpected = userCancels; switch (changeType) { case IncidenceChanger::ChangeTypeCreate: m_changer->createIncidence(incidence, mCollection); waitForIt(); QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), expectedEmailCount); break; case IncidenceChanger::ChangeTypeModify: { // Create if first, so we have something to modify m_changer->setGroupwareCommunication(false); // we disable groupware because creating an incidence which we're not the organizer of is not permitted. m_changer->createIncidence(incidence, mCollection); waitForIt(); m_changer->setGroupwareCommunication(true); QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), 0); QVERIFY(mLastInsertedItem.isValid()); m_pendingIncidenceChangerSignal = 1; Incidence::Ptr oldIncidence = Incidence::Ptr(incidence->clone()); incidence->setSummary(QStringLiteral("the-new-summary")); int changeId = m_changer->modifyIncidence(mLastInsertedItem, oldIncidence); QVERIFY(changeId != 1); waitForIt(); QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), expectedEmailCount); break; } case IncidenceChanger::ChangeTypeDelete: // Create if first, so we have something to delete m_changer->setGroupwareCommunication(false); m_changer->createIncidence(incidence, mCollection); waitForIt(); m_changer->setGroupwareCommunication(true); QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), 0); QVERIFY(mLastInsertedItem.isValid()); m_pendingIncidenceChangerSignal = 1; m_changer->deleteIncidence(mLastInsertedItem); waitForIt(); QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), expectedEmailCount); break; default: Q_ASSERT(false); } } void ITIPHandlerTest::testIdentity_data() { QTest::addColumn("email"); QTest::addColumn("expectedResult"); const QString myEmail = QLatin1String(s_ourEmail); QString myEmail2 = QStringLiteral("Some name <%1>").arg(myEmail); const QString myAlias1 = QStringLiteral("alias1@kde.org"); // hardcoded in emailidentities, do not change const QString myIdentity2 = QLatin1String(s_outEmail2); QTest::newRow("Me") << myEmail << true; QTest::newRow("Also me") << myEmail2 << true; QTest::newRow("My identity2") << myIdentity2 << true; QTest::newRow("Not me") << QStringLiteral("laura.palmer@twinpeaks.com") << false; QTest::newRow("My alias") << myAlias1 << true; } void ITIPHandlerTest::testIdentity() { QFETCH(QString, email); QFETCH(bool, expectedResult); if (CalendarUtils::thatIsMe(email) != expectedResult) { qDebug() << email; QVERIFY(false); } } void ITIPHandlerTest::cleanup() { Akonadi::Item::List items = calendarItems(); foreach (const Akonadi::Item &item, items) { ItemDeleteJob *job = new ItemDeleteJob(item); AKVERIFYEXEC(job); } delete m_itipHandler; m_itipHandler = 0; } void ITIPHandlerTest::createITIPHandler() { m_itipHandler = new Akonadi::ITIPHandler(new FakeITIPHandlerComponentFactory(this), this); m_itipHandler->setShowDialogsOnError(false); connect(m_itipHandler, SIGNAL(iTipMessageProcessed(Akonadi::ITIPHandler::Result,QString)), SLOT(oniTipMessageProcessed(Akonadi::ITIPHandler::Result,QString))); } QString ITIPHandlerTest::icalData(const QString &data_filename) { QString absolutePath = QLatin1String(ITIP_DATA_DIR) + QLatin1Char('/') + data_filename; return QString::fromLatin1(readFile(absolutePath)); } void ITIPHandlerTest::processItip(const QString &icaldata, const QString &receiver, const QString &action, int expectedNumIncidences, Akonadi::Item::List &items) { items.clear(); m_pendingItipMessageSignal = 1; m_itipHandler->processiTIPMessage(receiver, icaldata, action); waitForIt(); // 0 e-mails are sent because the status update e-mail is sent by // kmail's text_calendar.cpp. QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), 0); items = calendarItems(); if (expectedNumIncidences != -1) { QCOMPARE(items.count(), expectedNumIncidences); } } Attendee::Ptr ITIPHandlerTest::ourAttendee(const KCalCore::Incidence::Ptr &incidence) const { KCalCore::Attendee::List attendees = incidence->attendees(); KCalCore::Attendee::Ptr me; foreach (const KCalCore::Attendee::Ptr &attendee, attendees) { if (attendee->email() == QLatin1String(s_ourEmail)) { me = attendee; break; } } return me; } void ITIPHandlerTest::oniTipMessageProcessed(ITIPHandler::Result result, const QString &errorMessage) { if (result != ITIPHandler::ResultSuccess && result != m_expectedResult) { qDebug() << "ITIPHandlerTest::oniTipMessageProcessed() error = " << errorMessage; } m_pendingItipMessageSignal--; QVERIFY(m_pendingItipMessageSignal >= 0); if (m_pendingItipMessageSignal == 0) { stopWaiting(); } QCOMPARE(m_expectedResult, result); } void ITIPHandlerTest::onCreateFinished(int changeId, const Item &item, IncidenceChanger::ResultCode resultCode, const QString &errorString) { Q_UNUSED(changeId); Q_UNUSED(errorString); mLastInsertedItem = item; m_pendingIncidenceChangerSignal--; QVERIFY(m_pendingIncidenceChangerSignal >= 0); if (m_pendingIncidenceChangerSignal == 0) { stopWaiting(); } QCOMPARE(resultCode, IncidenceChanger::ResultCodeSuccess); } -void ITIPHandlerTest::onDeleteFinished(int changeId, const QVector &deletedIds, +void ITIPHandlerTest::onDeleteFinished(int changeId, const QVector &deletedIds, IncidenceChanger::ResultCode resultCode, const QString &errorString) { Q_UNUSED(changeId); Q_UNUSED(errorString); Q_UNUSED(deletedIds); m_pendingIncidenceChangerSignal--; QVERIFY(m_pendingIncidenceChangerSignal >= 0); if (m_pendingIncidenceChangerSignal == 0) { stopWaiting(); } QCOMPARE(resultCode, IncidenceChanger::ResultCodeSuccess); } void ITIPHandlerTest::onModifyFinished(int changeId, const Item &item, IncidenceChanger::ResultCode resultCode, const QString &errorString) { Q_UNUSED(changeId); Q_UNUSED(errorString); Q_UNUSED(item); m_pendingIncidenceChangerSignal--; QVERIFY(m_pendingIncidenceChangerSignal >= 0); if (m_pendingIncidenceChangerSignal == 0) { stopWaiting(); } QCOMPARE(resultCode, m_cancelExpected ? IncidenceChanger::ResultCodeUserCanceled : IncidenceChanger::ResultCodeSuccess); } -QTEST_AKONADIMAIN(ITIPHandlerTest, GUI) +QTEST_AKONADIMAIN(ITIPHandlerTest) diff --git a/autotests/itiphandlertest.h b/autotests/itiphandlertest.h index 4618d21..f40f646 100644 --- a/autotests/itiphandlertest.h +++ b/autotests/itiphandlertest.h @@ -1,95 +1,95 @@ /* Copyright (c) 2013 Sérgio Martins 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 ITIPHANDLER_TEST_H #define ITIPHANDLER_TEST_H -#include "../incidencechanger.h" -#include "../itiphandler.h" +#include "incidencechanger.h" +#include "itiphandler.h" #include "unittestbase.h" #include #include #include class ITIPHandlerTest : public UnitTestBase { Q_OBJECT private Q_SLOTS: void initTestCase(); void testProcessITIPMessages_data(); void testProcessITIPMessages(); // Deprecated methods, use testProcessITIPMessages() for new stuff void testProcessITIPMessage_data(); void testProcessITIPMessage(); // Deprecated methods do test CANCEL. void testProcessITIPMessageCancel_data(); void testProcessITIPMessageCancel(); // These ones don't have to do with kmail. It's when doing a modification, itip REQUESTs are sent. // Also tests cases where we're not the organizer. void testOutgoingInvitations_data(); void testOutgoingInvitations(); // Tests identity related code, like "thisIsMe()". void testIdentity_data(); void testIdentity(); private: void waitForSignals(); void cleanup(); void createITIPHandler(); QString icalData(const QString &filename); void processItip(const QString &icaldata, const QString &receiver, const QString &action, int expectedNumIncidences, Akonadi::Item::List &items); KCalCore::Attendee::Ptr ourAttendee(const KCalCore::Incidence::Ptr &incidence) const; public Q_SLOTS: void oniTipMessageProcessed(Akonadi::ITIPHandler::Result result, const QString &errorMessage); void onCreateFinished(int changeId, const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); void onDeleteFinished(int changeId, const QVector &deletedIds, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorMessage); void onModifyFinished(int changeId, const Akonadi::Item &item, Akonadi::IncidenceChanger::ResultCode resultCode, const QString &errorString); private: int m_pendingItipMessageSignal; int m_pendingIncidenceChangerSignal; Akonadi::Item mLastInsertedItem; Akonadi::ITIPHandler::Result m_expectedResult; Akonadi::ITIPHandler *m_itipHandler; Akonadi::IncidenceChanger *m_changer; bool m_cancelExpected; }; #endif diff --git a/autotests/mailclienttest.cpp b/autotests/mailclienttest.cpp index 0e26724..8e2ec0b 100644 --- a/autotests/mailclienttest.cpp +++ b/autotests/mailclienttest.cpp @@ -1,444 +1,444 @@ /* Copyright (c) 2011 Sérgio Martins 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. */ // mailclient_p.cpp isn't exported so we include it directly. -#include "../mailclient_p.h" +#include "mailclient_p.h" #include #include #include -#include +#include #include #include #include static const char *s_ourEmail = "unittests@dev.nul"; // change also in kdepimlibs/akonadi/calendar/tests/unittestenv/kdehome/share/config using namespace Akonadi; Q_DECLARE_METATYPE(KIdentityManagement::Identity) Q_DECLARE_METATYPE(KCalCore::Incidence::Ptr) class FakeMessageQueueJob : public MailTransport::MessageQueueJob { public: explicit FakeMessageQueueJob(QObject *parent = 0) : MailTransport::MessageQueueJob(parent) { } virtual void start() { UnitTestResult unitTestResult; unitTestResult.message = message(); unitTestResult.from = addressAttribute().from(); unitTestResult.to = addressAttribute().to(); unitTestResult.cc = addressAttribute().cc(); unitTestResult.bcc = addressAttribute().bcc(); unitTestResult.transportId = transportAttribute().transportId(); FakeMessageQueueJob::sUnitTestResults << unitTestResult; setError(Akonadi::MailClient::ResultSuccess); setErrorText(QString()); emitResult(); } static UnitTestResult::List sUnitTestResults; }; UnitTestResult::List FakeMessageQueueJob::sUnitTestResults; class FakeITIPHandlerComponentFactory : public ITIPHandlerComponentFactory { public: explicit FakeITIPHandlerComponentFactory(QObject *parent = 0) : ITIPHandlerComponentFactory(parent) { } virtual MailTransport::MessageQueueJob *createMessageQueueJob(const KCalCore::IncidenceBase::Ptr &incidence, const KIdentityManagement::Identity &identity, QObject *parent = 0) { Q_UNUSED(incidence); Q_UNUSED(identity); return new FakeMessageQueueJob(parent); } }; class MailClientTest : public QObject { Q_OBJECT private: MailClient *mMailClient; int mPendingSignals; MailClient::Result mLastResult; QString mLastErrorMessage; private Q_SLOTS: void initTestCase() { AkonadiTest::checkTestIsIsolated(); mPendingSignals = 0; mMailClient = new MailClient(new FakeITIPHandlerComponentFactory(this), this); mLastResult = MailClient::ResultSuccess; connect(mMailClient, SIGNAL(finished(Akonadi::MailClient::Result,QString)), SLOT(handleFinished(Akonadi::MailClient::Result,QString))); } void cleanupTestCase() { } void testMailAttendees_data() { QTest::addColumn("incidence"); QTest::addColumn("identity"); QTest::addColumn("bccMe"); QTest::addColumn("attachment"); QTest::addColumn("transport"); QTest::addColumn("expectedResult"); QTest::addColumn("expectedTransportId"); QTest::addColumn("expectedFrom"); QTest::addColumn("expectedToList"); QTest::addColumn("expectedCcList"); QTest::addColumn("expectedBccList"); KCalCore::Incidence::Ptr incidence(new KCalCore::Event()); KIdentityManagement::Identity identity; bool bccMe; QString attachment; QString transport; MailClient::Result expectedResult = MailClient::ResultNoAttendees; const int expectedTransportId = 69372773; // from tests/unittestenv/kdehome/share/config/mailtransports const QString expectedFrom = QStringLiteral("unittests@dev.nul"); // from tests/unittestenv/kdehome/share/config/emailidentities KCalCore::Person::Ptr organizer(new KCalCore::Person(QStringLiteral("Organizer"), QStringLiteral("unittests@dev.nul"))); QStringList toList; QStringList toCcList; QStringList toBccList; //---------------------------------------------------------------------------------------------- QTest::newRow("No attendees") << incidence << identity << bccMe << attachment << transport << expectedResult << -1 << QString() << toList << toCcList << toBccList; //---------------------------------------------------------------------------------------------- // One attendee, but without e-mail KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(QStringLiteral("name1"), QString())); incidence = KCalCore::Incidence::Ptr(new KCalCore::Event()); incidence->addAttendee(attendee); expectedResult = MailClient::ResultReallyNoAttendees; QTest::newRow("No attendees with email") << incidence << identity << bccMe << attachment << transport << expectedResult << -1 << QString() << toList << toCcList << toBccList; //---------------------------------------------------------------------------------------------- // One valid attendee attendee = KCalCore::Attendee::Ptr(new KCalCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"))); incidence = KCalCore::Incidence::Ptr(new KCalCore::Event()); incidence->addAttendee(attendee); incidence->setOrganizer(organizer); expectedResult = MailClient::ResultSuccess; toList << QStringLiteral("test@foo.org"); QTest::newRow("One attendee") << incidence << identity << bccMe << attachment << transport << expectedResult << expectedTransportId << expectedFrom << toList << toCcList << toBccList; //---------------------------------------------------------------------------------------------- // One valid attendee attendee = KCalCore::Attendee::Ptr(new KCalCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"))); incidence = KCalCore::Incidence::Ptr(new KCalCore::Event()); incidence->setOrganizer(organizer); incidence->addAttendee(attendee); QString invalidTransport = QStringLiteral("foo"); expectedResult = MailClient::ResultSuccess; // Should default to the default transport QTest::newRow("Invalid transport") << incidence << identity << bccMe << attachment << invalidTransport << expectedResult << expectedTransportId << expectedFrom << toList << toCcList << toBccList; //---------------------------------------------------------------------------------------------- // One valid attendee, and bcc me attendee = KCalCore::Attendee::Ptr(new KCalCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"))); incidence = KCalCore::Incidence::Ptr(new KCalCore::Event()); incidence->setOrganizer(organizer); incidence->addAttendee(attendee); expectedResult = MailClient::ResultSuccess; // Should default to the default transport toBccList.clear(); toBccList << QStringLiteral("unittests@dev.nul"); QTest::newRow("Test bcc") << incidence << identity << /*bccMe*/true << attachment << transport << expectedResult << expectedTransportId << expectedFrom << toList << toCcList << toBccList; //---------------------------------------------------------------------------------------------- // Test CC list attendee = KCalCore::Attendee::Ptr(new KCalCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"))); KCalCore::Attendee::Ptr optionalAttendee = KCalCore::Attendee::Ptr(new KCalCore::Attendee(QStringLiteral("opt"), QStringLiteral("optional@foo.org"))); KCalCore::Attendee::Ptr nonParticipant = KCalCore::Attendee::Ptr(new KCalCore::Attendee(QStringLiteral("non"), QStringLiteral("non@foo.org"))); optionalAttendee->setRole(KCalCore::Attendee::OptParticipant); nonParticipant->setRole(KCalCore::Attendee::NonParticipant); incidence = KCalCore::Incidence::Ptr(new KCalCore::Event()); incidence->setOrganizer(organizer); incidence->addAttendee(attendee); incidence->addAttendee(optionalAttendee); incidence->addAttendee(nonParticipant); expectedResult = MailClient::ResultSuccess; // Should default to the default transport toBccList.clear(); toBccList << QStringLiteral("unittests@dev.nul"); toCcList.clear(); toCcList << QStringLiteral("optional@foo.org") << QStringLiteral("non@foo.org"); QTest::newRow("Test cc") << incidence << identity << /*bccMe*/true << attachment << transport << expectedResult << expectedTransportId << expectedFrom << toList << toCcList << toBccList; } void testMailAttendees() { QFETCH(KCalCore::Incidence::Ptr, incidence); QFETCH(KIdentityManagement::Identity, identity); QFETCH(bool, bccMe); QFETCH(QString, attachment); QFETCH(QString, transport); QFETCH(MailClient::Result, expectedResult); QFETCH(int, expectedTransportId); QFETCH(QString, expectedFrom); QFETCH(QStringList, expectedToList); QFETCH(QStringList, expectedCcList); QFETCH(QStringList, expectedBccList); FakeMessageQueueJob::sUnitTestResults.clear(); mPendingSignals = 1; mMailClient->mailAttendees(incidence, identity, bccMe, attachment, transport); waitForSignals(); if (mLastResult != expectedResult) { qDebug() << "Fail1: last=" << mLastResult << "; expected=" << expectedResult << "; error=" << mLastErrorMessage; QVERIFY(false); } UnitTestResult unitTestResult; if (FakeMessageQueueJob::sUnitTestResults.isEmpty()) { qDebug() << "mail results are empty"; } else { unitTestResult = FakeMessageQueueJob::sUnitTestResults.first(); } if (expectedTransportId != -1 && unitTestResult.transportId != expectedTransportId) { qDebug() << "got " << unitTestResult.transportId << "; expected=" << expectedTransportId; QVERIFY(false); } QCOMPARE(unitTestResult.from, expectedFrom); QCOMPARE(unitTestResult.to, expectedToList); QCOMPARE(unitTestResult.cc, expectedCcList); QCOMPARE(unitTestResult.bcc, expectedBccList); } void testMailOrganizer_data() { QTest::addColumn("incidence"); QTest::addColumn("identity"); QTest::addColumn("from"); QTest::addColumn("bccMe"); QTest::addColumn("attachment"); QTest::addColumn("subject"); QTest::addColumn("transport"); QTest::addColumn("expectedResult"); QTest::addColumn("expectedTransportId"); QTest::addColumn("expectedFrom"); QTest::addColumn("expectedToList"); QTest::addColumn("expectedBccList"); QTest::addColumn("expectedSubject"); KCalCore::IncidenceBase::Ptr incidence(new KCalCore::Event()); KIdentityManagement::Identity identity; const QString from = QLatin1String(s_ourEmail); bool bccMe; QString attachment; QString subject = QStringLiteral("subject1"); QString transport; MailClient::Result expectedResult = MailClient::ResultSuccess; const int expectedTransportId = 69372773; // from tests/unittestenv/kdehome/share/config/mailtransports QString expectedFrom = from; // from tests/unittestenv/kdehome/share/config/emailidentities KCalCore::Person::Ptr organizer(new KCalCore::Person(QStringLiteral("Organizer"), QStringLiteral("unittests@dev.nul"))); incidence->setOrganizer(organizer); QStringList toList; toList << QStringLiteral("unittests@dev.nul"); QStringList toBccList; QString expectedSubject; //---------------------------------------------------------------------------------------------- expectedSubject = subject; QTest::newRow("test1") << incidence << identity << from << bccMe << attachment << subject << transport << expectedResult << expectedTransportId << expectedFrom << toList << toBccList << expectedSubject; //---------------------------------------------------------------------------------------------- expectedSubject = QStringLiteral("Free Busy Message"); incidence = KCalCore::IncidenceBase::Ptr(new KCalCore::FreeBusy()); incidence->setOrganizer(organizer); QTest::newRow("FreeBusy") << incidence << identity << from << bccMe << attachment << subject << transport << expectedResult << expectedTransportId << expectedFrom << toList << toBccList << expectedSubject; } void testMailOrganizer() { QFETCH(KCalCore::IncidenceBase::Ptr, incidence); QFETCH(KIdentityManagement::Identity, identity); QFETCH(QString, from); QFETCH(bool, bccMe); QFETCH(QString, attachment); QFETCH(QString, subject); QFETCH(QString, transport); QFETCH(MailClient::Result, expectedResult); QFETCH(int, expectedTransportId); QFETCH(QString, expectedFrom); QFETCH(QStringList, expectedToList); QFETCH(QStringList, expectedBccList); QFETCH(QString, expectedSubject); FakeMessageQueueJob::sUnitTestResults.clear(); mPendingSignals = 1; mMailClient->mailOrganizer(incidence, identity, from, bccMe, attachment, subject, transport); waitForSignals(); QCOMPARE(mLastResult, expectedResult); UnitTestResult unitTestResult = FakeMessageQueueJob::sUnitTestResults.first(); if (expectedTransportId != -1) { QCOMPARE(unitTestResult.transportId, expectedTransportId); } QCOMPARE(unitTestResult.from, expectedFrom); QCOMPARE(unitTestResult.to, expectedToList); QCOMPARE(unitTestResult.bcc, expectedBccList); QCOMPARE(unitTestResult.message->subject()->asUnicodeString(), expectedSubject); } void testMailTo_data() { QTest::addColumn("incidence"); QTest::addColumn("identity"); QTest::addColumn("from"); QTest::addColumn("bccMe"); QTest::addColumn("recipients"); QTest::addColumn("attachment"); QTest::addColumn("transport"); QTest::addColumn("expectedResult"); QTest::addColumn("expectedTransportId"); QTest::addColumn("expectedFrom"); QTest::addColumn("expectedToList"); QTest::addColumn("expectedBccList"); KCalCore::IncidenceBase::Ptr incidence(new KCalCore::Event()); KIdentityManagement::Identity identity; const QString from = QLatin1String(s_ourEmail); bool bccMe; const QString recipients = QStringLiteral("unittests@dev.nul"); QString attachment; QString transport; MailClient::Result expectedResult = MailClient::ResultSuccess; const int expectedTransportId = 69372773; // from tests/unittestenv/kdehome/share/config/mailtransports QString expectedFrom = from; // from tests/unittestenv/kdehome/share/config/emailidentities KCalCore::Person::Ptr organizer(new KCalCore::Person(QStringLiteral("Organizer"), QStringLiteral("unittests@dev.nul"))); QStringList toList; toList << QLatin1String(s_ourEmail); QStringList toBccList; //---------------------------------------------------------------------------------------------- QTest::newRow("test1") << incidence << identity << from << bccMe << recipients << attachment << transport << expectedResult << expectedTransportId << expectedFrom << toList << toBccList; } void testMailTo() { QFETCH(KCalCore::IncidenceBase::Ptr, incidence); QFETCH(KIdentityManagement::Identity, identity); QFETCH(QString, from); QFETCH(bool, bccMe); QFETCH(QString, recipients); QFETCH(QString, attachment); QFETCH(QString, transport); QFETCH(MailClient::Result, expectedResult); QFETCH(int, expectedTransportId); QFETCH(QString, expectedFrom); QFETCH(QStringList, expectedToList); QFETCH(QStringList, expectedBccList); FakeMessageQueueJob::sUnitTestResults.clear(); mPendingSignals = 1; mMailClient->mailTo(incidence, identity, from, bccMe, recipients, attachment, transport); waitForSignals(); QCOMPARE(mLastResult, expectedResult); UnitTestResult unitTestResult = FakeMessageQueueJob::sUnitTestResults.first(); if (expectedTransportId != -1) { QCOMPARE(unitTestResult.transportId, expectedTransportId); } QCOMPARE(unitTestResult.from, expectedFrom); QCOMPARE(unitTestResult.to, expectedToList); QCOMPARE(unitTestResult.bcc, expectedBccList); } void handleFinished(Akonadi::MailClient::Result result, const QString &errorMessage) { qDebug() << "handleFinished: " << result << errorMessage; mLastResult = result; mLastErrorMessage = errorMessage; --mPendingSignals; QTestEventLoop::instance().exitLoop(); } void waitForSignals() { if (mPendingSignals > 0) { QTestEventLoop::instance().enterLoop(5); // 5 seconds is enough QVERIFY(!QTestEventLoop::instance().timeout()); } } public Q_SLOTS: private: }; -QTEST_AKONADIMAIN(MailClientTest, GUI) +QTEST_AKONADIMAIN(MailClientTest) #include "mailclienttest.moc" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4cdd6bf..9e2b735 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,117 +1,111 @@ -# TODO: Add a cmake option for this and enable it on jenkins -set( PLEASE_TEST_INVITATIONS FALSE) -if ( PLEASE_TEST_INVITATIONS ) - add_definitions( -DPLEASE_TEST_INVITATIONS ) -endif() - set(akonadicalendar_LIB_SRC blockalarmsattribute.cpp calendarbase.cpp calendarclipboard.cpp calendarmodel.cpp calfilterproxymodel_p.cpp etmcalendar.cpp history.cpp history_p.cpp icalimporter.cpp incidencefetchjob_p.cpp incidencechanger.cpp incidencechanger_p.cpp itiphandler.cpp itiphandler_p.cpp itiphandlerhelper_p.cpp kcolumnfilterproxymodel.cpp fetchjobcalendar.cpp freebusydownloadjob_p.cpp freebusymanager.cpp freebusyproviderbase.cpp mailclient_p.cpp mailscheduler_p.cpp publishdialog.cpp publishdialog_p.cpp scheduler_p.cpp standardcalendaractionmanager.cpp todopurger.cpp utils_p.cpp calfilterpartstatusproxymodel_p.cpp ) ecm_qt_declare_logging_category(akonadicalendar_LIB_SRC HEADER akonadicalendar_debug.h IDENTIFIER AKONADICALENDAR_LOG CATEGORY_NAME org.kde.pim.akonadicalendar) kconfig_add_kcfg_files(akonadicalendar_LIB_SRC calendarsettings.kcfgc) ki18n_wrap_ui(akonadicalendar_LIB_SRC publishdialog_base.ui) qt5_add_dbus_adaptor( akonadicalendar_LIB_SRC interfaces/org.freedesktop.Akonadi.Resource.FreeBusyProvider.xml freebusyproviderbase_p.h Akonadi::FreeBusyProviderBasePrivate freebusyprovideradaptor Akonadi__FreeBusyProviderAdaptor ) add_library(KF5AkonadiCalendar ${akonadicalendar_LIB_SRC}) generate_export_header(KF5AkonadiCalendar BASE_NAME akonadi-calendar) add_library(KF5::AkonadiCalendar ALIAS KF5AkonadiCalendar) target_include_directories(KF5AkonadiCalendar INTERFACE "$") target_include_directories(KF5AkonadiCalendar PUBLIC "$") target_link_libraries(KF5AkonadiCalendar PUBLIC KF5::AkonadiCore KF5::CalendarCore PRIVATE KF5::AkonadiContact KF5::CalendarUtils KF5::AkonadiWidgets KF5::MailTransport KF5::IdentityManagement KF5::Codecs KF5::DBusAddons ) set_target_properties(KF5AkonadiCalendar PROPERTIES VERSION ${AKONADICALENDAR_VERSION_STRING} SOVERSION ${AKONADICALENDAR_SOVERSION} EXPORT_NAME AkonadiCalendar ) ecm_generate_pri_file(BASE_NAME AkonadiCalendar LIB_NAME KF5AkonadiCalendar DEPS "AkonadiCore CalendarCore" FILENAME_VAR PRI_FILENAME ) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) install(TARGETS KF5AkonadiCalendar EXPORT KF5AkonadiCalendarTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS} ) ecm_generate_headers(AkonadiCalendar_CamelCase_HEADERS HEADER_NAMES BlockAlarmsAttribute CalendarBase CalendarClipboard ETMCalendar FetchJobCalendar FreeBusyManager FreeBusyProviderBase History ICalImporter IncidenceChanger ITIPHandler PublishDialog StandardCalendarActionManager TodoPurger REQUIRED_HEADERS AkonadiCalendar_HEADERS PREFIX Akonadi/Calendar ) install( FILES ${AkonadiCalendar_CamelCase_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/Akonadi/Calendar COMPONENT Devel ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/akonadi-calendar_export.h ${AkonadiCalendar_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/calendarsettings.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/akonadi/calendar COMPONENT Devel )