Commit 8cf8bfb9 authored by Nicolas Fella's avatar Nicolas Fella
Browse files

Add unit test for contactmapper

Contactmapper is a complex piece, this helps with catching and debugging issues/regressions.

It currently tests phonenumber->kpeople URI resolution, but could be extended to do other checks in the future
parent fcc384e8
......@@ -12,6 +12,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
include(ECMAddTests)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
......@@ -51,6 +52,10 @@ install(FILES org.kde.phone.dialer.appdata.xml DESTINATION ${KDE_INSTALL_METAINF
add_subdirectory(src)
add_subdirectory(approver)
if (BUILD_TESTING)
add_subdirectory(autotests)
endif()
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h)
kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES})
kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT)
......
# SPDX-FileCopyrightText: 2021 Nicolas Fella <nicolas.fella@gmx.de>
# SPDX-License-Identifier: BSD-3-Clause
find_package(Qt5Test REQUIRED)
ecm_add_test(TEST_NAME contactmappertest contactmappertest.cpp fakecontactsource.cpp LINK_LIBRARIES Qt5::Test Qt5::Sql KF5::PeopleBackend dialer)
// SPDX-FileCopyrightText: 2021 Nicolas Fella <nicolas.fella@gmx.de>
//
// SPDX-License-Identifier: LicenseRef-KDE-Accepted-GPL
#include <QTest>
#include <QTemporaryFile>
#include "contactmapper.h"
#include "fakecontactsource.h"
#include <KPeople/PersonPluginManager>
#include <kpeopleprivate/personmanager_p.h>
class ContactMapperTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase()
{
QVERIFY(m_database.open());
// For this test we assume we are in Sweden and the implicit country code is +46
QLocale::setDefault(QLocale::Swedish);
// Called before the first testfunction is executed
PersonManager::instance(m_database.fileName());
m_source = new FakeContactSource(nullptr); // don't own. PersonPluginManager removes it on destruction
QHash<QString, KPeople::BasePersonsDataSource *> sources;
sources[QStringLiteral("fakesource")] = m_source;
KPeople::PersonPluginManager::setDataSourcePlugins(sources);
}
void testURI_data()
{
QTest::addColumn<QString>("number");
QTest::addColumn<QString>("uri");
QTest::newRow("nonexistant number") << QStringLiteral("+49123456") << QString();
QTest::newRow("contact 2, foreign country code") << QStringLiteral("+1 234 567 890") << QStringLiteral("fakesource://contact2");
QTest::newRow("contact 2, dashes") << QStringLiteral("+1-234-567-890") << QStringLiteral("fakesource://contact2");
QTest::newRow("contact 3") << QStringLiteral("+46 666 777 999") << QStringLiteral("fakesource://contact3");
QTest::newRow("contact 3, 00 instead of +") << QStringLiteral("0046 666 777 999") << QStringLiteral("fakesource://contact3");
QTest::newRow("contact 3, no spaces") << QStringLiteral("+46666777999") << QStringLiteral("fakesource://contact3");
QTest::newRow("contact 3, dashes") << QStringLiteral("+46-666-777-999") << QStringLiteral("fakesource://contact3");
QTest::newRow("contact 5, first number") << QStringLiteral("+46111222333") << QStringLiteral("fakesource://contact5");
QTest::newRow("contact 5, first number, no country code") << QStringLiteral("0111222333") << QStringLiteral("fakesource://contact5");
QTest::newRow("contact 5, second number") << QStringLiteral("+46333222111") << QStringLiteral("fakesource://contact5");
QTest::newRow("contact 5, second number, no country code") << QStringLiteral("0333222111") << QStringLiteral("fakesource://contact5");
QTest::newRow("invalid number") << QStringLiteral("+49yyy123456") << QString();
}
void testURI()
{
auto &mapper = ContactMapper::instance(true);
QFETCH(QString, number);
QFETCH(QString, uri);
QCOMPARE(mapper.uriForNumber(number), uri);
}
private:
FakeContactSource *m_source;
QTemporaryFile m_database;
};
QTEST_GUILESS_MAIN(ContactMapperTest)
#include "contactmappertest.moc"
/*
SPDX-FileCopyrightText: 2013 David Edmundson <davidedmundson@kde.org>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "fakecontactsource.h"
#include <QDebug>
FakeContactSource::FakeContactSource(QObject *parent, const QVariantList &args)
: BasePersonsDataSource(parent, args)
{
}
QString FakeContactSource::sourcePluginId() const
{
return QStringLiteral("fakesource://");
}
KPeople::AllContactsMonitor *FakeContactSource::createAllContactsMonitor()
{
return new FakeAllContactsMonitor();
}
void FakeContactSource::changeProperty(const QString &key, const QVariant &value)
{
qobject_cast<FakeAllContactsMonitor *>(allContactsMonitor().data())->changeProperty(key, value);
}
void FakeContactSource::remove(const QString &uri)
{
qobject_cast<FakeAllContactsMonitor *>(allContactsMonitor().data())->remove(uri);
}
class FakeContact : public KPeople::AbstractContact
{
public:
FakeContact(const QVariantMap &props)
: m_properties(props)
{
}
QVariant customProperty(const QString &key) const override
{
if (key == KPeople::AbstractContact::AllPhoneNumbersProperty) {
const QStringList allNumbers = m_properties[KPeople::AbstractContact::AllPhoneNumbersProperty].toStringList();
if (allNumbers.isEmpty()) {
return m_properties[KPeople::AbstractContact::PhoneNumberProperty];
}
return m_properties[KPeople::AbstractContact::AllPhoneNumbersProperty];
}
if (key.startsWith(QLatin1String("all-"))) {
return QStringList(m_properties[key.mid(4)].toString());
} else {
return m_properties[key];
}
}
QVariantMap m_properties;
};
FakeAllContactsMonitor::FakeAllContactsMonitor()
{
// clang-format off
m_contacts.insert(
QStringLiteral("fakesource://contact1"),
KPeople::AbstractContact::Ptr(new FakeContact({
{KPeople::AbstractContact::NameProperty, QStringLiteral("Contact 1")},
{KPeople::AbstractContact::EmailProperty, QStringLiteral("contact1@example.com")}
}))
);
m_contacts.insert(
QStringLiteral("fakesource://contact2"),
KPeople::AbstractContact::Ptr(new FakeContact({
{KPeople::AbstractContact::NameProperty, QStringLiteral("Contact 2")},
{KPeople::AbstractContact::EmailProperty, QStringLiteral("contact2@example.com")},
{KPeople::AbstractContact::PhoneNumberProperty, QStringLiteral("+1 234 567 890")}
}))
);
m_contacts.insert(
QStringLiteral("fakesource://contact3"),
KPeople::AbstractContact::Ptr(new FakeContact({{KPeople::AbstractContact::NameProperty, QStringLiteral("Contact 3")},
{KPeople::AbstractContact::EmailProperty, QStringLiteral("contact3@example.com")},
{KPeople::AbstractContact::PhoneNumberProperty, QStringLiteral("+46 666 777 999")}
}))
);
m_contacts.insert(
QStringLiteral("fakesource://contact4"),
KPeople::AbstractContact::Ptr(new FakeContact({
{KPeople::AbstractContact::NameProperty, QStringLiteral("Contact 4")},
{KPeople::AbstractContact::EmailProperty, QStringLiteral("contact4@example.com")},
{KPeople::AbstractContact::AllPhoneNumbersProperty, QStringList{QStringLiteral("+46-111-111-111")}}
}))
);
m_contacts.insert(
QStringLiteral("fakesource://contact5"),
KPeople::AbstractContact::Ptr(new FakeContact({
{KPeople::AbstractContact::NameProperty, QStringLiteral("Contact 5")},
{KPeople::AbstractContact::AllPhoneNumbersProperty, QVariantList{QStringLiteral("+46 111 222 333"), QStringLiteral("0 333 222 111")}}
}))
);
m_contacts.insert(
QStringLiteral("fakesource://contact6"),
KPeople::AbstractContact::Ptr(new FakeContact({
{KPeople::AbstractContact::NameProperty, QStringLiteral("Malory")},
{KPeople::AbstractContact::AllPhoneNumbersProperty, QVariantList{QStringLiteral("+46 111&222x333") /* Intentionally invalid */}}
}))
);
// clang-format on
emitInitialFetchComplete(true);
}
void FakeAllContactsMonitor::remove(const QString &uri)
{
m_contacts.remove(uri);
Q_EMIT contactRemoved(uri);
}
QMap<QString, KPeople::AbstractContact::Ptr> FakeAllContactsMonitor::contacts()
{
return m_contacts;
}
void FakeAllContactsMonitor::changeProperty(const QString &key, const QVariant &value)
{
KPeople::AbstractContact::Ptr contact1 = contacts()[QStringLiteral("fakesource://contact1")];
static_cast<FakeContact *>(contact1.data())->m_properties[key] = value;
Q_ASSERT(contact1->customProperty(key) == value);
Q_EMIT contactChanged(QStringLiteral("fakesource://contact1"), contact1);
}
/*
SPDX-FileCopyrightText: 2013 David Edmundson <davidedmundson@kde.org>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef FAKECONTACTSOURCE_H
#define FAKECONTACTSOURCE_H
#include <KPeopleBackend/AllContactsMonitor>
#include <KPeopleBackend/BasePersonsDataSource>
class FakeContactSource : public KPeople::BasePersonsDataSource
{
public:
FakeContactSource(QObject *parent, const QVariantList &args = QVariantList());
QString sourcePluginId() const override;
void remove(const QString &uri);
void changeProperty(const QString &key, const QVariant &value);
protected:
KPeople::AllContactsMonitor *createAllContactsMonitor() override;
};
class FakeAllContactsMonitor : public KPeople::AllContactsMonitor
{
Q_OBJECT
public:
explicit FakeAllContactsMonitor();
void changeProperty(const QString &key, const QVariant &value);
QMap<QString, KPeople::AbstractContact::Ptr> contacts() override;
void remove(const QString &uri);
private:
QMap<QString, KPeople::AbstractContact::Ptr> m_contacts;
};
#endif // FAKECONTACTSOURCE_H
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