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 }