Files
yourls-ui/tests/yourlsclient_test.cpp
T
2026-10-01 12:21:40 -04:00

79 lines
4.0 KiB
C++

#include "../yourlsclient.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QSignalSpy>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTest>
#include <QUrlQuery>
class YourlsClientTest : public QObject {
Q_OBJECT
private slots:
void responses_data() {
QTest::addColumn<int>("httpStatus");
QTest::addColumn<QString>("status");
QTest::addColumn<QString>("code");
QTest::addColumn<QString>("originalUrl");
QTest::addColumn<QString>("shortUrl");
QTest::addColumn<bool>("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"