File indexing completed on 2024-05-12 05:13:46

0001 /*
0002     SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include "testhelper.h"
0007 #include "passmanager.h"
0008 
0009 #include <KItinerary/JsonLdDocument>
0010 #include <KItinerary/ProgramMembership>
0011 #include <KItinerary/Ticket>
0012 
0013 #include <qtest.h>
0014 #include <QAbstractItemModelTester>
0015 #include <QJsonDocument>
0016 #include <QJsonObject>
0017 #include <QSignalSpy>
0018 #include <QStandardPaths>
0019 #include <QTemporaryFile>
0020 
0021 using namespace KItinerary;
0022 
0023 class PassManagerTest : public QObject
0024 {
0025     Q_OBJECT
0026 private Q_SLOTS:
0027     void initTestCase()
0028     {
0029         qputenv("TZ", "UTC");
0030         QStandardPaths::setTestModeEnabled(true);
0031     }
0032 
0033     void testPassManager()
0034     {
0035         PassManager mgr;
0036         QAbstractItemModelTester modelTest(&mgr);
0037 
0038         Test::clearAll(&mgr);
0039         QCOMPARE(mgr.rowCount(), 0);
0040 
0041         // test import
0042         QVERIFY(!mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/bahncard.json"))).object())).isEmpty());
0043         QVERIFY(!mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/9euroticket.json"))).object())).isEmpty());
0044         // duplicates get merged
0045         QVERIFY(!mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/9euroticket.json"))).object())).isEmpty());
0046         QCOMPARE(mgr.rowCount(), 2);
0047 
0048         // retrieval
0049         auto idx = mgr.index(0, 0);
0050         const auto passId = idx.data(PassManager::PassIdRole).toString();
0051         QVERIFY(!passId.isEmpty());
0052         const auto pass = idx.data(PassManager::PassRole);
0053         QVERIFY(!pass.isNull());
0054         QVERIFY(JsonLd::isA<ProgramMembership>(pass));
0055         QCOMPARE(idx.data(PassManager::PassTypeRole).toInt(), PassManager::ProgramMembership);
0056         QVERIFY(!idx.data(PassManager::PassDataRole).toByteArray().isEmpty());
0057         QCOMPARE(idx.data(PassManager::NameRole).toString(), QLatin1StringView("BahnCard 25 (2. Kl.) (BC25)"));
0058         QCOMPARE(idx.data(PassManager::ValidUntilRole).toDateTime(), QDateTime({2122, 3, 24}, {23, 59, 59}));
0059         QVERIFY(!idx.data(PassManager::SectionRole).toString().isEmpty());
0060         QVERIFY(!mgr.pass(passId).isNull());
0061 
0062         idx = mgr.index(1, 0);
0063         const auto passId2 = idx.data(PassManager::PassIdRole).toString();
0064         QVERIFY(!passId2.isEmpty());
0065         const auto ticket = idx.data(PassManager::PassRole);
0066         QVERIFY(!ticket.isNull());
0067         QVERIFY(JsonLd::isA<Ticket>(ticket));
0068         QCOMPARE(idx.data(PassManager::PassTypeRole).toInt(), PassManager::Ticket);
0069         QVERIFY(!idx.data(PassManager::PassDataRole).toByteArray().isEmpty());
0070         QCOMPARE(idx.data(PassManager::NameRole).toString(), QLatin1StringView("9-Euro-Ticket"));
0071         QCOMPARE(idx.data(PassManager::ValidUntilRole).toDateTime(), QDateTime({2022, 5, 31}, {23, 59, 59}));
0072         QVERIFY(!idx.data(PassManager::SectionRole).toString().isEmpty());
0073         QVERIFY(!mgr.pass(passId2).isNull());
0074 
0075         mgr.remove(passId2);
0076         QCOMPARE(mgr.rowCount(), 1);
0077 
0078 
0079 
0080         {
0081             // test persistence
0082             PassManager mgr2;
0083             QCOMPARE(mgr2.rowCount(), 1);
0084             auto idx = mgr2.index(0, 0);
0085             QCOMPARE(idx.data(PassManager::PassIdRole).toString(), passId);
0086             const auto pass = idx.data(PassManager::PassRole);
0087             QVERIFY(!pass.isNull());
0088             QVERIFY(JsonLd::isA<ProgramMembership>(pass));
0089         }
0090 
0091         // test removal
0092         QVERIFY(mgr.remove(passId));
0093         QCOMPARE(mgr.rowCount(), 0);
0094     }
0095 
0096     void testPassMatching_data()
0097     {
0098         QTest::addColumn<QString>("name");
0099         QTest::addColumn<QString>("number");
0100         QTest::addColumn<bool>("matches");
0101 
0102         QTest::newRow("empty") << QString() << QString() << false;
0103         QTest::newRow("generic-name") << QStringLiteral("BahnCard") << QString() << true;
0104         QTest::newRow("generic-name-case-mismatch") << QStringLiteral("Bahncard") << QString() << true;
0105         QTest::newRow("number-match") << QStringLiteral("BahnCard") << QStringLiteral("7081123456789012") << true;
0106         QTest::newRow("number-mismatch") << QStringLiteral("BahnCard") << QStringLiteral("7081123456789013") << false;
0107         QTest::newRow("name-mismatch") << QStringLiteral("CartaFRECCIA") << QString() << false;
0108         QTest::newRow("abbr-match") << QStringLiteral("BC25") << QString() << true;
0109         QTest::newRow("abbr-mismatch") << QStringLiteral("BC50") << QString() << false;
0110     }
0111 
0112     void testPassMatching()
0113     {
0114         QFETCH(QString, name);
0115         QFETCH(QString, number);
0116         QFETCH(bool, matches);
0117 
0118         PassManager mgr;
0119         Test::clearAll(&mgr);
0120         QVERIFY(!mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/bahncard.json"))).object())).isEmpty());
0121         const auto passId = mgr.index(0, 0).data(PassManager::PassIdRole).toString();
0122         QVERIFY(!passId.isEmpty());
0123 
0124         ProgramMembership program;
0125         program.setProgramName(name);
0126         program.setMembershipNumber(number);
0127         if (matches) {
0128             QCOMPARE(mgr.findMatchingPass(program), passId);
0129         } else {
0130             QCOMPARE(mgr.findMatchingPass(program), QString());
0131         }
0132     }
0133 
0134     void testPassUpdate()
0135     {
0136         PassManager mgr;
0137         QAbstractItemModelTester modelTest(&mgr);
0138         QSignalSpy updateSpy(&mgr, &PassManager::passChanged);
0139 
0140         Test::clearAll(&mgr);
0141         QCOMPARE(mgr.rowCount(), 0);
0142 
0143         const auto passId = mgr.import(JsonLdDocument::fromJsonSingular(QJsonDocument::fromJson(Test::readFile(QStringLiteral(SOURCE_DIR "/data/9euroticket.json"))).object()));
0144         QVERIFY(!passId.isEmpty());
0145 
0146         auto pass = mgr.pass(passId).value<Ticket>();
0147         QCOMPARE(pass.name(), QLatin1StringView("9-Euro-Ticket"));
0148         pass.setName(QLatin1StringView("9-Euro-Ticket (May 2022)"));
0149         mgr.update(passId, pass);
0150 
0151         QCOMPARE(updateSpy.size(), 1);
0152         QCOMPARE(updateSpy[0][0].toString(), passId);
0153 
0154         pass = mgr.pass(passId).value<Ticket>();
0155         QCOMPARE(pass.name(), QLatin1StringView("9-Euro-Ticket (May 2022)"));
0156     }
0157 };
0158 
0159 QTEST_GUILESS_MAIN(PassManagerTest)
0160 
0161 #include "passmanagertest.moc"