#include "testenv.h" #include "fixtures.h" #include "nettest.h" #include "localization.h" #include "seasonalpackdownloader.h" #include namespace { const QString kPack = QStringLiteral("https://launcher-builds.galeonworx.com/packs/season-5-r3.zip"); } class TestSeasonalPackDownloader : public QObject { Q_OBJECT FakeInternet m_net; QString m_dir; struct Run { explicit Run(SeasonalPackDownloader &d) : started(&d, &SeasonalPackDownloader::started) , finished(&d, &SeasonalPackDownloader::finished) , failed(&d, &SeasonalPackDownloader::failed) , canceled(&d, &SeasonalPackDownloader::canceled) {} bool waitEnd() { return QTest::qWaitFor([&] { return finished.count() + failed.count() + canceled.count() > 0; }, 20000); } QSignalSpy started, finished, failed, canceled; }; private slots: void initTestCase() { BILAUNCHER_START_FAKE_INTERNET(m_net); } void init() { m_net.reset(); m_dir = TestEnv::freshDir(QStringLiteral("packs")); } void downloadsAndVerifies() { const QByteArray data(300 * 1024, 'p'); m_net.route(kPack, FakeResponse::bytes(data)); SeasonalPackDownloader downloader; Run run(downloader); const QString target = m_dir + "/sub/season-5.zip"; downloader.download(QUrl(kPack), target, Fixtures::sha256(data).toUpper(), data.size(), "Season 5"); QVERIFY(downloader.isRunning()); QCOMPARE(downloader.label(), QStringLiteral("Season 5")); QCOMPARE(downloader.currentFile(), QStringLiteral("season-5.zip")); QCOMPARE(downloader.bytesTotal(), qint64(data.size())); QCOMPARE(run.started.count(), 1); QVERIFY(run.waitEnd()); QCOMPARE(run.finished.count(), 1); QCOMPARE(run.finished.constFirst().constFirst().toString(), target); QCOMPARE(Fixtures::readFile(target), data); QVERIFY(!downloader.isRunning()); QCOMPARE(downloader.fraction(), -1.0); } void checksumMismatchLeavesNoFile() { m_net.route(kPack, FakeResponse::bytes("tampered")); SeasonalPackDownloader downloader; Run run(downloader); const QString target = m_dir + "/season.zip"; downloader.download(QUrl(kPack), target, QString(64, u'a'), 8, "S"); QVERIFY(run.waitEnd()); QCOMPARE(run.failed.count(), 1); QCOMPARE(run.failed.constFirst().at(0).toString(), QStringLiteral("S")); QCOMPARE(run.failed.constFirst().at(1).toString(), Loc::text("seasonal.error.checksumMismatch")); QVERIFY(!QFile::exists(target)); } void httpErrorAndTruncation() { SeasonalPackDownloader downloader; { m_net.route(kPack, FakeResponse::error(404)); Run run(downloader); downloader.download(QUrl(kPack), m_dir + "/a.zip", QString(64, u'a'), 0, "A"); QVERIFY(run.waitEnd()); QVERIFY(run.failed.constFirst().at(1).toString().startsWith( Loc::text("seasonal.error.downloadFailed").section(u'%', 0, 0))); } { FakeResponse cut = FakeResponse::bytes(QByteArray(4096, 'x')); cut.truncateTo = 100; m_net.route(kPack, cut); Run run(downloader); downloader.download(QUrl(kPack), m_dir + "/b.zip", Fixtures::sha256(QByteArray(4096, 'x')), 4096, "B"); QVERIFY2(run.waitEnd(), qPrintable(m_net.diagnostics())); QCOMPARE(run.failed.count(), 1); QVERIFY(!QFile::exists(m_dir + "/b.zip")); } } void cancelInFlight() { FakeResponse hang; hang.hang = true; m_net.route(kPack, hang); SeasonalPackDownloader downloader; Run run(downloader); downloader.download(QUrl(kPack), m_dir + "/c.zip", QString(64, u'a'), 10, "C"); QTRY_COMPARE_WITH_TIMEOUT(m_net.hits(kPack), 1, 15000); downloader.cancel(); QVERIFY(run.waitEnd()); QCOMPARE(run.canceled.count(), 1); QCOMPARE(run.canceled.constFirst().constFirst().toString(), QStringLiteral("C")); QVERIFY(!QFile::exists(m_dir + "/c.zip")); QVERIFY(!downloader.isRunning()); downloader.cancel(); // повторная отмена без загрузки — ничего не делает QCOMPARE(run.canceled.count(), 1); } void secondDownloadWhileBusyIsRejected() { FakeResponse slow = FakeResponse::bytes("x"); slow.delayMs = 500; m_net.route(kPack, slow); SeasonalPackDownloader downloader; Run run(downloader); downloader.download(QUrl(kPack), m_dir + "/d.zip", Fixtures::sha256("x"), 1, "D"); downloader.download(QUrl(kPack), m_dir + "/e.zip", Fixtures::sha256("x"), 1, "E"); QCOMPARE(run.failed.count(), 1); QCOMPARE(run.failed.constFirst().at(0).toString(), QStringLiteral("E")); QCOMPARE(run.failed.constFirst().at(1).toString(), Loc::text("seasonal.error.downloadInProgress")); QTRY_COMPARE_WITH_TIMEOUT(run.finished.count(), 1, 15000); } }; BILAUNCHER_TEST_MAIN(TestSeasonalPackDownloader) #include "tst_seasonalpackdownloader.moc"