diff options
Diffstat (limited to 'tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp')
-rw-r--r-- | tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp | 1386 |
1 files changed, 0 insertions, 1386 deletions
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp deleted file mode 100644 index 6dc7f03c1..000000000 --- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp +++ /dev/null @@ -1,1386 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QCoreApplication> -#include <QSignalSpy> -#include <QStandardPaths> -#include <QTemporaryDir> -#include <QTest> -#include <QRegularExpression> -#include <QWebEngineDownloadItem> -#include <QWebEnginePage> -#include <QWebEngineProfile> -#include <QWebEngineSettings> -#include <QWebEngineView> -#include <httpserver.h> - -class tst_QWebEngineDownloadItem : public QObject -{ - Q_OBJECT - -public: - enum UserAction { - SaveLink, - ClickLink, - }; - - enum FileAction { - FileIsDownloaded, - FileIsDisplayed, - }; - -private Q_SLOTS: - void initTestCase(); - void init(); - void cleanup(); - void cleanupTestCase(); - - void downloadLink_data(); - void downloadLink(); - void downloadTwoLinks_data(); - void downloadTwoLinks(); - void downloadPage_data(); - void downloadPage(); - void downloadViaSetUrl(); - void downloadFileNot1(); - void downloadFileNot2(); - void downloadDeleted(); - void downloadDeletedByProfile(); - void downloadUniqueFilename_data(); - void downloadUniqueFilename(); - void downloadUniqueFilenameWithTimestamp(); - void downloadToDefaultLocation(); - void downloadToNonExistentDir(); - void downloadToReadOnlyDir(); - void downloadPathValidation(); - void downloadToDirectoryWithFileName(); - -private: - void saveLink(QPoint linkPos); - void clickLink(QPoint linkPos); - void simulateUserAction(QPoint linkPos, UserAction action); - - QWebEngineDownloadItem::DownloadType expectedDownloadType( - UserAction userAction, - const QByteArray &contentDisposition = QByteArray()); - - HttpServer *m_server; - QWebEngineProfile *m_profile; - QWebEnginePage *m_page; - QWebEngineView *m_view; - QSet<QWebEngineDownloadItem *> m_requestedDownloads; - QSet<QWebEngineDownloadItem *> m_finishedDownloads; -}; - -class ScopedConnection { -public: - ScopedConnection(QMetaObject::Connection connection) : m_connection(std::move(connection)) {} - ~ScopedConnection() { QObject::disconnect(m_connection); } -private: - QMetaObject::Connection m_connection; -}; - -Q_DECLARE_METATYPE(tst_QWebEngineDownloadItem::UserAction) -Q_DECLARE_METATYPE(tst_QWebEngineDownloadItem::FileAction) - -void tst_QWebEngineDownloadItem::initTestCase() -{ - m_server = new HttpServer(); - m_profile = new QWebEngineProfile; - m_profile->setHttpCacheType(QWebEngineProfile::NoCache); - m_profile->settings()->setAttribute(QWebEngineSettings::AutoLoadIconsForPage, false); - connect(m_profile, &QWebEngineProfile::downloadRequested, [this](QWebEngineDownloadItem *item) { - m_requestedDownloads.insert(item); - connect(item, &QWebEngineDownloadItem::destroyed, [this, item](){ - m_requestedDownloads.remove(item); - m_finishedDownloads.remove(item); - }); - connect(item, &QWebEngineDownloadItem::finished, [this, item](){ - m_finishedDownloads.insert(item); - }); - }); - m_page = new QWebEnginePage(m_profile); - m_view = new QWebEngineView; - m_view->setPage(m_page); - m_view->resize(640, 480); - m_view->show(); -} - -void tst_QWebEngineDownloadItem::init() -{ - QVERIFY(m_server->start()); -} - -void tst_QWebEngineDownloadItem::cleanup() -{ - for (QWebEngineDownloadItem *item : m_finishedDownloads) { - item->deleteLater(); - } - 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() -{ - delete m_view; - delete m_page; - delete m_profile; - delete m_server; -} - -void tst_QWebEngineDownloadItem::saveLink(QPoint linkPos) -{ - // Simulate right-clicking on link and choosing "save link as" from menu. - QSignalSpy menuSpy(m_view, &QWebEngineView::customContextMenuRequested); - m_view->setContextMenuPolicy(Qt::CustomContextMenu); - auto event1 = new QContextMenuEvent(QContextMenuEvent::Mouse, linkPos); - auto event2 = new QMouseEvent(QEvent::MouseButtonPress, linkPos, Qt::RightButton, {}, {}); - auto event3 = new QMouseEvent(QEvent::MouseButtonRelease, linkPos, Qt::RightButton, {}, {}); - QTRY_VERIFY(m_view->focusWidget()); - QWidget *renderWidget = m_view->focusWidget(); - QCoreApplication::postEvent(renderWidget, event1); - QCoreApplication::postEvent(renderWidget, event2); - QCoreApplication::postEvent(renderWidget, event3); - QTRY_COMPARE(menuSpy.count(), 1); - m_page->triggerAction(QWebEnginePage::DownloadLinkToDisk); -} - -void tst_QWebEngineDownloadItem::clickLink(QPoint linkPos) -{ - // Simulate left-clicking on link. - QTRY_VERIFY(m_view->focusWidget()); - QWidget *renderWidget = m_view->focusWidget(); - QTest::mouseClick(renderWidget, Qt::LeftButton, {}, linkPos); -} - -void tst_QWebEngineDownloadItem::simulateUserAction(QPoint linkPos, UserAction action) -{ - switch (action) { - case SaveLink: return saveLink(linkPos); - case ClickLink: return clickLink(linkPos); - } -} - -QWebEngineDownloadItem::DownloadType tst_QWebEngineDownloadItem::expectedDownloadType( - UserAction userAction, const QByteArray &contentDisposition) -{ - if (userAction == SaveLink) - return QWebEngineDownloadItem::UserRequested; - if (contentDisposition == QByteArrayLiteral("attachment")) - return QWebEngineDownloadItem::Attachment; - return QWebEngineDownloadItem::DownloadAttribute; -} - -void tst_QWebEngineDownloadItem::downloadLink_data() -{ - QTest::addColumn<UserAction>("userAction"); - QTest::addColumn<bool>("anchorHasDownloadAttribute"); - QTest::addColumn<QByteArray>("fileName"); - QTest::addColumn<QByteArray>("fileContents"); - QTest::addColumn<QByteArray>("fileMimeTypeDeclared"); - QTest::addColumn<QByteArray>("fileMimeTypeDetected"); - QTest::addColumn<QByteArray>("fileDisposition"); - QTest::addColumn<bool>("fileHasReferer"); - QTest::addColumn<FileAction>("fileAction"); - QTest::addColumn<QWebEngineDownloadItem::DownloadType>("downloadType"); - - // SaveLink should always trigger a download, even for empty files. - QTest::newRow("save link to empty file") - /* userAction */ << SaveLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("") - /* fileMimeTypeDetected */ << QByteArrayLiteral("") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // SaveLink should always trigger a download, also for text files. - QTest::newRow("save link to text file") - /* userAction */ << SaveLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // ... adding the "download" attribute should have no effect. - QTest::newRow("save link to text file (attribute)") - /* userAction */ << SaveLink - /* anchorHasDownloadAttribute */ << true - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // ... adding the "attachment" content disposition should also have no effect. - QTest::newRow("save link to text file (attachment)") - /* userAction */ << SaveLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("attachment") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // ... even adding both should have no effect. - QTest::newRow("save link to text file (attribute+attachment)") - /* userAction */ << SaveLink - /* anchorHasDownloadAttribute */ << true - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("attachment") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // Navigating to an empty file should show an empty page. - QTest::newRow("navigate to empty file") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("") - /* fileMimeTypeDetected */ << QByteArrayLiteral("") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDisplayed; - - // Navigating to a text file should show the text file. - QTest::newRow("navigate to text file") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDisplayed; - - // ... unless the link has the "download" attribute: then the file should be downloaded. - QTest::newRow("navigate to text file (attribute)") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << true - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << false // crbug.com/455987 - /* fileAction */ << FileIsDownloaded; - - // ... same with the content disposition header save for the download type. - QTest::newRow("navigate to text file (attachment)") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("attachment") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // ... and both. - QTest::newRow("navigate to text file (attribute+attachment)") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << true - /* fileName */ << QByteArrayLiteral("foo.txt") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("text/plain") - /* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain") - /* fileDisposition */ << QByteArrayLiteral("attachment") - /* fileHasReferer */ << false // crbug.com/455987 - /* fileAction */ << FileIsDownloaded; - - // The file's extension has no effect. - QTest::newRow("navigate to supposed zip file") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.zip") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("") - /* fileMimeTypeDetected */ << QByteArrayLiteral("") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDisplayed; - - // ... the file's mime type however does. - QTest::newRow("navigate to supposed zip file (application/zip)") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.zip") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("application/zip") - /* fileMimeTypeDetected */ << QByteArrayLiteral("application/zip") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // ... but we're not very picky about the exact type. - QTest::newRow("navigate to supposed zip file (application/octet-stream)") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.zip") - /* fileContents */ << QByteArrayLiteral("bar") - /* fileMimeTypeDeclared */ << QByteArrayLiteral("application/octet-stream") - /* fileMimeTypeDetected */ << QByteArrayLiteral("application/octet-stream") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // empty zip file (consisting only of "end of central directory record") - QByteArray zipFile = QByteArrayLiteral("PK\x05\x06") + QByteArray(18, 0); - - // The mime type is guessed automatically if not provided by the server. - QTest::newRow("navigate to actual zip file") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.zip") - /* fileContents */ << zipFile - /* fileMimeTypeDeclared */ << QByteArrayLiteral("") - /* fileMimeTypeDetected */ << QByteArrayLiteral("application/octet-stream") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; - - // The mime type is not guessed automatically if provided by the server. - QTest::newRow("navigate to actual zip file (application/zip)") - /* userAction */ << ClickLink - /* anchorHasDownloadAttribute */ << false - /* fileName */ << QByteArrayLiteral("foo.zip") - /* fileContents */ << zipFile - /* fileMimeTypeDeclared */ << QByteArrayLiteral("application/zip") - /* fileMimeTypeDetected */ << QByteArrayLiteral("application/zip") - /* fileDisposition */ << QByteArrayLiteral("") - /* fileHasReferer */ << true - /* fileAction */ << FileIsDownloaded; -} - -void tst_QWebEngineDownloadItem::downloadLink() -{ - QFETCH(UserAction, userAction); - QFETCH(bool, anchorHasDownloadAttribute); - QFETCH(QByteArray, fileName); - QFETCH(QByteArray, fileContents); - QFETCH(QByteArray, fileMimeTypeDeclared); - QFETCH(QByteArray, fileMimeTypeDetected); - QFETCH(QByteArray, fileDisposition); - QFETCH(bool, fileHasReferer); - QFETCH(FileAction, fileAction); - - // Set up HTTP server - int indexRequestCount = 0; - int fileRequestCount = 0; - QByteArray fileRequestReferer; - ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { - if (rr->requestMethod() == "GET" && rr->requestPath() == "/") { - indexRequestCount++; - - rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html")); - QByteArray html; - html += QByteArrayLiteral("<html><body><a href=\""); - html += fileName; - html += QByteArrayLiteral("\" "); - if (anchorHasDownloadAttribute) - html += QByteArrayLiteral("download"); - html += QByteArrayLiteral(">Link</a></body></html>"); - rr->setResponseBody(html); - rr->sendResponse(); - } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/" + fileName) { - fileRequestCount++; - fileRequestReferer = rr->requestHeader(QByteArrayLiteral("referer")); - - if (!fileDisposition.isEmpty()) - rr->setResponseHeader(QByteArrayLiteral("content-disposition"), fileDisposition); - if (!fileMimeTypeDeclared.isEmpty()) - rr->setResponseHeader(QByteArrayLiteral("content-type"), fileMimeTypeDeclared); - rr->setResponseBody(fileContents); - rr->sendResponse(); - } else { - rr->setResponseStatus(404); - rr->sendResponse(); - } - }); - - // Set up profile and download handler - QTemporaryDir tmpDir; - QVERIFY(tmpDir.isValid()); - QByteArray slashFileName = QByteArrayLiteral("/") + fileName; - QString suggestedPath = - QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + slashFileName; - QString downloadDirectory = tmpDir.path(); - QString downloadFileName = fileName; - QString downloadPath = tmpDir.path() + slashFileName; - QUrl downloadUrl = m_server->url(slashFileName); - int acceptedCount = 0; - int finishedCount = 0; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested); - QCOMPARE(item->isFinished(), false); - QCOMPARE(item->totalBytes(), -1); - QCOMPARE(item->receivedBytes(), 0); - QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition)); - QCOMPARE(item->isSavePageDownload(), false); - QCOMPARE(item->mimeType(), QString(fileMimeTypeDetected)); - QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), suggestedPath); - QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat); - QCOMPARE(item->url(), downloadUrl); - QCOMPARE(item->page(), m_page); - - connect(item, &QWebEngineDownloadItem::finished, [&, item]() { - QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted); - QCOMPARE(item->isFinished(), true); - QCOMPARE(item->totalBytes(), fileContents.size()); - QCOMPARE(item->receivedBytes(), fileContents.size()); - QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition)); - QCOMPARE(item->isSavePageDownload(), false); - QCOMPARE(item->mimeType(), QString(fileMimeTypeDetected)); - QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath); - QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat); - QCOMPARE(item->url(), downloadUrl); - QCOMPARE(item->page(), m_page); - - finishedCount++; - }); - item->setDownloadDirectory(downloadDirectory); - item->setDownloadFileName(downloadFileName); - item->accept(); - - acceptedCount++; - }); - - // Load an HTML page with a link - // - // The only variation being whether the <a> element has a "download" - // attribute or not. - QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished); - m_view->load(m_server->url()); - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true); - QCOMPARE(indexRequestCount, 1); - - simulateUserAction(QPoint(10, 10), userAction); - - // If file is expected to be displayed and not downloaded then end test - if (fileAction == FileIsDisplayed) { - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true); - QCOMPARE(acceptedCount, 0); - return; - } - - // Otherwise file is downloaded - QTRY_COMPARE(acceptedCount, 1); - QTRY_COMPARE(finishedCount, 1); - QCOMPARE(fileRequestCount, 1); - if (fileHasReferer) - QCOMPARE(fileRequestReferer, m_server->url().toEncoded()); - else - QCOMPARE(fileRequestReferer, QByteArray()); - QFile file(downloadPath); - QVERIFY(file.open(QIODevice::ReadOnly)); - QCOMPARE(file.readAll(), fileContents); -} - -void tst_QWebEngineDownloadItem::downloadTwoLinks_data() -{ - QTest::addColumn<UserAction>("action1"); - QTest::addColumn<UserAction>("action2"); - QTest::newRow("Save+Save") << SaveLink << SaveLink; - QTest::newRow("Save+Click") << SaveLink << ClickLink; - QTest::newRow("Click+Save") << ClickLink << SaveLink; - QTest::newRow("Click+Click") << ClickLink << ClickLink; -} - -void tst_QWebEngineDownloadItem::downloadTwoLinks() -{ - QFETCH(UserAction, action1); - QFETCH(UserAction, action2); - - // Set up HTTP server - int file1RequestCount = 0; - int file2RequestCount = 0; - ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { - if (rr->requestMethod() == "GET" && rr->requestPath() == "/") { - rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html")); - rr->setResponseBody(QByteArrayLiteral("<html><body><a href=\"file1\" download>Link1</a><br/><a href=\"file2\">Link2</a></body></html>")); - rr->sendResponse(); - } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/file1") { - file1RequestCount++; - rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/plain")); - rr->setResponseBody(QByteArrayLiteral("file1")); - rr->sendResponse(); - } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/file2") { - file2RequestCount++; - rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/plain")); - rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); - rr->setResponseBody(QByteArrayLiteral("file2")); - rr->sendResponse(); - } else { - rr->setResponseStatus(404); - rr->sendResponse(); - } - }); - - // Set up profile and download handler - QTemporaryDir tmpDir; - QVERIFY(tmpDir.isValid()); - QString standardDir = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); - int acceptedCount = 0; - int finishedCount = 0; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested); - QCOMPARE(item->isFinished(), false); - QCOMPARE(item->totalBytes(), -1); - QCOMPARE(item->receivedBytes(), 0); - QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat); - QCOMPARE(item->mimeType(), QStringLiteral("text/plain")); - QString filePart = QChar('/') + item->url().fileName(); - QString fileName = item->url().fileName(); - QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), standardDir + filePart); - - // type() is broken due to race condition in DownloadManagerDelegateQt - if (action1 == ClickLink && action2 == ClickLink) { - if (filePart == QStringLiteral("/file1")) - QCOMPARE(item->type(), expectedDownloadType(action1)); - else if (filePart == QStringLiteral("/file2")) - QCOMPARE(item->type(), expectedDownloadType(action2, QByteArrayLiteral("attachment"))); - else - QFAIL(qPrintable("Unexpected file name: " + filePart)); - } - - connect(item, &QWebEngineDownloadItem::finished, [&]() { - finishedCount++; - }); - item->setDownloadDirectory(tmpDir.path()); - item->setDownloadFileName(fileName); - item->accept(); - - acceptedCount++; - }); - - QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished); - m_view->load(m_server->url()); - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true); - - // Trigger downloads - simulateUserAction(QPoint(10, 10), action1); - simulateUserAction(QPoint(10, 30), action2); - - // Wait for downloads - QTRY_COMPARE(file1RequestCount, 1); - QTRY_COMPARE(file2RequestCount, 1); - QTRY_COMPARE(acceptedCount, 2); - QTRY_COMPARE(finishedCount, 2); -} - -void tst_QWebEngineDownloadItem::downloadPage_data() -{ - QTest::addColumn<QWebEngineDownloadItem::SavePageFormat>("savePageFormat"); - QTest::newRow("SingleHtmlSaveFormat") << QWebEngineDownloadItem::SingleHtmlSaveFormat; - QTest::newRow("CompleteHtmlSaveFormat") << QWebEngineDownloadItem::CompleteHtmlSaveFormat; - QTest::newRow("MimeHtmlSaveFormat") << QWebEngineDownloadItem::MimeHtmlSaveFormat; -} - -void tst_QWebEngineDownloadItem::downloadPage() -{ - QFETCH(QWebEngineDownloadItem::SavePageFormat, savePageFormat); - - // Set up HTTP server - int indexRequestCount = 0; - ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { - if (rr->requestMethod() == "GET" && rr->requestPath() == "/") { - indexRequestCount++; - rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html")); - rr->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>")); - rr->sendResponse(); - } else { - rr->setResponseStatus(404); - rr->sendResponse(); - } - }); - - // Set up profile and download handler - QTemporaryDir tmpDir; - QVERIFY(tmpDir.isValid()); - QString downloadPath = tmpDir.path() + QStringLiteral("/test.html"); - QUrl downloadUrl = m_server->url("/"); - int acceptedCount = 0; - int finishedCount = 0; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadInProgress); - QCOMPARE(item->isFinished(), false); - QCOMPARE(item->totalBytes(), -1); - QCOMPARE(item->receivedBytes(), 0); - QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(item->type(), QWebEngineDownloadItem::SavePage); - QCOMPARE(item->isSavePageDownload(), true); - // FIXME(juvaldma): why is mimeType always the same? - QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive")); - QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath); - QCOMPARE(item->savePageFormat(), savePageFormat); - QCOMPARE(item->url(), downloadUrl); - QCOMPARE(item->page(), m_page); - // no need to call 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::SavePage); - QCOMPARE(item->isSavePageDownload(), true); - QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive")); - QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath); - QCOMPARE(item->savePageFormat(), savePageFormat); - QCOMPARE(item->url(), downloadUrl); - QCOMPARE(item->page(), m_page); - - finishedCount++; - }); - - acceptedCount++; - }); - - // Load some HTML - QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished); - m_page->load(m_server->url()); - QTRY_COMPARE(loadSpy.count(), 1); - QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true); - QCOMPARE(indexRequestCount, 1); - - // Save some HTML - m_page->save(downloadPath, savePageFormat); - QTRY_COMPARE(acceptedCount, 1); - QTRY_COMPARE(finishedCount, 1); - QFile file(downloadPath); - QVERIFY(file.exists()); -} - -void tst_QWebEngineDownloadItem::downloadViaSetUrl() -{ - // Reproduce the scenario described in QTBUG-63388 by triggering downloads - // of the same file multiple times via QWebEnginePage::setUrl - - // Set up HTTP server - ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { - if (rr->requestMethod() == "GET" && rr->requestPath() == "/") { - rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html")); - rr->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>")); - rr->sendResponse(); - } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/file") { - rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); - rr->setResponseBody(QByteArrayLiteral("redacted")); - rr->sendResponse(); - } else { - rr->setResponseStatus(404); - rr->sendResponse(); - } - }); - - // Set up profile and download handler - QVector<QUrl> downloadUrls; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - downloadUrls.append(item->url()); - }); - - // Set up the test scenario by trying to load some unrelated HTML. - QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished); - QSignalSpy urlSpy(m_page, &QWebEnginePage::urlChanged); - const QUrl indexUrl = m_server->url(); - m_page->setUrl(indexUrl); - QTRY_COMPARE(loadSpy.count(), 1); - QTRY_COMPARE(urlSpy.count(), 1); - QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true); - QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), indexUrl); - - // Download files via setUrl. With QTBUG-63388 after the first iteration the - // downloads would be triggered for indexUrl and not fileUrl. - const QUrl fileUrl = m_server->url(QByteArrayLiteral("/file")); - for (int i = 0; i != 3; ++i) { - m_page->setUrl(fileUrl); - QCOMPARE(m_page->url(), fileUrl); - QTRY_COMPARE(loadSpy.count(), 1); - QTRY_COMPARE(urlSpy.count(), 2); - QTRY_COMPARE(downloadUrls.count(), 1); - QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false); - QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), fileUrl); - QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), indexUrl); - QCOMPARE(downloadUrls.takeFirst(), fileUrl); - QCOMPARE(m_page->url(), indexUrl); - } -} - -void tst_QWebEngineDownloadItem::downloadFileNot1() -{ - // Trigger file download via download() but don't accept(). - - ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { - rr->setResponseStatus(404); - rr->sendResponse(); - }); - - QPointer<QWebEngineDownloadItem> downloadItem; - int downloadCount = 0; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - QVERIFY(item); - QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested); - downloadItem = item; - downloadCount++; - }); - - m_page->download(m_server->url(QByteArrayLiteral("/file"))); - QTRY_COMPARE(downloadCount, 1); - QVERIFY(!downloadItem); -} - -void tst_QWebEngineDownloadItem::downloadFileNot2() -{ - // Trigger file download via download() but call cancel() instead of accept(). - - ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { - rr->setResponseStatus(404); - rr->sendResponse(); - }); - - QPointer<QWebEngineDownloadItem> downloadItem; - int downloadCount = 0; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - QVERIFY(item); - QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested); - item->cancel(); - downloadItem = item; - downloadCount++; - }); - - m_page->download(m_server->url(QByteArrayLiteral("/file"))); - QTRY_COMPARE(downloadCount, 1); - QVERIFY(downloadItem); - QCOMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled); -} - -void tst_QWebEngineDownloadItem::downloadDeleted() -{ - QPointer<QWebEngineDownloadItem> downloadItem; - m_server->setExpectError(true); - int downloadCount = 0; - int finishedCount = 0; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - QVERIFY(item); - QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested); - downloadItem = item; - connect(downloadItem, &QWebEngineDownloadItem::finished, [&]() { - finishedCount++; - }); - item->accept(); - downloadCount++; - }); - - m_page->download(m_server->url(QByteArrayLiteral("/file"))); - QTRY_COMPARE(downloadCount, 1); - QVERIFY(downloadItem); - QCOMPARE(finishedCount, 0); - downloadItem->deleteLater(); - QTRY_COMPARE(finishedCount, 1); -} - -void tst_QWebEngineDownloadItem::downloadDeletedByProfile() -{ - m_server->setExpectError(true); - - QPointer<QWebEngineProfile> profile(new QWebEngineProfile); - profile->setHttpCacheType(QWebEngineProfile::NoCache); - profile->settings()->setAttribute(QWebEngineSettings::AutoLoadIconsForPage, false); - - bool downloadFinished = false; - QPointer<QWebEngineDownloadItem> downloadItem; - connect(profile, &QWebEngineProfile::downloadRequested, [&] (QWebEngineDownloadItem *item) { - connect(item, &QWebEngineDownloadItem::finished, [&] () { - downloadFinished = true; - }); - downloadItem = item; - item->accept(); - }); - - QPointer<QWebEnginePage> page(new QWebEnginePage(profile)); - page->download(m_server->url(QByteArrayLiteral("/file"))); - - QTRY_COMPARE(downloadItem.isNull(), false); - QVERIFY(downloadItem); - - page->deleteLater(); - profile->deleteLater(); - - QTRY_COMPARE(downloadFinished, true); - QTRY_COMPARE(downloadItem.isNull(), true); -} - -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; - QString suggestedFileName; - 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) { - suggestedFileName = item->suggestedFileName(); - 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 = QDir(item->downloadDirectory()).filePath(item->downloadFileName()); - 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); - QCOMPARE(suggestedFileName, fileName); - } -} - -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; - QString suggestedFileName; - 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) { - suggestedFileName = item->suggestedFileName(); - 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 = QDir(item->downloadDirectory()).filePath(item->downloadFileName()); - }); - }); - - // 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); - QCOMPARE(suggestedFileName, fileName); - - // 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))); - QCOMPARE(suggestedFileName, fileName); - } -} - -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; - QString suggestedFileName; - 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) { - suggestedFileName = item->suggestedFileName(); - 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 = QDir(item->downloadDirectory()).filePath(item->downloadFileName()); - }); - }); - - // 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); - QCOMPARE(suggestedFileName, fileName); -} - -void tst_QWebEngineDownloadItem::downloadToReadOnlyDir() -{ -#ifdef Q_OS_WIN - QSKIP("Cannot change file permissions on Windows."); -#endif - QString baseName("test(1.test)"); - QString extension("txt"); - QString fileName = QString("%1.%2").arg(baseName).arg(extension); - QString downloadedFilePath; - QString suggestedFileName; - 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) { - suggestedFileName = item->suggestedFileName(); - 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()); - QCOMPARE(suggestedFileName, fileName); - - // Clear m_requestedDownloads explicitly because download is accepted but never finished. - m_requestedDownloads.clear(); - QVERIFY(!downloadFinished); - QFile(m_profile->downloadPath()).setPermissions(QFileDevice::WriteOwner); -} - -void tst_QWebEngineDownloadItem::downloadPathValidation() -{ - const QString fileName = "test.txt"; - QString downloadPath; - QString originalDownloadPath; - - 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 - QPointer<QWebEngineDownloadItem> downloadItem; - ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { - downloadItem = item; - originalDownloadPath = item->path(); - - item->setPath(downloadPath); - item->accept(); - - connect(item, &QWebEngineDownloadItem::stateChanged, [&, item](QWebEngineDownloadItem::DownloadState downloadState) { - if (downloadState == QWebEngineDownloadItem::DownloadInterrupted) { - item->cancel(); - } - }); - - connect(item, &QWebEngineDownloadItem::finished, [&, item]() { - QCOMPARE(item->isFinished(), true); - QCOMPARE(item->totalBytes(), item->receivedBytes()); - QVERIFY(item->receivedBytes() > 0); - QCOMPARE(item->page(), m_page); - }); - }); - - QString oldPath = QDir::currentPath(); - QDir::setCurrent(tmpDir.path()); - - // Set only the file name. - downloadItem.clear(); - originalDownloadPath = ""; - downloadPath = fileName; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadItem); - QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted); - QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(downloadItem->path(), fileName); - - // Set only the directory path. - downloadItem.clear(); - originalDownloadPath = ""; - downloadPath = tmpDir.path(); - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadItem); - QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted); - QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(downloadItem->path(), originalDownloadPath); - - // Set only the directory path with separator. - downloadItem.clear(); - originalDownloadPath = ""; - downloadPath = tmpDir.path() + QDir::separator(); - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadItem); - QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted); - QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(downloadItem->path(), originalDownloadPath); - - // Set only the directory with the current directory path without ending separator. - downloadItem.clear(); - originalDownloadPath = ""; - downloadPath = "."; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadItem); - QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted); - QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(downloadItem->path(), originalDownloadPath); - - // Set only the directory with the current directory path with ending separator. - downloadItem.clear(); - originalDownloadPath = ""; - downloadPath = "./"; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadItem); - QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted); - QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(downloadItem->path(), originalDownloadPath); - - downloadItem.clear(); - originalDownloadPath = ""; - downloadPath = "..."; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadItem); -#if !defined(Q_OS_WIN) - QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled); - QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileFailed); - QCOMPARE(downloadItem->path(), downloadPath); -#else - // Windows interprets the "..." path as a valid path. It will be the current path. - QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted); - QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason); - QCOMPARE(downloadItem->path(), originalDownloadPath); -#endif // !defined(Q_OS_WIN) - QDir::setCurrent(oldPath); -} - -void tst_QWebEngineDownloadItem::downloadToDirectoryWithFileName() -{ - QString downloadDirectory; - QString downloadFileName; - QString downloadedFilePath; - QString downloadedSuggestedFileName; - QString fileName = "test.txt"; - QString uniqueFileName = "test (1).txt"; - - 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) { - - if (!downloadDirectory.isEmpty()) { - item->setDownloadDirectory(downloadDirectory); - QCOMPARE(item->downloadDirectory(), downloadDirectory); - } - - if (!downloadFileName.isEmpty()) { - item->setDownloadFileName(downloadFileName); - QCOMPARE(item->downloadFileName(), downloadFileName); - } - - QCOMPARE(item->path(), QDir(item->downloadDirectory()).filePath(item->downloadFileName())); - 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 = QDir(item->downloadDirectory()).filePath(item->downloadFileName()); - downloadedSuggestedFileName = item->suggestedFileName(); - }); - }); - - // Download file to the default download directory. - downloadDirectory = ""; - downloadFileName = ""; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadFinished); - QVERIFY(QFile(downloadedFilePath).exists()); - QCOMPARE(downloadedFilePath, QDir(m_profile->downloadPath()).filePath(fileName)); - QCOMPARE(downloadedSuggestedFileName, fileName); - - // Download the same file to another directory - downloadFinished = false; - downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test1" + QDir::separator(); - downloadFileName = ""; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadFinished); - QVERIFY(QFile(downloadedFilePath).exists()); - QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(fileName)); - QCOMPARE(downloadedSuggestedFileName, fileName); - - // Download the same file to the same directory and the file name must be unique. - downloadFinished = false; - downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test1" + QDir::separator(); - downloadFileName = ""; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadFinished); - QVERIFY(QFile(downloadedFilePath).exists()); - QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(uniqueFileName)); - QCOMPARE(downloadedSuggestedFileName, fileName); - - // Download another file to the same directory and set file name by - // QWebEngineDownloadItem::setDownloadDirectory() and setDownloadFileName() to avoid uniquification. - downloadFinished = false; - downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test1" + QDir::separator(); - downloadFileName = "test1.txt"; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadFinished); - QVERIFY(QFile(downloadedFilePath).exists()); - QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(downloadFileName)); - QCOMPARE(downloadedSuggestedFileName, fileName); - - // Download the same file to another directory without uniquifying the file name - downloadFinished = false; - downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test2" + QDir::separator(); - downloadFileName = "test1.txt"; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadFinished); - QVERIFY(QFile(downloadedFilePath).exists()); - QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(downloadFileName)); - QCOMPARE(downloadedSuggestedFileName, fileName); - - // Download the same file to same directory and set file name by - // QWebEngineDownloadItem::setDownloadDirectory() and setDownloadFileName() to avoid uniquification. - downloadFinished = false; - downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test2" + QDir::separator(); - downloadFileName = "test1.txt"; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadFinished); - QVERIFY(QFile(downloadedFilePath).exists()); - QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(downloadFileName)); - QCOMPARE(downloadedSuggestedFileName, fileName); - - // Download the same file in the same directory. - // Use the suggested file name (test.txt) and the file name will not be unique because this file name don't yet exists. - downloadFinished = false; - downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test2" + QDir::separator(); - downloadFileName = ""; - m_page->setUrl(m_server->url("/" + fileName)); - QTRY_VERIFY(downloadFinished); - QVERIFY(QFile(downloadedFilePath).exists()); - QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(fileName)); - QCOMPARE(downloadedSuggestedFileName, fileName); -} - -QTEST_MAIN(tst_QWebEngineDownloadItem) -#include "tst_qwebenginedownloaditem.moc" |