diff options
author | Tamas Zakor <ztamas@inf.u-szeged.hu> | 2018-11-26 08:34:08 +0100 |
---|---|---|
committer | Zakor Tamas <ztamas@inf.u-szeged.hu> | 2019-01-30 14:03:31 +0000 |
commit | 46d68dcf726e6ba385a91cbeb5db131c0d1d0e9d (patch) | |
tree | 8050bf160f77c01c4e3db2ce8d4a90eaf3ad129a /tests | |
parent | e08c5e162559737672ae90b12dde369dc09c21f8 (diff) |
Add API to set default download path
Add functions and property to set the default download
location in QWebEngineProfile and QQuickWebEngineProfile.
Also add new test for check uniquifying download filename.
Update plugins.qmltypes to 1.9
[ChangeLog][Profile][QtWebEngine][QtWebEngineWidgets]
Add functions and property to set the default download
location in QWebEngineProfile and QQuickWebEngineProfile.
Task-number: QTBUG-66262
Task-number: QTBUG-72176
Change-Id: I7fa93b66c326766b176aec24d453dd75602b91de
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
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" |