1 /*
2     SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "config-kitinerary.h"
8 
9 #include <KItinerary/ExtractorDocumentNode>
10 #include <KItinerary/ExtractorDocumentNodeFactory>
11 #include <KItinerary/ExtractorDocumentProcessor>
12 #include <KItinerary/ExtractorEngine>
13 #include <KItinerary/ExtractorResult>
14 #include <KItinerary/ScriptExtractor>
15 
16 #include <QDebug>
17 #include <QFile>
18 #include <QJsonDocument>
19 #include <QTest>
20 
21 using namespace KItinerary;
22 
23 #define s(x) QStringLiteral(x)
24 
initLocale()25 void initLocale()
26 {
27     qputenv("LC_ALL", "en_US.utf-8");
28     qputenv("TZ", "Europe/Brussels");
29 }
30 
Q_CONSTRUCTOR_FUNCTION(initLocale)31 Q_CONSTRUCTOR_FUNCTION(initLocale)
32 
33 static void expandRecursive(ExtractorDocumentNode &node, const ExtractorEngine *engine)
34 {
35     if (node.isNull()) {
36         return;
37     }
38     node.processor()->expandNode(node, engine);
39     for (auto child : node.childNodes()) {
40         expandRecursive(child, engine);
41     }
42 
43     node.processor()->preExtract(node, engine);
44 }
45 
46 class ExtractorScriptEngineTest : public QObject
47 {
48     Q_OBJECT
49 private Q_SLOTS:
testArguments_data()50     void testArguments_data()
51     {
52         QTest::addColumn<QString>("inputFile");
53         QTest::addColumn<QString>("refFile");
54 
55         QTest::newRow("text/plain") << s(SOURCE_DIR "/scriptenginedata/plain-text.txt") << s(SOURCE_DIR "/scriptenginedata/plain-text.txt.json");
56         QTest::newRow("pkpass") << s(SOURCE_DIR "/pkpassdata/swiss.pkpass") << s(SOURCE_DIR "/scriptenginedata/swiss.pkpass.json");
57         QTest::newRow("IATA BCBP PDF") << s(SOURCE_DIR "/extractordata/synthetic/iata-bcbp-demo.pdf")
58 #ifdef HAVE_ZXING
59             << s(SOURCE_DIR "/scriptenginedata/iata-bcbp-demo.pdf.json");
60 #else
61             << s(SOURCE_DIR "/scriptenginedata/iata-bcbp-demo.pdf-no-zxing.json");
62 #endif
63         QTest::newRow("ical") << s(SOURCE_DIR "/extractordata/ical/eventreservation.ics") << s(SOURCE_DIR "/scriptenginedata/eventreservation.ics.json");
64         QTest::newRow("uic9183") << s(SOURCE_DIR "/uic918-3/valid/Testw_VOW8XG6_A9E8DXL_0.bin") << s(SOURCE_DIR "/scriptenginedata/Testw_VOW8XG6_A9E8DXL_0.bin.json");
65         QTest::newRow("html") << s(SOURCE_DIR "/structureddata/google-flight-reservation-json-ld.html") << s(SOURCE_DIR "/scriptenginedata/google-flight-reservation-json-ld.html.json");
66     }
67 
testArguments()68     void testArguments()
69     {
70         QFETCH(QString, inputFile);
71         QFETCH(QString, refFile);
72 
73         QFile in(inputFile);
74         QVERIFY(in.open(QFile::ReadOnly));
75 
76         ExtractorEngine engine;
77         auto root = engine.documentNodeFactory()->createNode(in.readAll(), inputFile);
78         QVERIFY(!root.isNull());
79         expandRecursive(root, &engine);
80 
81         ScriptExtractor extractor;
82         extractor.setScriptFileName(s(":/reflector.js"));
83         extractor.setScriptFunction(s("dumpArgs"));
84         const auto result = extractor.extract(root, &engine).jsonLdResult();
85 
86         QFile ref(refFile);
87         QVERIFY(ref.open(QFile::ReadOnly));
88         const auto refResult = QJsonDocument::fromJson(ref.readAll()).array();
89 
90         if (result != refResult) {
91             qDebug().noquote() << QJsonDocument(result).toJson();
92         }
93         QCOMPARE(result, refResult);
94     }
95 
testInfiniteLoop()96     void testInfiniteLoop()
97     {
98         QFile in(s(SOURCE_DIR "/scriptenginedata/plain-text.txt"));
99         QVERIFY(in.open(QFile::ReadOnly));
100 
101         ExtractorEngine engine;
102         auto root = engine.documentNodeFactory()->createNode(in.readAll());
103         QVERIFY(!root.isNull());
104         expandRecursive(root, &engine);
105 
106         ScriptExtractor extractor;
107         extractor.setScriptFileName(s(":/buggy.js"));
108         extractor.setScriptFunction(s("infiniteLoop"));
109         const auto result = extractor.extract(root, &engine).jsonLdResult();
110     }
111 };
112 
113 QTEST_GUILESS_MAIN(ExtractorScriptEngineTest)
114 
115 #include "extractorscriptenginetest.moc"
116