diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/quick/qmltests/data/tst_download.qml | 20 | ||||
-rw-r--r-- | tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp | 268 |
2 files changed, 287 insertions, 1 deletions
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml index 019ebd9dc..5eb704cce 100644 --- a/tests/auto/quick/qmltests/data/tst_download.qml +++ b/tests/auto/quick/qmltests/data/tst_download.qml @@ -28,7 +28,8 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.5 +import QtWebEngine 1.9 +import Qt.labs.platform 1.0 TestWebEngineView { id: webEngineView @@ -42,6 +43,12 @@ TestWebEngineView { property var downloadState: [] property var downloadInterruptReason: null + function urlToPath(url) { + var path = url.toString() + path = path.replace(/^(file:\/{2})/,"") + return path + } + SignalSpy { id: downLoadRequestedSpy target: testDownloadProfile @@ -135,5 +142,16 @@ TestWebEngineView { tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadCancelled) tryCompare(webEngineView, "downloadInterruptReason", WebEngineDownloadItem.UserCanceled) } + + function test_downloadLocation() { + var tmpPath = urlToPath(StandardPaths.writableLocation(StandardPaths.TempLocation)); + var downloadPath = urlToPath(StandardPaths.writableLocation(StandardPaths.DownloadLocation)); + + testDownloadProfile.downloadPath = tmpPath; + compare(testDownloadProfile.downloadPath, tmpPath); + + testDownloadProfile.downloadPath = downloadPath; + compare(testDownloadProfile.downloadPath, downloadPath); + } } } diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp index 5227f2d0a..b50036aa8 100644 --- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp +++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp @@ -31,6 +31,7 @@ #include <QStandardPaths> #include <QTemporaryDir> #include <QTest> +#include <QRegularExpression> #include <QWebEngineDownloadItem> #include <QWebEnginePage> #include <QWebEngineProfile> @@ -69,6 +70,12 @@ private Q_SLOTS: void downloadFileNot1(); void downloadFileNot2(); void downloadDeleted(); + void downloadUniqueFilename_data(); + void downloadUniqueFilename(); + void downloadUniqueFileNameWithTimeStamp(); + void downloadToDefaultLocation(); + void downloadToNonExistentDir(); + void downloadToReadOnlyDir(); private: void saveLink(QPoint linkPos); @@ -134,6 +141,8 @@ void tst_QWebEngineDownloadItem::cleanup() QTRY_COMPARE(m_requestedDownloads.count(), 0); QCOMPARE(m_finishedDownloads.count(), 0); QVERIFY(m_server->stop()); + // Set download path to default. + m_profile->setDownloadPath(""); } void tst_QWebEngineDownloadItem::cleanupTestCase() @@ -813,5 +822,264 @@ void tst_QWebEngineDownloadItem::downloadDeleted() QTRY_COMPARE(finishedCount, 1); } +void tst_QWebEngineDownloadItem::downloadUniqueFilename_data() +{ + QTest::addColumn<QString>("baseName"); + QTest::addColumn<QString>("extension"); + + QTest::newRow("txt") << QString("test(1.test)") << QString("txt"); + QTest::newRow("tar.gz") << QString("test(1.test)") << QString("tar.gz"); +} + +void tst_QWebEngineDownloadItem::downloadUniqueFilename() +{ + QFETCH(QString, baseName); + QFETCH(QString, extension); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + // Set up HTTP server + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + // Set up profile and download handler + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted); + QCOMPARE(item->isFinished(), true); + QCOMPARE(item->totalBytes(), item->receivedBytes()); + QVERIFY(item->receivedBytes() > 0); + QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); + QCOMPARE(item->type(), QWebEngineDownloadItem::Attachment); + QCOMPARE(item->isSavePageDownload(), false); + downloadedFilePath = item->path(); + downloadFinished = true; + }); + }); + + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + "." + extension); + + for (int i = 1; i <= 2; ++i) { + downloadFinished = false; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension); + } +} + +void tst_QWebEngineDownloadItem::downloadUniqueFileNameWithTimeStamp() +{ + // Set up HTTP server + QString baseName("test(1.test)"); + QString extension("txt"); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + // Set up profile and download handler + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted); + QCOMPARE(item->isFinished(), true); + QCOMPARE(item->totalBytes(), item->receivedBytes()); + QVERIFY(item->receivedBytes() > 0); + QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); + QCOMPARE(item->page(), m_page); + downloadFinished = true; + downloadedFilePath = item->path(); + }); + }); + + // Create the first empty file without uniquifier. + { + QFile file(m_profile->downloadPath() + "/" + fileName); + file.open(QIODevice::ReadWrite); + } + + // Create 99 empty files with uniquifier. + for (int i = 1; i < 100; i++) { + QFile file(m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension); + file.open(QIODevice::ReadWrite); + } + + // Create 100th (kMaxUniqueFiles) empty file with uniquifier. + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (100)." + extension); + + // Check if the downloaded files are suffixed with timestamp after the 100th download. + for (int i = 101; i < 103; i++) { + downloadFinished = false; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QRegularExpression fileNameCheck("^.*" + QRegularExpression::escape(baseName) + " - (.*)[.]" + QRegularExpression::escape(extension) + "$"); + QRegularExpressionMatch match = fileNameCheck.match(downloadedFilePath); + QVERIFY(match.hasMatch()); + // ISO 8601 Date and time in UTC + QRegExp timeStamp("^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])([.][0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$"); + QVERIFY(timeStamp.exactMatch(match.captured(1))); + } +} + +void tst_QWebEngineDownloadItem::downloadToDefaultLocation() +{ + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + + QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); + + m_profile->setDownloadPath(""); + QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); + + m_profile->setDownloadPath(tmpDir.path()); + QCOMPARE(m_profile->downloadPath(), tmpDir.path()); + + m_profile->setDownloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); + QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); +} + +void tst_QWebEngineDownloadItem::downloadToNonExistentDir() +{ + QString baseName("test(1.test)"); + QString extension("txt"); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + // Set up HTTP server + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + // Set up profile and download handler + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted); + QCOMPARE(item->isFinished(), true); + QCOMPARE(item->totalBytes(), item->receivedBytes()); + QVERIFY(item->receivedBytes() > 0); + QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); + QCOMPARE(item->page(), m_page); + downloadFinished = true; + downloadedFilePath = item->path(); + }); + }); + + // Set a non-existent directory for the default download location. + QString nonExistentDownloadPath(m_profile->downloadPath() + "/non_existent_dir"); + m_profile->setDownloadPath(nonExistentDownloadPath); + QCOMPARE(m_profile->downloadPath(), nonExistentDownloadPath); + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, nonExistentDownloadPath + "/" + fileName); +} + +void tst_QWebEngineDownloadItem::downloadToReadOnlyDir() +{ + QString baseName("test(1.test)"); + QString extension("txt"); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadAccepted = false; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + // Set up HTTP server + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + QPointer<QWebEngineDownloadItem> downloadItem; + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + downloadItem = item; + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + downloadFinished = true; + }); + downloadAccepted = true; + }); + + // Change permission for directory. + QFile(m_profile->downloadPath()).setPermissions(QFileDevice::ReadOwner); + QVERIFY(QFile(m_profile->downloadPath()).exists()); + + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadAccepted); + + QVERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadInterrupted); + QCOMPARE(downloadItem->isFinished(), false); + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileAccessDenied); + QVERIFY(!QFile(downloadedFilePath).exists()); + + // Clear m_requestedDownloads explicitly because download is accepted but never finished. + m_requestedDownloads.clear(); + QVERIFY(!downloadFinished); + QFile(m_profile->downloadPath()).setPermissions(QFileDevice::WriteOwner); +} + QTEST_MAIN(tst_QWebEngineDownloadItem) #include "tst_qwebenginedownloaditem.moc" |