File indexing completed on 2024-04-28 04:42:40

0001 /*
0002     SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include <KWeatherCore/CAPAlertInfo>
0007 #include <KWeatherCore/CAPAlertMessage>
0008 #include <KWeatherCore/CAPArea>
0009 #include <KWeatherCore/CAPParser>
0010 #include <KWeatherCore/CAPReference>
0011 
0012 #include <QFile>
0013 #include <QTest>
0014 
0015 class CapParserTest : public QObject
0016 {
0017     Q_OBJECT
0018 private Q_SLOTS:
0019     void testParseCap()
0020     {
0021         QFile f(QFINDTESTDATA("capdata/thunderstorm.xml"));
0022         QVERIFY(f.open(QFile::ReadOnly));
0023         KWeatherCore::CAPParser parser(f.readAll());
0024         auto alert = parser.parse();
0025 
0026         QCOMPARE(alert.status(), KWeatherCore::CAPAlertMessage::Status::Actual);
0027         QCOMPARE(alert.messageType(), KWeatherCore::CAPAlertMessage::MessageType::Alert);
0028         QCOMPARE(alert.identifier(), QLatin1String("KSTO1055887203"));
0029         QCOMPARE(alert.sender(), QLatin1String("KSTO@NWS.NOAA.GOV"));
0030         QCOMPARE(alert.sentTime(), QDateTime({2003, 06, 17}, {14, 57}, Qt::OffsetFromUTC, -7 * 60 * 60));
0031         QCOMPARE(alert.scope(), KWeatherCore::CAPAlertMessage::Scope::Public);
0032         QCOMPARE(alert.note(), QString());
0033 
0034         QCOMPARE(alert.alertInfos().size(), 1);
0035         const auto &info = alert.alertInfos()[0];
0036 
0037         QCOMPARE(info.event(), QLatin1String("SEVERE THUNDERSTORM"));
0038         QCOMPARE(info.effectiveTime(), QDateTime());
0039         QCOMPARE(info.onsetTime(), QDateTime());
0040         QCOMPARE(info.expireTime(), QDateTime({2003, 06, 17}, {16, 0}, Qt::OffsetFromUTC, -7 * 60 * 60));
0041         QCOMPARE(info.headline(), QLatin1String("SEVERE THUNDERSTORM WARNING"));
0042         QCOMPARE(info.description().isEmpty(), false);
0043         QCOMPARE(info.instruction().isEmpty(), false);
0044         QCOMPARE(info.sender(), QLatin1String("NATIONAL WEATHER SERVICE SACRAMENTO CA"));
0045         QCOMPARE(info.language(), QLatin1String("en-US"));
0046         QCOMPARE(info.categories(), KWeatherCore::CAPAlertInfo::Category::Meteorological);
0047         QCOMPARE(info.urgency(), KWeatherCore::CAPAlertInfo::Urgency::Immediate);
0048         QCOMPARE(info.severity(), KWeatherCore::CAPAlertInfo::Severity::Severe);
0049         QCOMPARE(info.certainty(), KWeatherCore::CAPAlertInfo::Certainty::Observed);
0050         QCOMPARE(info.responseTypes(), KWeatherCore::CAPAlertInfo::ResponseType::Shelter);
0051         QCOMPARE(info.contact(), QLatin1String("BARUFFALDI/JUSKIE"));
0052 
0053         QCOMPARE(info.areas().size(), 1);
0054         const auto area = info.areas()[0];
0055         QCOMPARE(area.description(),
0056                  QLatin1String("EXTREME NORTH CENTRAL TUOLUMNE COUNTY IN CALIFORNIA, EXTREME NORTHEASTERN CALAVERAS COUNTY IN CALIFORNIA, SOUTHWESTERN ALPINE "
0057                                "COUNTY IN CALIFORNIA"));
0058         QCOMPARE(area.polygons().size(), 1);
0059         QCOMPARE(area.polygons()[0].size(), 5);
0060         QCOMPARE(area.geoCodes().size(), 3);
0061         QCOMPARE(area.geoCodes()[0].name, QLatin1String("SAME"));
0062         QCOMPARE(area.geoCodes()[0].value, QLatin1String("006109"));
0063         QCOMPARE(area.geoCodes()[1].name, QLatin1String("SAME"));
0064         QCOMPARE(area.geoCodes()[1].value, QLatin1String("006009"));
0065 
0066         QCOMPARE(info.eventCodes().size(), 1);
0067         QCOMPARE(info.eventCodes()[0].name, QLatin1String("SAME"));
0068         QCOMPARE(info.eventCodes()[0].value, QLatin1String("SVR"));
0069     }
0070 
0071     void testMultiArea()
0072     {
0073         QFile f(QFINDTESTDATA("capdata/multi-area.xml"));
0074         QVERIFY(f.open(QFile::ReadOnly));
0075         KWeatherCore::CAPParser parser(f.readAll());
0076         auto alert = parser.parse();
0077 
0078         QCOMPARE(alert.status(), KWeatherCore::CAPAlertMessage::Status::Actual);
0079         QCOMPARE(alert.messageType(), KWeatherCore::CAPAlertMessage::MessageType::Alert);
0080         QCOMPARE(alert.sender(), QLatin1String("vigilance@meteo.fr"));
0081         QCOMPARE(alert.sentTime(), QDateTime({2022, 8, 10}, {16, 12, 20}, Qt::OffsetFromUTC, +2 * 60 * 60));
0082 
0083         QCOMPARE(alert.alertInfos().size(), 2);
0084         auto info = alert.alertInfos()[0];
0085         QCOMPARE(info.language(), QLatin1String("fr-FR"));
0086         QCOMPARE(info.responseTypes(), KWeatherCore::CAPAlertInfo::ResponseType::Monitor);
0087         QCOMPARE(info.web(), QLatin1String("http://vigilance.meteofrance.com/"));
0088         QCOMPARE(info.areas().size(), 4);
0089         auto area = info.areas()[3];
0090         QCOMPARE(area.description(), QLatin1String("Haute Garonne"));
0091         QCOMPARE(area.polygons().size(), 0);
0092         QCOMPARE(area.geoCodes().size(), 1);
0093         QCOMPARE(area.geoCodes()[0].name, QLatin1String("NUTS3"));
0094         QCOMPARE(area.geoCodes()[0].value, QLatin1String("FR623"));
0095 
0096         info = alert.alertInfos()[1];
0097         QCOMPARE(info.language(), QLatin1String("en-GB"));
0098         QCOMPARE(info.parameters().size(), 2);
0099         QCOMPARE(info.parameters()[1].name, QLatin1String("awareness_type"));
0100         QCOMPARE(info.parameters()[1].value, QLatin1String("3; Thunderstorm"));
0101         QCOMPARE(info.areas().size(), 4);
0102         area = info.areas()[0];
0103         QCOMPARE(area.description(), QLatin1String("Alpes de Haute Provence"));
0104         QCOMPARE(area.polygons().size(), 0);
0105         QCOMPARE(area.geoCodes().size(), 1);
0106         QCOMPARE(area.geoCodes()[0].name, QLatin1String("NUTS3"));
0107         QCOMPARE(area.geoCodes()[0].value, QLatin1String("FR821"));
0108     }
0109 
0110     void testCircleArea()
0111     {
0112         QFile f(QFINDTESTDATA("capdata/tsunami.xml"));
0113         QVERIFY(f.open(QFile::ReadOnly));
0114         KWeatherCore::CAPParser parser(f.readAll());
0115         auto alert = parser.parse();
0116 
0117         QCOMPARE(alert.status(), KWeatherCore::CAPAlertMessage::Status::Actual);
0118         QCOMPARE(alert.messageType(), KWeatherCore::CAPAlertMessage::MessageType::Alert);
0119         QCOMPARE(alert.sender(), QLatin1String("ntwc@noaa.gov"));
0120         QCOMPARE(alert.sentTime(), QDateTime({2022, 8, 01}, {0, 40, 48}, Qt::OffsetFromUTC, 0));
0121 
0122         QCOMPARE(alert.alertInfos().size(), 1);
0123         auto info = alert.alertInfos()[0];
0124         QCOMPARE(info.language(), QLatin1String("en-US"));
0125         QCOMPARE(info.areas().size(), 1);
0126         auto area = info.areas()[0];
0127         QCOMPARE(area.polygons().size(), 0);
0128         QCOMPARE(area.circles().size(), 1);
0129         auto circle = area.circles()[0];
0130         QCOMPARE(circle.latitude, 53.401f);
0131         QCOMPARE(circle.longitude, -165.164f);
0132         QCOMPARE(circle.radius, 1.0f);
0133     }
0134 
0135     void testPolygon()
0136     {
0137         QFile f(QFINDTESTDATA("capdata/polygon-trailing-space.xml"));
0138         QVERIFY(f.open(QFile::ReadOnly));
0139         KWeatherCore::CAPParser parser(f.readAll());
0140         auto alert = parser.parse();
0141 
0142         QCOMPARE(alert.status(), KWeatherCore::CAPAlertMessage::Status::Actual);
0143         QCOMPARE(alert.messageType(), KWeatherCore::CAPAlertMessage::MessageType::Alert);
0144         QCOMPARE(alert.sender(), QLatin1String("info.aviso@inmet.gov.br"));
0145         QCOMPARE(alert.sentTime(), QDateTime({2022, 8, 12}, {13, 22, 45}, Qt::OffsetFromUTC, -3 * 60 * 60));
0146 
0147         QCOMPARE(alert.alertInfos().size(), 1);
0148         auto info = alert.alertInfos()[0];
0149         QCOMPARE(info.language(), QLatin1String("pt-BR"));
0150         QCOMPARE(info.areas().size(), 1);
0151         auto area = info.areas()[0];
0152         QCOMPARE(area.polygons().size(), 1);
0153         auto polygon = area.polygons()[0];
0154         QCOMPARE(polygon.size(), 10);
0155         for (const auto &p : polygon) {
0156             QVERIFY(p.latitude != 0.0f);
0157             QVERIFY(p.longitude != 0.0f);
0158         }
0159     }
0160 
0161     void testReferences()
0162     {
0163         QFile f(QFINDTESTDATA("capdata/dwd-update.xml"));
0164         QVERIFY(f.open(QFile::ReadOnly));
0165         KWeatherCore::CAPParser parser(f.readAll());
0166         auto alert = parser.parse();
0167 
0168         QCOMPARE(alert.status(), KWeatherCore::CAPAlertMessage::Status::Actual);
0169         QCOMPARE(alert.messageType(), KWeatherCore::CAPAlertMessage::MessageType::Update);
0170         QCOMPARE(alert.references().size(), 1);
0171         auto ref = alert.references()[0];
0172         QCOMPARE(ref.sender(), QLatin1String("opendata@dwd.de"));
0173         QCOMPARE(ref.identifier(), QLatin1String("2.49.0.0.276.0.DWD.PVW.1661542140000.7462e657-ce54-473f-91c8-abe408afe703.MUL"));
0174         QCOMPARE(ref.sent(), QDateTime({2022, 8, 26}, {21, 29}, Qt::OffsetFromUTC, 2 * 60 * 60));
0175 
0176         ref = alert.ownReference();
0177         QCOMPARE(ref.sender(), QLatin1String("opendata@dwd.de"));
0178         QCOMPARE(ref.identifier(), QLatin1String("2.49.0.0.276.0.DWD.PVW.1661544180000.6ffa85ac-a5ed-4e69-977c-e767a423ecd6.MUL"));
0179         QCOMPARE(ref.sent(), QDateTime({2022, 8, 26}, {22, 3}, Qt::OffsetFromUTC, 2 * 60 * 60));
0180 
0181         QCOMPARE(alert.alertInfos().size(), 1);
0182         const auto info = alert.alertInfos()[0];
0183         QCOMPARE(info.areas().size(), 2);
0184         const auto area = info.areas()[0];
0185         QCOMPARE(area.altitude(), 0.0f);
0186         QCOMPARE(area.ceiling(), 9842.5197f);
0187     }
0188 };
0189 
0190 QTEST_GUILESS_MAIN(CapParserTest)
0191 
0192 #include "capparsertest.moc"