Files
BiLauncher/tests/net/tst_fakeinternet.cpp
T

135 lines
5.7 KiB
C++
Raw Normal View History

2026-10-12 13:14:08 +03:00
// Самопроверка FakeInternet: если она красная, остальные сетевые тесты
// бессмысленны — значит, перехват трафика на этой платформе не работает.
#include "testenv.h"
#include "fakeinternet.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSignalSpy>
class TestFakeInternet : public QObject
{
Q_OBJECT
FakeInternet m_net;
QNetworkReply *get(QNetworkAccessManager &manager, const QString &url)
{
return manager.get(QNetworkRequest(QUrl(url)));
}
static bool waitFinished(QNetworkReply *reply)
{
if (reply->isFinished())
return true;
QSignalSpy spy(reply, &QNetworkReply::finished);
return spy.wait(15000);
}
private slots:
void initTestCase()
{
QString error;
if (!m_net.start(&error))
QSKIP(qPrintable(QStringLiteral("FakeInternet недоступен: ") + error));
}
void init() { m_net.reset(); }
void httpsGetIsIntercepted()
{
m_net.route(QStringLiteral("https://launchermeta.mojang.com/mc/game/version_manifest_v2.json"),
FakeResponse::json(QByteArrayLiteral("{\"ok\":true}")));
QNetworkAccessManager manager;
QScopedPointer<QNetworkReply> reply(
get(manager, QStringLiteral("https://launchermeta.mojang.com/mc/game/version_manifest_v2.json?x=1")));
QVERIFY(waitFinished(reply.data()));
QCOMPARE(reply->error(), QNetworkReply::NoError);
QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200);
QCOMPARE(reply->readAll(), QByteArrayLiteral("{\"ok\":true}"));
QCOMPARE(m_net.hits(QStringLiteral("https://launchermeta.mojang.com/mc/game/version_manifest_v2.json")), 1);
QCOMPARE(m_net.requests().constFirst().query, QStringLiteral("x=1"));
}
void postBodyAndHeaders()
{
m_net.route(QStringLiteral("https://authserver.ely.by/auth/authenticate"),
[](const FakeRequest &request) {
return FakeResponse::json(request.body, request.method == "POST" ? 200 : 405);
});
QNetworkAccessManager manager;
QNetworkRequest request(QUrl(QStringLiteral("https://authserver.ely.by/auth/authenticate")));
request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
QScopedPointer<QNetworkReply> reply(manager.post(request, QByteArrayLiteral("{\"a\":1}")));
QVERIFY(waitFinished(reply.data()));
QCOMPARE(reply->readAll(), QByteArrayLiteral("{\"a\":1}"));
QCOMPARE(m_net.requests().constFirst().header("content-type"), QByteArrayLiteral("application/json"));
}
void prefixRoutesAndKeepAlive()
{
m_net.route(QStringLiteral("https://resources.download.minecraft.net/*"),
[](const FakeRequest &request) { return FakeResponse::text(request.path.toUtf8()); });
QNetworkAccessManager manager;
for (int i = 0; i < 5; ++i) {
const QString path = QStringLiteral("/ab/ab%1").arg(i);
QScopedPointer<QNetworkReply> reply(
get(manager, QStringLiteral("https://resources.download.minecraft.net") + path));
QVERIFY(waitFinished(reply.data()));
QCOMPARE(reply->readAll(), path.toUtf8());
}
QCOMPARE(m_net.requests().size(), 5);
}
void unknownRouteIs404AndRecorded()
{
QNetworkAccessManager manager;
QTest::ignoreMessage(QtWarningMsg, QRegularExpression(QStringLiteral("FakeInternet: нет маршрута")));
QScopedPointer<QNetworkReply> reply(get(manager, QStringLiteral("https://example.invalid/x")));
QVERIFY(waitFinished(reply.data()));
QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 404);
QCOMPARE(m_net.unmatched(), QStringList{QStringLiteral("https://example.invalid/x")});
}
void errorStatusesAndDrop()
{
m_net.route(QStringLiteral("https://a.test/500"), FakeResponse::error(500));
m_net.route(QStringLiteral("https://a.test/drop"), [] {
FakeResponse response;
response.drop = true;
return response;
}());
m_net.route(QStringLiteral("https://a.test/short"), [] {
FakeResponse response = FakeResponse::bytes(QByteArray(1000, 'x'));
response.truncateTo = 10;
return response;
}());
QNetworkAccessManager manager;
QScopedPointer<QNetworkReply> r500(get(manager, QStringLiteral("https://a.test/500")));
QVERIFY(waitFinished(r500.data()));
QCOMPARE(r500->error(), QNetworkReply::InternalServerError);
QScopedPointer<QNetworkReply> drop(get(manager, QStringLiteral("https://a.test/drop")));
QVERIFY(waitFinished(drop.data()));
QVERIFY(drop->error() != QNetworkReply::NoError);
QScopedPointer<QNetworkReply> shortReply(get(manager, QStringLiteral("https://a.test/short")));
QVERIFY(waitFinished(shortReply.data()));
QVERIFY(shortReply->error() != QNetworkReply::NoError);
}
void plainHttpThroughProxy()
{
m_net.route(QStringLiteral("http://plain.test/hello"), FakeResponse::text("hi"));
QNetworkAccessManager manager;
QScopedPointer<QNetworkReply> reply(get(manager, QStringLiteral("http://plain.test/hello")));
QVERIFY(waitFinished(reply.data()));
QCOMPARE(reply->readAll(), QByteArrayLiteral("hi"));
QCOMPARE(m_net.requests().constFirst().scheme, QStringLiteral("http"));
}
};
BILAUNCHER_TEST_MAIN(TestFakeInternet)
#include "tst_fakeinternet.moc"