#include "../yourlsclient.h" #include #include #include #include #include #include #include class YourlsClientTest : public QObject { Q_OBJECT private slots: void responses_data() { QTest::addColumn("httpStatus"); QTest::addColumn("status"); QTest::addColumn("code"); QTest::addColumn("originalUrl"); QTest::addColumn("shortUrl"); QTest::addColumn("success"); const QString source = QStringLiteral("https://git.himro.ca/explore/repos?q=a%26b&next=x+y#section"); const QString shortened = QStringLiteral("https://cut.himro.ca/h"); QTest::newRow("created") << 200 << "success" << "" << source << shortened << true; QTest::newRow("duplicate") << 400 << "fail" << "error:url" << source << shortened << true; QTest::newRow("different-url") << 400 << "fail" << "error:url" << "https://example.com" << shortened << false; QTest::newRow("missing-short-url") << 400 << "fail" << "error:url" << source << "" << false; QTest::newRow("relative-short-url") << 400 << "fail" << "error:url" << source << "/h" << false; QTest::newRow("other-error") << 400 << "fail" << "error:auth" << source << shortened << false; QTest::newRow("server-error") << 500 << "fail" << "error:url" << source << shortened << false; } void responses() { QFETCH(int, httpStatus); QFETCH(QString, status); QFETCH(QString, code); QFETCH(QString, originalUrl); QFETCH(QString, shortUrl); QFETCH(bool, success); QTcpServer server; QVERIFY(server.listen(QHostAddress::LocalHost)); QByteArray requestData; const QByteArray body = QJsonDocument(QJsonObject{ {"status", status}, {"code", code}, {"shorturl", shortUrl}, {"url", QJsonObject{{"url", originalUrl}}}}) .toJson(QJsonDocument::Compact); connect(&server, &QTcpServer::newConnection, this, [&]() { auto *socket = server.nextPendingConnection(); connect(socket, &QTcpSocket::readyRead, &server, [&, socket]() { requestData += socket->readAll(); if (!requestData.contains("\r\n\r\n")) return; socket->write("HTTP/1.1 " + QByteArray::number(httpStatus) + " Result\r\nContent-Type: application/json\r\nContent-Length: " + QByteArray::number(body.size()) + "\r\nConnection: close\r\n\r\n" + body); socket->disconnectFromHost(); }); }); YourlsClient client; QSignalSpy succeeded(&client, &YourlsClient::shortenSucceeded); QSignalSpy failed(&client, &YourlsClient::shortenFailed); const QUrl source(QStringLiteral("https://git.himro.ca/explore/repos?q=a%26b&next=x+y#section")); client.shortenUrl({QStringLiteral("http://127.0.0.1:%1/api").arg(server.serverPort()), QStringLiteral("test-signature")}, source); QTRY_COMPARE(succeeded.count() + failed.count(), 1); QCOMPARE(succeeded.count(), success ? 1 : 0); if (success) QCOMPARE(succeeded.first().first().toUrl(), QUrl(shortUrl)); const QByteArray target = requestData.split(' ').value(1); const QUrlQuery query(QUrl::fromEncoded(target)); // Decode the HTTP query once, as the server does, preserving URL escapes. const QString encodedValue = query.queryItemValue(QStringLiteral("url"), QUrl::FullyEncoded); QCOMPARE(QUrl::fromPercentEncoding(encodedValue.toLatin1()), source.toString(QUrl::FullyEncoded)); } }; QTEST_GUILESS_MAIN(YourlsClientTest) #include "yourlsclient_test.moc"