File indexing completed on 2024-04-28 05:19:53

0001 /*
0002  * SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #include "testutils.h"
0008 #include "job.h"
0009 
0010 #include <QEventLoop>
0011 #include <QFile>
0012 #include <QJsonDocument>
0013 #include <QProcess>
0014 #include <QTemporaryFile>
0015 
0016 #include <iostream>
0017 
0018 bool execJob(KGAPI2::Job *job)
0019 {
0020     QEventLoop loop;
0021     QObject::connect(job, &KGAPI2::Job::finished, &loop, &QEventLoop::quit);
0022     return loop.exec() == 0;
0023 }
0024 
0025 FakeNetworkAccessManager::Scenario scenarioFromFile(const QString &requestFile, const QString &responseFile, bool needsAuth)
0026 {
0027     QFile request(requestFile);
0028     VERIFY_RET(request.open(QIODevice::ReadOnly), {});
0029 
0030     FakeNetworkAccessManager::Scenario scenario;
0031     auto http = request.readLine().trimmed();
0032     if (http.startsWith("PUT")) {
0033         scenario.requestMethod = QNetworkAccessManager::PutOperation;
0034         scenario.requestUrl = QUrl(QString::fromLatin1(http.constData() + 4));
0035     } else if (http.startsWith("POST")) {
0036         scenario.requestMethod = QNetworkAccessManager::PostOperation;
0037         scenario.requestUrl = QUrl(QString::fromLatin1(http.constData() + 5));
0038     } else if (http.startsWith("GET")) {
0039         scenario.requestMethod = QNetworkAccessManager::GetOperation;
0040         scenario.requestUrl = QUrl(QString::fromLatin1(http.constData() + 4));
0041     } else if (http.startsWith("DELETE")) {
0042         scenario.requestMethod = QNetworkAccessManager::DeleteOperation;
0043         scenario.requestUrl = QUrl(QString::fromLatin1(http.constData() + 7));
0044     } else if (http.startsWith("PATCH")) {
0045         scenario.requestMethod = QNetworkAccessManager::CustomOperation;
0046         scenario.requestUrl = QUrl(QString::fromLatin1(http.constData() + 6));
0047     } else {
0048         FAIL_RET("Invalid request method in test data", {});
0049     }
0050 
0051     auto line = request.readLine().trimmed();
0052     while (!line.isEmpty()) {
0053         const int idx = line.indexOf(':');
0054         scenario.requestHeaders.push_back(qMakePair(line.left(idx), line.mid(idx + 1).trimmed()));
0055 
0056         line = request.readLine().trimmed();
0057     }
0058     scenario.requestData = request.readAll();
0059 
0060     QFile response(responseFile);
0061     VERIFY_RET(response.open(QIODevice::ReadOnly), {});
0062 
0063     http = response.readLine();
0064     scenario.responseCode = http.mid(9, 3).toInt();
0065 
0066     line = response.readLine().trimmed();
0067     while (!line.isEmpty()) {
0068         const int idx = line.indexOf(':');
0069         scenario.responseHeaders.push_back(qMakePair(line.left(idx), line.mid(idx + 1).trimmed()));
0070 
0071         line = response.readLine().trimmed();
0072     }
0073     scenario.responseData = response.readAll();
0074     scenario.needsAuth = needsAuth;
0075 
0076     return scenario;
0077 }
0078 
0079 QByteArray reformatXML(const QByteArray &xml)
0080 {
0081 #ifdef Q_OS_UNIX
0082     QProcess lint;
0083     lint.start(QStringLiteral("xmllint"), {QStringLiteral("--format"), QStringLiteral("-")});
0084     lint.waitForStarted();
0085     if (lint.state() != QProcess::Running) { // missing xmllint?
0086         return xml;
0087     }
0088     if (!xml.startsWith("<?xml")) {
0089         lint.write("<?xml version=\"1.0\" ?>");
0090     }
0091     lint.write(xml);
0092     lint.closeWriteChannel();
0093     lint.waitForFinished();
0094     const auto err = lint.readAllStandardError();
0095     if (!err.isEmpty()) {
0096         std::cerr << err.constData() << std::endl;
0097         FAIL_RET("Malformed XML!", xml);
0098     }
0099     return lint.readAllStandardOutput();
0100 #else
0101     return xml;
0102 #endif
0103 }
0104 
0105 QByteArray reformatJSON(const QByteArray &json)
0106 {
0107     return QJsonDocument::fromJson(json).toJson(QJsonDocument::Indented);
0108 }
0109 
0110 QByteArray diffData(const QByteArray &actual, const QByteArray &expected)
0111 {
0112 #ifdef Q_OS_UNIX
0113     QTemporaryFile tmpActual(QStringLiteral("%1-actual.XXXXXX").arg(QCoreApplication::applicationName()));
0114     tmpActual.open();
0115     tmpActual.write(actual);
0116     tmpActual.close();
0117 
0118     QTemporaryFile tmpExpected(QStringLiteral("%1-expected.XXXXXX").arg(QCoreApplication::applicationName()));
0119     tmpExpected.open();
0120     tmpExpected.write(expected);
0121     tmpExpected.close();
0122 
0123     QProcess diff;
0124     diff.start(QStringLiteral("diff"), {QStringLiteral("-a"), QStringLiteral("-u"), tmpActual.fileName(), tmpExpected.fileName()});
0125     diff.waitForStarted();
0126     if (diff.state() != QProcess::Running) {
0127         return "======== ACTUAL ========\n\n" + actual + "\n\n"
0128                "======= EXPECTED =======\n\n" + expected + "\n\n"
0129                "========================";
0130     }
0131     diff.waitForFinished();
0132     return diff.readAll();
0133 #else
0134     return "======== ACTUAL ========\n\n" + actual + "\n\n"
0135            "======= EXPECTED =======\n\n" + expected + "\n\n"
0136            "========================";
0137 #endif
0138 }