Commit 701db76d authored by Glen Ditchfield's avatar Glen Ditchfield 🐛
Browse files

Detect invalid start and end times

If the user enters an invalid string such as "25:00" into the start time field
or the end/due time field, IncidenceDateTime does not detect it, because the
QDateTime constructor used by currentStartDateTime() and currentEndDateTime()
treats it as "00:00".

This patch
 * detects and reports the error,
 * uses more specific error messages,
 * focuses on the erroneous field, and
 * logs at "debug" level, because the problem isn't very big.

CCBUG: 409912
parent 18855591
Pipeline #39227 passed with stage
in 13 minutes and 26 seconds
......@@ -58,3 +58,17 @@ target_link_libraries(testindividualmaildialog
KF5::WidgetsAddons
KF5::I18n
)
add_executable(incidencedatetimetest incidencedatetimetest.cpp
../src/combinedincidenceeditor.cpp
../src/incidencedatetime.cpp
../src/incidenceeditor_debug.cpp)
add_test(NAME incidencedatetimetest COMMAND incidencedatetimetest)
ecm_mark_as_test(incidencedatetimetest)
target_link_libraries(incidencedatetimetest
Qt5::Test
Qt5::Widgets
KF5::Completion
KF5::IncidenceEditor
KF5::WidgetsAddons
)
/*
SPDX-FileCopyrightText: 2020 Glen Ditchfield <GJDitchfield@acm.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <QObject>
#include <QTest>
#include "combinedincidenceeditor.h"
#include "incidencedatetime.h"
#include "incidencedialog.h"
#include "ui_dialogdesktop.h"
using namespace IncidenceEditorNG;
class IncidenceDateTimeTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testStartTimeValidation()
{
QLocale currentLocale;
QLocale::setDefault(QLocale::c());
Akonadi::Item item;
KCalendarCore::Event::Ptr event(new KCalendarCore::Event);
item.setPayload<KCalendarCore::Event::Ptr>(event);
auto *dialog = new IncidenceDialog();
dialog->load(item);
// Put the dialog into a known, valid state.
auto editor = dialog->findChild<IncidenceEditor *>();
QVERIFY2(editor, "Couldn't find the combined editor.");
QCOMPARE(editor->metaObject()->className(), "IncidenceEditorNG::CombinedIncidenceEditor");
auto allDay = dialog->findChild<QCheckBox *>(QStringLiteral("mWholeDayCheck"));
QVERIFY2(allDay, "Couldn't find the 'All Day' checkbox.");
allDay->setCheckState(Qt::Unchecked);
auto startCheck = dialog->findChild<QCheckBox *>(QStringLiteral("mStartCheck"));
QVERIFY2(startCheck, "Couldn't find the 'Start' checkbox.");
startCheck->setCheckState(Qt::Checked);
auto endCheck = dialog->findChild<QCheckBox *>(QStringLiteral("mEndCheck"));
QVERIFY2(endCheck, "Couldn't find the 'End' checkbox.");
endCheck->setCheckState(Qt::Checked);
auto title = dialog->findChild<QLineEdit *>(QStringLiteral("mSummaryEdit"));
QVERIFY2(title, "Couldn't find the 'Title' field.");
title->setText(QStringLiteral("e"));
QVERIFY(editor->isValid());
auto startDate = dialog->findChild<KDateComboBox *>(QStringLiteral("mStartDateEdit"));
QVERIFY2(startDate, "Couldn't find start date field.");
startDate->setCurrentText(QStringLiteral("32 Jan 2000"));
QVERIFY2(!editor->isValid(), "Didn't detect invalid start date.");
startDate->setCurrentText(QStringLiteral("12 Jan 2000"));
QVERIFY(editor->isValid());
auto startTime = dialog->findChild<KTimeComboBox *>(QStringLiteral("mStartTimeEdit"));
QVERIFY2(startTime, "Couldn't find start time field.");
startTime->setCurrentText(QStringLiteral("12:99:00"));
QVERIFY2(!editor->isValid(), "Didn't detect invalid start time.");
startTime->setCurrentText(QStringLiteral("12:00:00"));
QVERIFY(editor->isValid());
auto endDate = dialog->findChild<KDateComboBox *>(QStringLiteral("mEndDateEdit"));
QVERIFY2(endDate, "Couldn't find end date field.");
endDate->setCurrentText(QStringLiteral("33 Jan 2000"));
QVERIFY2(!editor->isValid(), "Didn't detect invalid end date.");
endDate->setCurrentText(QStringLiteral("13 Jan 2000"));
QVERIFY(editor->isValid());
auto endTime = dialog->findChild<KTimeComboBox *>(QStringLiteral("mEndTimeEdit"));
QVERIFY2(endTime, "Couldn't find end time field.");
endTime->setCurrentText(QStringLiteral("12:99:00"));
QVERIFY2(!editor->isValid(), "Didn't detect invalid end time.");
endTime->setCurrentText(QStringLiteral("12:00:00"));
QVERIFY(editor->isValid());
endDate->setDate(startDate->date());
endTime->setTime(startTime->time().addSecs(-60));
QVERIFY2(!editor->isValid(), "Didn't detect end date & time < start date & time");
endTime->setTime(startTime->time());
QVERIFY(editor->isValid());
QLocale::setDefault(currentLocale);
}
};
QTEST_MAIN(IncidenceDateTimeTest)
#include "incidencedatetimetest.moc"
......@@ -886,20 +886,65 @@ bool IncidenceDateTime::endDateTimeEnabled() const
return mUi->mEndCheck->isChecked();
}
void IncidenceDateTime::focusInvalidField()
{
if (startDateTimeEnabled()) {
if (!mUi->mStartDateEdit->isValid()) {
mUi->mStartDateEdit->setFocus();
return;
}
if (!mUi->mWholeDayCheck->isChecked() && !mUi->mStartTimeEdit->isValid()) {
mUi->mStartTimeEdit->setFocus();
return;
}
}
if (endDateTimeEnabled()) {
if (!mUi->mEndDateEdit->isValid()) {
mUi->mEndDateEdit->setFocus();
return;
}
if (!mUi->mWholeDayCheck->isChecked() && !mUi->mEndTimeEdit->isValid()) {
mUi->mEndTimeEdit->setFocus();
return;
}
}
if (startDateTimeEnabled() && endDateTimeEnabled()
&& currentStartDateTime() > currentEndDateTime()) {
if (mUi->mEndDateEdit->date() < mUi->mStartDateEdit->date()) {
mUi->mEndDateEdit->setFocus();
} else {
mUi->mEndTimeEdit->setFocus();
}
}
}
bool IncidenceDateTime::isValid() const
{
if (startDateTimeEnabled() && !currentStartDateTime().isValid()) {
mLastErrorString = i18nc("@info",
"Invalid start date and time.");
qCWarning(INCIDENCEEDITOR_LOG) << "Start date is invalid";
return false;
if (startDateTimeEnabled()) {
if (!mUi->mStartDateEdit->isValid()) {
mLastErrorString = i18nc("@info", "Invalid start date.");
qCDebug(INCIDENCEEDITOR_LOG) << mLastErrorString;
return false;
}
if (!mUi->mWholeDayCheck->isChecked() && !mUi->mStartTimeEdit->isValid()) {
mLastErrorString = i18nc("@info", "Invalid start time.");
qCDebug(INCIDENCEEDITOR_LOG) << mLastErrorString;
return false;
}
}
if (endDateTimeEnabled() && !currentEndDateTime().isValid()) {
mLastErrorString = i18nc("@info",
"Invalid end date and time.");
qCWarning(INCIDENCEEDITOR_LOG) << "End date is invalid";
return false;
if (endDateTimeEnabled()) {
if (!mUi->mEndDateEdit->isValid()) {
mLastErrorString = i18nc("@info", "Invalid end date.");
qCDebug(INCIDENCEEDITOR_LOG) << mLastErrorString;
return false;
}
if (!mUi->mWholeDayCheck->isChecked() && !mUi->mEndTimeEdit->isValid()) {
mLastErrorString = i18nc("@info", "Invalid end time.");
qCDebug(INCIDENCEEDITOR_LOG) << mLastErrorString;
return false;
}
}
if (startDateTimeEnabled() && endDateTimeEnabled()
......
......@@ -56,6 +56,8 @@ public:
Q_REQUIRED_RESULT bool startDateTimeEnabled() const;
Q_REQUIRED_RESULT bool endDateTimeEnabled() const;
void focusInvalidField() override;
Q_REQUIRED_RESULT bool isValid() const override;
void printDebugInfo() const override;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment