File indexing completed on 2024-04-14 04:36:48
0001 /* 0002 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <KPublicTransport/Journey> 0008 #include <KPublicTransport/JourneyReply> 0009 #include <KPublicTransport/JourneyRequest> 0010 #include <KPublicTransport/Location> 0011 #include <KPublicTransport/LocationReply> 0012 #include <KPublicTransport/LocationRequest> 0013 #include <KPublicTransport/Manager> 0014 #include <KPublicTransport/Stopover> 0015 #include <KPublicTransport/StopoverReply> 0016 #include <KPublicTransport/StopoverRequest> 0017 0018 #include <QDir> 0019 #include <QSignalSpy> 0020 #include <QStandardPaths> 0021 #include <QtTest> 0022 0023 using namespace KPublicTransport; 0024 0025 class QueryTest : public QObject 0026 { 0027 Q_OBJECT 0028 private: 0029 Location loc(const char *name, float lat, float lon) const 0030 { 0031 Location l; 0032 l.setName(QString::fromUtf8(name)); 0033 l.setCoordinate(lat, lon); 0034 return l; 0035 } 0036 0037 static bool hasRealtimeJourneyData(const std::vector<Journey> &journeys) { 0038 return std::any_of(journeys.begin(), journeys.end(), [](const auto &jny) { 0039 return std::any_of(jny.sections().begin(), jny.sections().end(), [](const auto &sec) { 0040 return sec.hasExpectedDepartureTime() || sec.hasExpectedArrivalTime() || sec.hasExpectedDeparturePlatform() || sec.hasExpectedArrivalPlatform(); 0041 }); 0042 }); 0043 } 0044 0045 static constexpr const auto TIMEOUT = 60000; 0046 0047 KPublicTransport::Manager m_ptMgr; 0048 0049 private Q_SLOTS: 0050 void initTestCase() 0051 { 0052 QStandardPaths::setTestModeEnabled(true); 0053 QDir(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)).removeRecursively(); 0054 0055 m_ptMgr.setAllowInsecureBackends(true); 0056 } 0057 0058 void testBackend_data() 0059 { 0060 QTest::addColumn<QString>("backend"); 0061 QTest::addColumn<Location>("loc1"); 0062 QTest::addColumn<Location>("loc2"); 0063 0064 // international 0065 // TODO un_gbfs - this needs special-casing given it cannot do journey and departure searches 0066 QTest::newRow("un_navitia") << "un_navitia" << loc("Paris Gare de Lyon", 48.84444, 2.37412) << loc("Paris Aéroport Charles de Gaulle 2 TGV", 49.00423, 2.57215); 0067 QTest::newRow("au_navitia") << "au_navitia" << loc("King George Square Station", -27.468903869, 153.0242799) << loc("Brisbane International Airport", -27.404467, 153.108597); 0068 0069 // national 0070 QTest::newRow("at_oebb") << "at_oebb" << loc("Wien Hauptbahnhof", 48.18282, 16.37859) << loc("Linz/Donau Hbf", 48.29058, 14.29018); 0071 QTest::newRow("be_sncb") << "be_sncb" << loc("Bruxelles Midi", 50.83604, 4.33679) << loc("Mechelen", 51.01745, 4.48336); 0072 QTest::newRow("ch_opentransportdata") << "ch_opentransportdata" << loc("Zürich Flughafen", 47.45, 8.561) << loc("Randa", 46.09982, 7.78149); 0073 // endpoint defunct 0074 // QTest::newRow("ch_sbb") << "ch_sbb" << loc("Zürich Flughafen", 47.45015, 8.56199 ) << loc("Randa", 46.09982, 7.78149); 0075 QTest::newRow("de_db") << "de_db" << loc("Berlin Hauptbahnhof", 52.52509, 13.36946) << loc("Frankfurt Hbf", 50.10675, 8.66281); 0076 QTest::newRow("dk_dsb") << "dk_dsb" << loc("København H", 55.67228, 12.56442) << loc("Københavns Lufthavn Kastrup", 55.62940, 12.64872); 0077 QTest::newRow("ee_peatus") << "ee_peatus" << loc("Tallinn Hobujaama", 59.43727, 24.75824) << loc("Pärnu", 58.37254, 24.55502); 0078 QTest::newRow("eu_railteam") << "eu_railteam" << loc("Bruxelles Midi", 50.8353, 4.33679) << loc("Amsterdam Centraal", 52.37923, 4.90055); 0079 QTest::newRow("fi_digitransit") << "fi_digitransit" << loc("Helsinki", 60.17174, 24.94148) << loc("Espoo", 60.20530, 24.65748); 0080 QTest::newRow("fi_waltti") << "fi_waltti" << loc("Helsinki", 60.17174, 24.94148) << loc("Tampere", 61.49859, 23.77392); 0081 QTest::newRow("fr_sncf") << "fr_sncf" << loc("Paris Gare de Lyon", 48.84444, 2.37412) << loc("Paris Aéroport Charles de Gaulle 2 TGV", 49.00423, 2.57215); 0082 QTest::newRow("gb_traveline") << "gb_traveline" << loc( "London Euston", 51.52814, -0.13365) << loc("Glasgow Queen Street", 55.86252, -4.25074); 0083 QTest::newRow("ie_tfi") << "ie_tfi" << loc("Dublin Connolly", 53.35258, -6.24706) << loc("Cork Kent", 51.90159, -8.45823); 0084 QTest::newRow("lu_cfl") << "lu_cfl" << loc("Luxembourg Gare Centrale", 49.59962, 6.13473) << loc("Ettelbruck", 49.84745, 6.10645); 0085 QTest::newRow("nl_ns") << "nl_ns" << loc("Amsterdam Centraal", 52.37923, 4.90055) << loc("Den Haag Centraal", 52.08108, 4.32406); 0086 QTest::newRow("no_entur") << "no_entur" << loc("Oslo", 59.91157, 10.75413) << loc("Bergen", 60.39033, 5.33396); 0087 QTest::newRow("pl_pkp") << "pl_pkp" << loc("Warszawa Centralna", 52.228862, 21.00323295) << loc("Gdańsk Główny", 54.35625, 18.64417); 0088 QTest::newRow("se_resrobot") << "se_resrobot" << loc("Stockholm Central", 59.32976, 18.05715) << loc("Göteborgs centralstation", 57.70913, 11.97321); 0089 // TODO tn_sncft 0090 0091 // local 0092 QTest::newRow("at_3_vor") << "at_3_vor" << loc("Wien Hauptbahnhof", 48.185184, 16.37641) << loc("Wien Flughafen", 48.12012, 16.56441); 0093 QTest::newRow("at_4_linz") << "at_4_linz" << loc("Linz/Donau Hbf", 48.29007, 14.29207) << loc("Hörsching", 48.24549, 14.18587); 0094 QTest::newRow("at_4_ooevv") << "at_4_ooevv" << loc("Linz/Donau Hbf", 48.29058, 14.29018) << loc("Hörsching", 48.24549, 14.18587); 0095 QTest::newRow("at_5_svv") << "at_5_svv" << loc("Salzburg Hbf", 47.81285, 13.04592) << loc("Freilassing", 47.83690, 12.97673); 0096 QTest::newRow("at_6_vvst") << "at_6_vvst" << loc("Graz Hauptbahnhof", 47.07236, 15.41665) << loc("Bruck an der Mur", 47.41413, 15.28000); 0097 QTest::newRow("at_7_vvt") << "at_7_vvt" << loc("Innsbruck Hbf", 47.26289, 11.40163) << loc("Kufstein", 47.58308, 12.16626); 0098 QTest::newRow("at_8_vvv") << "at_8_vvv" << loc("Bregenz", 47.50307, 9.74019) << loc("Dornbirn", 47.413280, 9.743741); 0099 QTest::newRow("at_9_wien") << "at_9_wien" << loc("Wien Hauptbahnhof", 48.18282, 16.37859) << loc("Wien Praterstern", 48.21870, 16.39247); 0100 0101 QTest::newRow("au_nsw") << "au_nsw" << loc("Sydney Central", -33.88315, 151.20587) << loc("Sydney Internation Airport", -33.93503, 151.16603); 0102 0103 QTest::newRow("ch_zh_zvv") << "ch_zh_zvv" << loc("Zürich Flughafen", 47.45015, 8.56199 ) << loc("Zürich HB", 47.37833, 8.53912); 0104 0105 QTest::newRow("de_bb_bbnavi_angermuende") << "de_bb_bbnavi_angermuende" << loc("Angermünde", 53.01579, 13.99634) << loc("Schwedt", 53.06298, 14.29054); 0106 QTest::newRow("de_bb_vbb") << "de_bb_vbb" << loc("Berlin Hauptbahnhof", 52.52509, 13.36946) << loc("Berlin Alexanderplatz", 52.52147, 13.41134); 0107 QTest::newRow("de_be_bvg") << "de_be_bvg" << loc("Berlin Hauptbahnhof", 52.52509, 13.36946) << loc("Berlin Alexanderplatz", 52.52147, 13.41134); 0108 QTest::newRow("de_bw_bwegt") << "de_bw_bwegt" << loc("Stuttgart Hbf", 48.78539, 9.18345) << loc("Herrenberg", 48.59392, 8.86275); 0109 QTest::newRow("de_bw_kvv") << "de_bw_kvv" << loc("Karlsruhe Hbf", 48.99342, 8.40173 ) << loc("Ettlingen Stadt", 48.93867, 8.40953); 0110 QTest::newRow("de_bw_stadtnavi") << "de_bw_stadtnavi" << loc("Stuttgart Hbf", 48.78539, 9.18345) << loc("Herrenberg", 48.59392, 8.86275); 0111 QTest::newRow("de_bw_ulm") << "de_bw_ulm" << loc("Ulm Hbf", 48.39946, 9.98302) << loc("Neu Ulm", 48.39330, 10.00520); 0112 QTest::newRow("de_bw_vvs") << "de_bw_vvs" << loc("Stuttgart Hbf", 48.78539, 9.18345) << loc("Herrenberg", 48.59392, 8.86275); 0113 QTest::newRow("de_by_bayern") << "de_by_bayern" << loc("München Hbf", 48.14046, 11.55819) << loc("Nürnberg Hbf", 49.44559, 11.08219); 0114 QTest::newRow("de_by_invg") << "de_by_invg" << loc("Ingolstadt Hbf", 48.74436, 11.43746) << loc("Ingolstadt Nord", 48.77350, 11.43251); 0115 QTest::newRow("de_by_mvv") << "de_by_mvv" << loc("München Hbf", 48.14046, 11.55819) << loc("Isartor", 48.13375, 11.58303); 0116 QTest::newRow("de_by_vgn") << "de_by_vgn" << loc("Erlangen", 49.59591, 11.00220) << loc("Nürnberg Hbf", 49.44559, 11.08219); 0117 QTest::newRow("de_he_nvv") << "de_he_nvv" << loc("Kassel Hbf", 51.31836, 9.48946) << loc("Kassel Wilhelmshöhe", 51.31137, 9.44827); 0118 QTest::newRow("de_he_rmv") << "de_he_rmv" << loc("Frankfurt Hbf", 50.10675, 8.66281) << loc("Frankfurt Flughafen Regionalbf", 50.05129, 8.57170); 0119 QTest::newRow("de_hh_hvv") << "de_hh_hvv" << loc("Hamburg Hauptbahnhof", 53.55299, 10.00702) << loc("Hamburg Altona", 53.55284, 9.93569); 0120 QTest::newRow("de_mv_rsag") << "de_mv_rsag" << loc("Rostock Hauptbahnhof", 54.07814, 12.13206) << loc("Warnemünde Bahnhof", 54.17695, 12.09069); 0121 QTest::newRow("de_mv_vmv") << "de_mv_vmv" << loc("Rostock Hauptbahnhof", 54.07814, 12.13206) << loc("Stralsund Hbf", 54.30766, 13.07931); 0122 QTest::newRow("de_ni_efa") << "de_ni_efa" << loc("Hannover Hbf", 52.37715, 9.74171) << loc("Bremen Hbf", 53.08322, 8.81388); 0123 QTest::newRow("de_ni_gvh") << "de_ni_gvh" << loc("Hannover Hbf", 52.37715, 9.74171) << loc("Bremen Hbf", 53.08322, 8.81388); 0124 QTest::newRow("de_ni_vbn") << "de_ni_vbn" << loc("Hannover Hbf", 52.37715, 9.74171) << loc("Bremen Hbf", 53.08322, 8.81388); 0125 QTest::newRow("de_ni_vsn") << "de_ni_vsn" << loc("Osnabrück Hbf",52.27280, 8.06136) << loc("Göttingen", 51.53676, 9.92626); 0126 QTest::newRow("de_nw_avv") << "de_nw_avv" << loc("Aachen Hbf", 50.76784, 6.09130) << loc("Aachen West", 50.78025, 6.07124); 0127 // TODO de_nw_muenster 0128 QTest::newRow("de_nw_vrr") << "de_nw_vrr" << loc("Düsseldorf Hbf", 51.21991, 6.79419) << loc("Essen Hbf", 51.45127, 7.01388); 0129 QTest::newRow("de_nw_vrs") << "de_nw_vrs" << loc("Köln Hbf", 50.94305, 6.95908) << loc("Bonn Hbf", 50.73203, 7.09719); 0130 QTest::newRow("de_nw_zks") << "de_nw_zks" << loc("Düsseldorf Hbf", 51.21991, 6.79419) << loc("Essen Hbf", 51.45127, 7.01388); 0131 QTest::newRow("de_rp_rolph") << "de_rp_rolph" << loc("Mainz Hbf", 50.00113, 8.25865) << loc("Kaiserslautern Hauptbahnhof", 49.43607, 7.76849); 0132 QTest::newRow("de_rp_vrn") << "de_rp_vrn" << loc("Kaiserslautern Hauptbahnhof", 49.43607, 7.76849) << loc("Mannheim Hauptbahnhof", 49.47930, 8.46947); 0133 QTest::newRow("de_rp_vrt") << "de_rp_vrt" << loc("Trier Hauptbahnhof", 49.75687, 6.65245) << loc("Wittlich Hauptbahnhof", 49.97306, 6.94357); 0134 QTest::newRow("de_sh_sh") << "de_sh_sh" << loc("Hamburg Hauptbahnhof", 53.55299, 10.00702) << loc("Hamburg-Altona", 53.55284, 9.93569); 0135 QTest::newRow("de_sl_saarvv") << "de_sl_saarvv" << loc("Saarbrücken Hauptbahnhof", 49.24116, 6.99110) << loc("Saarlouis Hbf", 49.32766, 6.75103); 0136 QTest::newRow("de_sn_vvo") << "de_sn_vvo" << loc("Dresden Hbf", 51.04025, 13.73160) << loc("Chemnitz Hauptbahnhof", 50.83981, 12.93069); 0137 QTest::newRow("de_st_insa") << "de_st_insa" << loc("Leipzig Hbf", 51.34508, 12.38196) << loc("Leipzig S Bahnhof Messe", 51.39603, 12.38987); 0138 QTest::newRow("de_th_vmt") << "de_th_vmt" << loc("Erfurt Hbf", 50.97227, 11.03790) << loc("Jena Paradies", 50.92491, 11.58725); 0139 0140 QTest::newRow("fi_17_helsinki") << "fi_17_helsinki" << loc("Helsinki", 60.17174, 24.94148) << loc("Espoo", 60.20530, 24.65748); 0141 0142 QTest::newRow("fr_ara_metromobilite") << "fr_ara_metromobilite" << loc("Grenoble", 45.19140, 5.71449) << loc("Échorolles", 45.15272, 5.71976); 0143 0144 // TODO it_21_piemonte 0145 QTest::newRow("it_21_torino") << "it_21_torino" << loc("Torino Porta Nuova", 45.06098, 7.67777) << loc("Torino Dora GTT", 45.09068, 7.67700); 0146 0147 QTest::newRow("us_ca_bart") << "us_ca_bart" << loc("San Francisco International Airport (SFO)", 37.61622, -122.39180) << loc("San Francisco Powell Street", 37.78441, -122.40767); 0148 QTest::newRow("us_ca_la_metro") << "us_ca_la_metro" << loc("Los Angeles Union Station", 34.05563, -118.23407) << loc("South Pasadena", 34.11518, -118.15811); 0149 QTest::newRow("us_ga_marta") << "us_ga_marta" << loc("Five Points", 33.75390, -84.39140) << loc("Airport", 33.64084, -84.44637); 0150 // TODO us_il_chicago 0151 QTest::newRow("us_ma_mbta") << "us_ma_mbta" << loc("Boston South Station", 42.35057, -71.05535) << loc("Boston North Station", 42.36696, -71.06263); 0152 // TODO us_or_trimet 0153 QTest::newRow("us_tx_cmta") << "us_tx_cmta" << loc("Downtown", 30.26487, -97.73928) << loc("crestview", 30.33921, -97.71968); 0154 } 0155 0156 void testBackend() 0157 { 0158 QFETCH(QString, backend); 0159 QFETCH(Location, loc1); 0160 QFETCH(Location, loc2); 0161 0162 // location search by name 0163 { 0164 LocationRequest req; 0165 req.setBackendIds({backend}); 0166 req.setName(loc1.name()); 0167 auto reply = m_ptMgr.queryLocation(req); 0168 QSignalSpy spy(reply, &LocationReply::finished); 0169 QVERIFY(spy.wait(TIMEOUT)); 0170 QCOMPARE(spy.size(), 1); 0171 QEXPECT_FAIL("us_ga_marta", "needs investigation", Continue); 0172 QCOMPARE(reply->error(), Reply::NoError); 0173 QEXPECT_FAIL("us_ga_marta", "needs investigation", Continue); 0174 QCOMPARE(reply->errorString(), QString()); 0175 QEXPECT_FAIL("fr_ara_metromobilite", "needs investigation", Continue); 0176 QEXPECT_FAIL("it_21_torino", "needs investigation", Continue); 0177 QEXPECT_FAIL("us_ga_marta", "needs investigation", Continue); 0178 QVERIFY(reply->result().size() > 0); 0179 const auto results = reply->takeResult(); 0180 if (!results.empty()) { 0181 // sanity check the result, should be close enough to where we expect it 0182 // there can be valid deviations of a few km due to lack of precision in our test data and 0183 // the use of fairly large objects like airports 0184 const auto d = Location::distance(loc1.latitude(), loc1.longitude(), results[0].latitude(), results[0].longitude()); 0185 QVERIFY(std::isnan(d) || d < 10'000); 0186 } 0187 } 0188 0189 // location search by coordinate 0190 { 0191 LocationRequest req; 0192 req.setBackendIds({backend}); 0193 req.setCoordinate(loc2.latitude(), loc2.longitude()); 0194 req.setMaximumResults(1); 0195 auto reply = m_ptMgr.queryLocation(req); 0196 QSignalSpy spy(reply, &LocationReply::finished); 0197 QVERIFY(spy.wait(TIMEOUT)); 0198 QCOMPARE(reply->error(), Reply::NoError); 0199 QCOMPARE(reply->errorString(), QString()); 0200 QCOMPARE(spy.size(), 1); 0201 QEXPECT_FAIL("at_6_vvst", "needs investigation", Continue); 0202 QEXPECT_FAIL("fr_ara_metromobilite", "needs investigation", Continue); 0203 QVERIFY(reply->result().size() > 0); 0204 } 0205 0206 // departure by name 0207 { 0208 StopoverRequest req; 0209 req.setBackendIds({backend}); 0210 Location loc; 0211 loc.setName(loc2.name()); 0212 req.setStop(loc); 0213 auto reply = m_ptMgr.queryStopover(req); 0214 QSignalSpy spy(reply, &StopoverReply::finished); 0215 QVERIFY(spy.wait(TIMEOUT)); 0216 QEXPECT_FAIL("no_entur", "name-based location search returns null results?!", Continue); 0217 QEXPECT_FAIL("it_21_torino", "needs investigation", Continue); 0218 QEXPECT_FAIL("us_ca_la_metro", "needs investigation", Continue); 0219 QEXPECT_FAIL("us_ga_marta", "needs investigation", Continue); 0220 QEXPECT_FAIL("us_ma_mbta", "needs investigation", Continue); 0221 QCOMPARE(reply->error(), Reply::NoError); 0222 QEXPECT_FAIL("no_entur", "name-based location search returns null results?!", Continue); 0223 QEXPECT_FAIL("it_21_torino", "needs investigation", Continue); 0224 QEXPECT_FAIL("us_ca_la_metro", "needs investigation", Continue); 0225 QEXPECT_FAIL("us_ga_marta", "needs investigation", Continue); 0226 QEXPECT_FAIL("us_ma_mbta", "needs investigation", Continue); 0227 QCOMPARE(reply->errorString(), QString()); 0228 QCOMPARE(spy.size(), 1); 0229 QEXPECT_FAIL("no_entur", "name-based location search returns null results?!", Continue); 0230 QEXPECT_FAIL("fr_ara_metromobilite", "needs investigation", Continue); 0231 QEXPECT_FAIL("it_21_torino", "needs investigation", Continue); 0232 QEXPECT_FAIL("us_ca_la_metro", "needs investigation", Continue); 0233 QEXPECT_FAIL("us_ga_marta", "needs investigation", Continue); 0234 QEXPECT_FAIL("us_ma_mbta", "needs investigation", Continue); 0235 QVERIFY(reply->result().size() > 0); 0236 } 0237 0238 // departure by coordinate 0239 { 0240 StopoverRequest req; 0241 req.setBackendIds({backend}); 0242 Location loc; 0243 loc.setCoordinate(loc1.latitude(), loc1.longitude()); 0244 req.setStop(loc); 0245 auto reply = m_ptMgr.queryStopover(req); 0246 QSignalSpy spy(reply, &StopoverReply::finished); 0247 QVERIFY(spy.wait(TIMEOUT)); 0248 QCOMPARE(reply->error(), Reply::NoError); 0249 QCOMPARE(reply->errorString(), QString()); 0250 QCOMPARE(spy.size(), 1); 0251 QEXPECT_FAIL("at_3_vor", "needs investigation", Continue); 0252 QEXPECT_FAIL("at_4_ooevv", "needs investigation", Continue); 0253 QEXPECT_FAIL("at_8_vvv", "needs investigation", Continue); 0254 QEXPECT_FAIL("fr_ara_metromobilite", "needs investigation", Continue); 0255 QEXPECT_FAIL("pl_pkp", "needs investigation", Continue); 0256 QEXPECT_FAIL("us_ca_la_metro", "needs investigation", Continue); 0257 QEXPECT_FAIL("us_ma_mbta", "needs investigation", Continue); 0258 QVERIFY(reply->result().size() > 0); 0259 } 0260 0261 // journey 0262 { 0263 JourneyRequest req; 0264 req.setBackendIds({backend}); 0265 req.setFrom(loc1); 0266 req.setTo(loc2); 0267 req.setMaximumResults(1); 0268 auto reply = m_ptMgr.queryJourney(req); 0269 QSignalSpy spy(reply, &JourneyReply::finished); 0270 QVERIFY(spy.wait(TIMEOUT)); 0271 QCOMPARE(reply->error(), Reply::NoError); 0272 QCOMPARE(reply->errorString(), QString()); 0273 QCOMPARE(spy.size(), 1); 0274 QVERIFY(reply->result().size() > 0); 0275 qDebug() << "Journey realtime data:" << hasRealtimeJourneyData(reply->result()); 0276 } 0277 } 0278 }; 0279 0280 QTEST_GUILESS_MAIN(QueryTest) 0281 0282 #include "querytest.moc"