File indexing completed on 2025-01-05 04:49:44

0001 /*
0002    SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "eventedittest.h"
0008 #include "../createeventplugin/eventdatetimewidget.h"
0009 #include "../createeventplugin/eventedit.h"
0010 #include <messageviewer/globalsettings_messageviewer.h>
0011 
0012 #include <Akonadi/Collection>
0013 #include <Akonadi/CollectionComboBox>
0014 #include <Akonadi/EntityTreeModel>
0015 #include <KCalendarCore/Event>
0016 #include <QPushButton>
0017 #include <QStandardItemModel>
0018 
0019 #include <QTest>
0020 #include <qtestkeyboard.h>
0021 #include <qtestmouse.h>
0022 
0023 #include <QLineEdit>
0024 #include <QShortcut>
0025 #include <QSignalSpy>
0026 
0027 namespace MessageViewer
0028 {
0029 extern MESSAGEVIEWER_EXPORT QAbstractItemModel *_k_eventEditStubModel;
0030 }
0031 
0032 EventEditTest::EventEditTest(QObject *parent)
0033     : QObject(parent)
0034 {
0035     qRegisterMetaType<Akonadi::Collection>();
0036     qRegisterMetaType<KMime::Message::Ptr>();
0037     qRegisterMetaType<KCalendarCore::Event::Ptr>();
0038     QStandardPaths::setTestModeEnabled(true);
0039 
0040     auto model = new QStandardItemModel;
0041     for (int id = 42; id < 51; ++id) {
0042         Akonadi::Collection collection(id);
0043         collection.setRights(Akonadi::Collection::AllRights);
0044         collection.setName(QString::number(id));
0045         collection.setContentMimeTypes(QStringList() << KCalendarCore::Event::eventMimeType());
0046 
0047         auto item = new QStandardItem(collection.name());
0048         item->setData(QVariant::fromValue(collection), Akonadi::EntityTreeModel::CollectionRole);
0049         item->setData(QVariant::fromValue(collection.id()), Akonadi::EntityTreeModel::CollectionIdRole);
0050 
0051         model->appendRow(item);
0052     }
0053     MessageViewer::_k_eventEditStubModel = model;
0054 
0055     // Fake a default-selected collection for shouldHaveDefaultValuesOnCreation test
0056     MessageViewer::MessageViewerSettingsBase::self()->setLastEventSelectedFolder(43);
0057 }
0058 
0059 void EventEditTest::shouldHaveDefaultValuesOnCreation()
0060 {
0061     MessageViewer::EventEdit edit;
0062     QVERIFY(edit.collection().isValid());
0063     QVERIFY(!edit.message());
0064     auto eventedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0065     QVERIFY(eventedit);
0066     QCOMPARE(eventedit->text(), QString());
0067 
0068     auto openEditor = edit.findChild<QPushButton *>(QStringLiteral("open-editor-button"));
0069     auto save = edit.findChild<QPushButton *>(QStringLiteral("save-button"));
0070     QVERIFY(openEditor);
0071     QVERIFY(save);
0072     QCOMPARE(openEditor->isEnabled(), false);
0073     QCOMPARE(save->isEnabled(), false);
0074 
0075     QDateTime currentDateTime = QDateTime::currentDateTime();
0076     auto startDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("startdatetimeedit"));
0077     QVERIFY(startDateTime);
0078     QCOMPARE(startDateTime->dateTime().date(), currentDateTime.date());
0079     QCOMPARE(startDateTime->dateTime().time().hour(), currentDateTime.time().hour());
0080     QCOMPARE(startDateTime->dateTime().time().minute(), currentDateTime.time().minute());
0081 
0082     auto endDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("enddatetimeedit"));
0083     QVERIFY(endDateTime);
0084     currentDateTime = currentDateTime.addSecs(3600); // +1hour
0085     QCOMPARE(endDateTime->dateTime().date(), currentDateTime.date());
0086     QCOMPARE(endDateTime->dateTime().time().hour(), currentDateTime.time().hour());
0087     QCOMPARE(endDateTime->dateTime().time().minute(), currentDateTime.time().minute());
0088 }
0089 
0090 void EventEditTest::shouldEmitCollectionChanged()
0091 {
0092     MessageViewer::EventEdit edit;
0093     QSignalSpy spy(&edit, &MessageViewer::EventEdit::collectionChanged);
0094     edit.setCollection(Akonadi::Collection(42));
0095     QCOMPARE(spy.count(), 1);
0096     QCOMPARE(spy.at(0).at(0).value<Akonadi::Collection>(), Akonadi::Collection(42));
0097 }
0098 
0099 void EventEditTest::shouldEmitMessageChanged()
0100 {
0101     MessageViewer::EventEdit edit;
0102     QSignalSpy spy(&edit, &MessageViewer::EventEdit::messageChanged);
0103     KMime::Message::Ptr msg(new KMime::Message);
0104     edit.setMessage(msg);
0105     QCOMPARE(spy.count(), 1);
0106     QCOMPARE(spy.at(0).at(0).value<KMime::Message::Ptr>(), msg);
0107 }
0108 
0109 void EventEditTest::shouldNotEmitWhenCollectionIsNotChanged()
0110 {
0111     MessageViewer::EventEdit edit;
0112     edit.setCollection(Akonadi::Collection(42));
0113     QSignalSpy spy(&edit, &MessageViewer::EventEdit::collectionChanged);
0114     edit.setCollection(Akonadi::Collection(42));
0115     QCOMPARE(spy.count(), 0);
0116 }
0117 
0118 void EventEditTest::shouldNotEmitWhenMessageIsNotChanged()
0119 {
0120     MessageViewer::EventEdit edit;
0121     KMime::Message::Ptr msg(new KMime::Message);
0122     edit.setMessage(msg);
0123     QSignalSpy spy(&edit, &MessageViewer::EventEdit::messageChanged);
0124     edit.setMessage(msg);
0125     QCOMPARE(spy.count(), 0);
0126 }
0127 
0128 void EventEditTest::shouldEmitEventWhenPressEnter()
0129 {
0130     MessageViewer::EventEdit edit;
0131     edit.show();
0132     // make sure the window is active so we can test for focus
0133     edit.activateWindow();
0134     QVERIFY(QTest::qWaitForWindowExposed(&edit));
0135     QVERIFY(edit.isVisible());
0136 
0137     KMime::Message::Ptr msg(new KMime::Message);
0138     QString subject = QStringLiteral("Test Note");
0139     msg->subject(true)->fromUnicodeString(subject, "us-ascii");
0140     edit.setMessage(msg);
0141     auto eventedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0142     eventedit->setFocus();
0143     QSignalSpy spy(&edit, &MessageViewer::EventEdit::createEvent);
0144     QTest::keyClick(eventedit, Qt::Key_Enter);
0145     QCOMPARE(spy.count(), 1);
0146 }
0147 
0148 void EventEditTest::shouldHideWidgetWhenPressEnter()
0149 {
0150     MessageViewer::EventEdit edit;
0151     edit.show();
0152     QVERIFY(QTest::qWaitForWindowExposed(&edit));
0153     QVERIFY(edit.isVisible());
0154 
0155     KMime::Message::Ptr msg(new KMime::Message);
0156     QString subject = QStringLiteral("Test Note");
0157     msg->subject(true)->fromUnicodeString(subject, "us-ascii");
0158     edit.setMessage(msg);
0159     auto eventedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0160     QTest::keyClick(eventedit, Qt::Key_Enter);
0161     QCOMPARE(edit.isVisible(), false);
0162 }
0163 
0164 void EventEditTest::shouldHideWidgetWhenPressEscape()
0165 {
0166     MessageViewer::EventEdit edit;
0167     edit.show();
0168     // make sure the window is active so we can test for focus
0169     edit.activateWindow();
0170     QVERIFY(QTest::qWaitForWindowExposed(&edit));
0171     auto eventedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0172     eventedit->setFocus();
0173     QVERIFY(eventedit->hasFocus());
0174     QTest::keyPress(&edit, Qt::Key_Escape);
0175     QCOMPARE(edit.isVisible(), false);
0176 }
0177 
0178 void EventEditTest::shouldHideWidgetWhenSaveClicked()
0179 {
0180     MessageViewer::EventEdit edit;
0181     edit.show();
0182     QVERIFY(QTest::qWaitForWindowExposed(&edit));
0183 
0184     KMime::Message::Ptr msg(new KMime::Message);
0185     msg->subject(true)->fromUnicodeString(QStringLiteral("Test Note"), "us-ascii");
0186     edit.setMessage(msg);
0187     auto save = edit.findChild<QPushButton *>(QStringLiteral("save-button"));
0188     QTest::mouseClick(save, Qt::LeftButton);
0189     QCOMPARE(edit.isVisible(), false);
0190 }
0191 
0192 void EventEditTest::shouldSaveCollectionSettings()
0193 {
0194     MessageViewer::EventEdit edit;
0195     edit.show();
0196     QVERIFY(QTest::qWaitForWindowExposed(&edit));
0197     auto akonadicombobox = edit.findChild<Akonadi::CollectionComboBox *>(QStringLiteral("akonadicombobox"));
0198     akonadicombobox->setCurrentIndex(3);
0199     const Akonadi::Collection::Id id = akonadicombobox->currentCollection().id();
0200     auto close = edit.findChild<QPushButton *>(QStringLiteral("close-button"));
0201     QTest::mouseClick(close, Qt::LeftButton);
0202     QCOMPARE(MessageViewer::MessageViewerSettingsBase::self()->lastEventSelectedFolder(), id);
0203 }
0204 
0205 void EventEditTest::shouldSaveCollectionSettingsWhenCloseWidget()
0206 {
0207     MessageViewer::EventEdit edit;
0208     edit.show();
0209     QVERIFY(QTest::qWaitForWindowExposed(&edit));
0210     auto akonadicombobox = edit.findChild<Akonadi::CollectionComboBox *>(QStringLiteral("akonadicombobox"));
0211     akonadicombobox->setCurrentIndex(4);
0212     const Akonadi::Collection::Id id = akonadicombobox->currentCollection().id();
0213     edit.writeConfig();
0214     QCOMPARE(MessageViewer::MessageViewerSettingsBase::self()->lastEventSelectedFolder(), id);
0215 }
0216 
0217 void EventEditTest::shouldSaveCollectionSettingsWhenDeleteWidget()
0218 {
0219     auto edit = new MessageViewer::EventEdit;
0220     auto akonadicombobox = edit->findChild<Akonadi::CollectionComboBox *>(QStringLiteral("akonadicombobox"));
0221     akonadicombobox->setCurrentIndex(5);
0222     const Akonadi::Collection::Id id = akonadicombobox->currentCollection().id();
0223     delete edit;
0224     QCOMPARE(MessageViewer::MessageViewerSettingsBase::self()->lastEventSelectedFolder(), id);
0225 }
0226 
0227 void EventEditTest::shouldNotEmitCreateEventWhenDateIsInvalid()
0228 {
0229     MessageViewer::EventEdit edit;
0230     KMime::Message::Ptr msg(new KMime::Message);
0231 
0232     auto startDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("startdatetimeedit"));
0233     startDateTime->setDateTime(QDateTime());
0234 
0235     auto endDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("enddatetimeedit"));
0236     endDateTime->setDateTime(QDateTime());
0237 
0238     QString subject = QStringLiteral("Test Note");
0239     msg->subject(true)->fromUnicodeString(subject, "us-ascii");
0240     edit.setMessage(msg);
0241     auto eventedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0242     QSignalSpy spy(&edit, &MessageViewer::EventEdit::createEvent);
0243     QTest::keyClick(eventedit, Qt::Key_Enter);
0244     QCOMPARE(spy.count(), 0);
0245 }
0246 
0247 void EventEditTest::shouldEventHasCorrectSubject()
0248 {
0249     MessageViewer::EventEdit edit;
0250     KMime::Message::Ptr msg(new KMime::Message);
0251     QString subject = QStringLiteral("Test Note");
0252     msg->subject(true)->fromUnicodeString(subject, "us-ascii");
0253     edit.setMessage(msg);
0254     auto noteedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0255     QVERIFY(noteedit);
0256     QSignalSpy spy(&edit, &MessageViewer::EventEdit::createEvent);
0257     QTest::keyClick(noteedit, Qt::Key_Enter);
0258     QCOMPARE(spy.count(), 1);
0259     auto eventPtr = spy.at(0).at(0).value<KCalendarCore::Event::Ptr>();
0260     QVERIFY(eventPtr);
0261     QCOMPARE(eventPtr->summary(), subject);
0262 }
0263 
0264 void EventEditTest::shouldSelectLineWhenPutMessage()
0265 {
0266     MessageViewer::EventEdit edit;
0267     KMime::Message::Ptr msg(new KMime::Message);
0268     QString subject = QStringLiteral("Test Note");
0269     msg->subject(true)->fromUnicodeString(subject, "us-ascii");
0270     edit.setMessage(msg);
0271     auto noteedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0272     QVERIFY(noteedit);
0273     QVERIFY(noteedit->hasSelectedText());
0274     const QString selectedText = noteedit->selectedText();
0275     QCOMPARE(selectedText, subject);
0276 }
0277 
0278 void EventEditTest::shouldHaveCorrectStartEndDateTime()
0279 {
0280     MessageViewer::EventEdit edit;
0281     KMime::Message::Ptr msg(new KMime::Message);
0282     QString subject = QStringLiteral("Test Note");
0283     msg->subject(true)->fromUnicodeString(subject, "us-ascii");
0284     edit.setMessage(msg);
0285 
0286     QDateTime currentDateTime = QDateTime::currentDateTime();
0287     auto startDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("startdatetimeedit"));
0288     startDateTime->setDateTime(currentDateTime);
0289 
0290     QDateTime endDt = currentDateTime.addDays(1);
0291     auto endDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("enddatetimeedit"));
0292     endDateTime->setDateTime(endDt);
0293 
0294     auto noteedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0295     QVERIFY(noteedit);
0296     QSignalSpy spy(&edit, &MessageViewer::EventEdit::createEvent);
0297     QTest::keyClick(noteedit, Qt::Key_Enter);
0298     QCOMPARE(spy.count(), 1);
0299     auto eventPtr = spy.at(0).at(0).value<KCalendarCore::Event::Ptr>();
0300     QVERIFY(eventPtr);
0301     QCOMPARE(eventPtr->dtStart().date(), currentDateTime.date());
0302     QCOMPARE(eventPtr->dtStart().time().hour(), currentDateTime.time().hour());
0303     QCOMPARE(eventPtr->dtStart().time().minute(), currentDateTime.time().minute());
0304 
0305     QCOMPARE(eventPtr->dtEnd().date(), endDt.date());
0306     QCOMPARE(eventPtr->dtEnd().time().hour(), endDt.time().hour());
0307     QCOMPARE(eventPtr->dtEnd().time().minute(), endDt.time().minute());
0308 }
0309 
0310 void EventEditTest::shouldSetFocusWhenWeCallTodoEdit()
0311 {
0312     MessageViewer::EventEdit edit;
0313     edit.show();
0314     // make sure the window is active so we can test for focus
0315     edit.activateWindow();
0316     QVERIFY(QTest::qWaitForWindowExposed(&edit));
0317     auto noteedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0318     QVERIFY(noteedit);
0319     edit.setFocus();
0320     edit.showEventEdit();
0321     QVERIFY(noteedit->hasFocus());
0322 }
0323 
0324 void EventEditTest::shouldEnsureEndDateIsNotBeforeStartDate()
0325 {
0326     MessageViewer::EventEdit edit;
0327     auto startDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("startdatetimeedit"));
0328     auto endDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("enddatetimeedit"));
0329 
0330     QDateTime startDt = startDateTime->dateTime();
0331     QVERIFY(startDt < endDateTime->dateTime());
0332 
0333     startDt.setTime(QTime(5, 12));
0334     endDateTime->setDateTime(startDt.addSecs(3600));
0335     startDt = startDt.addDays(1);
0336     startDateTime->setDateTime(startDt);
0337     QCOMPARE(startDt.date(), endDateTime->date());
0338     QVERIFY(startDt.time() < endDateTime->time());
0339 
0340     startDt = startDt.addSecs(2 * 3600);
0341     startDateTime->setDateTime(startDt);
0342     QCOMPARE(startDt.time(), endDateTime->time());
0343 }
0344 
0345 void EventEditTest::shouldEnabledSaveOpenEditorButton()
0346 {
0347     MessageViewer::EventEdit edit;
0348     KMime::Message::Ptr msg(new KMime::Message);
0349     msg->subject(true)->fromUnicodeString(QStringLiteral("Test note"), "us-ascii");
0350     edit.setMessage(msg);
0351 
0352     auto noteedit = edit.findChild<QLineEdit *>(QStringLiteral("eventedit"));
0353     QVERIFY(noteedit);
0354     auto openEditor = edit.findChild<QPushButton *>(QStringLiteral("open-editor-button"));
0355     auto save = edit.findChild<QPushButton *>(QStringLiteral("save-button"));
0356     QCOMPARE(openEditor->isEnabled(), true);
0357     QCOMPARE(save->isEnabled(), true);
0358     noteedit->clear();
0359 
0360     QCOMPARE(openEditor->isEnabled(), false);
0361     QCOMPARE(save->isEnabled(), false);
0362 
0363     noteedit->setText(QStringLiteral(" "));
0364     QCOMPARE(openEditor->isEnabled(), false);
0365     QCOMPARE(save->isEnabled(), false);
0366 
0367     noteedit->setText(QStringLiteral(" foo"));
0368     QCOMPARE(openEditor->isEnabled(), true);
0369     QCOMPARE(save->isEnabled(), true);
0370 }
0371 
0372 void EventEditTest::shouldUpdateStartEndDateWhenReopenIt()
0373 {
0374     MessageViewer::EventEdit edit;
0375     KMime::Message::Ptr msg(new KMime::Message);
0376     msg->subject(true)->fromUnicodeString(QStringLiteral("Test note"), "us-ascii");
0377     edit.setMessage(msg);
0378 
0379     QDateTime currentDateTime = QDateTime::currentDateTime();
0380     auto startDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("startdatetimeedit"));
0381     QCOMPARE(startDateTime->dateTime().date(), currentDateTime.date());
0382     QCOMPARE(startDateTime->dateTime().time().hour(), currentDateTime.time().hour());
0383     QCOMPARE(startDateTime->dateTime().time().minute(), currentDateTime.time().minute());
0384 
0385     auto endDateTime = edit.findChild<MessageViewer::EventDateTimeWidget *>(QStringLiteral("enddatetimeedit"));
0386     auto endTime = currentDateTime.addSecs(3600);
0387     QCOMPARE(endDateTime->dateTime().date(), endTime.date());
0388     QCOMPARE(endDateTime->dateTime().time().hour(), endTime.time().hour());
0389     QCOMPARE(endDateTime->dateTime().time().minute(), endTime.time().minute());
0390 
0391     QDateTime newDateTime = currentDateTime;
0392     newDateTime = newDateTime.addSecs(60 * 60); //+1h
0393     startDateTime->setDateTime(newDateTime);
0394     endDateTime->setDateTime(newDateTime);
0395 
0396     QCOMPARE(startDateTime->dateTime().time().hour(), newDateTime.time().hour());
0397     QCOMPARE(startDateTime->dateTime().time().minute(), newDateTime.time().minute());
0398     QCOMPARE(startDateTime->dateTime().date(), newDateTime.date());
0399 
0400     QCOMPARE(endDateTime->dateTime().time().hour(), newDateTime.time().hour());
0401     QCOMPARE(endDateTime->dateTime().time().minute(), newDateTime.time().minute());
0402     QCOMPARE(endDateTime->dateTime().date(), newDateTime.date());
0403 
0404     edit.slotCloseWidget();
0405 
0406     edit.showEventEdit();
0407     QCOMPARE(startDateTime->dateTime().date(), currentDateTime.date());
0408     QCOMPARE(startDateTime->dateTime().time().hour(), currentDateTime.time().hour());
0409     QCOMPARE(startDateTime->dateTime().time().minute(), currentDateTime.time().minute());
0410 
0411     QCOMPARE(endDateTime->dateTime().date(), endTime.date());
0412     QCOMPARE(endDateTime->dateTime().time().hour(), endTime.time().hour());
0413     QCOMPARE(endDateTime->dateTime().time().minute(), endTime.time().minute());
0414 }
0415 
0416 void EventEditTest::shouldDisabledSaveOpenEditorButtonWhenCollectionComboBoxIsEmpty()
0417 {
0418     MessageViewer::EventEdit edit;
0419     auto akonadicombobox = edit.findChild<Akonadi::CollectionComboBox *>(QStringLiteral("akonadicombobox"));
0420     // Create an empty combobox
0421     akonadicombobox->setModel(new QStandardItemModel());
0422     KMime::Message::Ptr msg(new KMime::Message);
0423     msg->subject(true)->fromUnicodeString(QStringLiteral("Test note"), "us-ascii");
0424     edit.setMessage(msg);
0425 
0426     auto openEditor = edit.findChild<QPushButton *>(QStringLiteral("open-editor-button"));
0427     auto save = edit.findChild<QPushButton *>(QStringLiteral("save-button"));
0428     QCOMPARE(openEditor->isEnabled(), false);
0429     QCOMPARE(save->isEnabled(), false);
0430 }
0431 
0432 QTEST_MAIN(EventEditTest)
0433 
0434 #include "moc_eventedittest.cpp"