diff options
-rw-r--r-- | src/core/cookie_monster_delegate_qt.h | 7 | ||||
-rw-r--r-- | src/core/type_conversion.h | 3 | ||||
-rw-r--r-- | src/core/url_request_context_getter_qt.cpp | 1 | ||||
-rw-r--r-- | tests/auto/auto.pro | 2 | ||||
-rw-r--r-- | tests/auto/core/core.pro | 6 | ||||
-rw-r--r-- | tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro | 2 | ||||
-rw-r--r-- | tests/auto/core/qwebenginecookiestoreclient/resources/content.html | 5 | ||||
-rw-r--r-- | tests/auto/core/qwebenginecookiestoreclient/resources/index.html | 38 | ||||
-rw-r--r-- | tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp | 212 | ||||
-rw-r--r-- | tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc | 6 | ||||
-rw-r--r-- | tests/auto/core/tests.pri | 18 |
11 files changed, 299 insertions, 1 deletions
diff --git a/src/core/cookie_monster_delegate_qt.h b/src/core/cookie_monster_delegate_qt.h index 971a09bbc..e5e295853 100644 --- a/src/core/cookie_monster_delegate_qt.h +++ b/src/core/cookie_monster_delegate_qt.h @@ -55,6 +55,13 @@ QT_FORWARD_DECLARE_CLASS(QWebEngineCookieStoreClient) namespace QtWebEngineCore { +// Extends net::CookieMonster::kDefaultCookieableSchemes with qrc, without enabling +// cookies for the file:// scheme, which is disabled by default in Chromium. +// Since qrc:// is similar to file:// and there are some unknowns about how +// to correctly handle file:// cookies, qrc:// should only be used for testing. +static const char* const kCookieableSchemes[] = + { "http", "https", "qrc", "ws", "wss" }; + class QWEBENGINE_EXPORT CookieMonsterDelegateQt: public net::CookieMonsterDelegate { QPointer<QWebEngineCookieStoreClient> m_client; scoped_refptr<net::CookieMonster> m_cookieMonster; diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index d49edd203..9e5461888 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -158,7 +158,8 @@ inline QNetworkCookie toQt(const net::CanonicalCookie & cookie) { QNetworkCookie qCookie = QNetworkCookie(QByteArray::fromStdString(cookie.Name()), QByteArray::fromStdString(cookie.Value())); qCookie.setDomain(toQt(cookie.Domain())); - qCookie.setExpirationDate(toQt(cookie.ExpiryDate())); + if (!cookie.ExpiryDate().is_null()) + qCookie.setExpirationDate(toQt(cookie.ExpiryDate())); qCookie.setHttpOnly(cookie.IsHttpOnly()); qCookie.setPath(toQt(cookie.Path())); qCookie.setSecure(cookie.IsSecure()); diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 1205e3674..caad543ff 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -226,6 +226,7 @@ void URLRequestContextGetterQt::generateCookieStore() m_storage->set_cookie_store(cookieStore); net::CookieMonster * const cookieMonster = cookieStore->GetCookieMonster(); + cookieMonster->SetCookieableSchemes(kCookieableSchemes, arraysize(kCookieableSchemes)); m_cookieDelegate->setCookieMonster(cookieMonster); } diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index f14305f72..06430cf8e 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -4,4 +4,6 @@ SUBDIRS = quick qtHaveModule(webenginewidgets) { SUBDIRS += widgets +# core tests depend on widgets for now + SUBDIRS += core } diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro new file mode 100644 index 000000000..c727bc9cc --- /dev/null +++ b/tests/auto/core/core.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs + +CONFIG += ordered + +SUBDIRS += \ + qwebenginecookiestoreclient \ diff --git a/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro b/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro new file mode 100644 index 000000000..ff6c49628 --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro @@ -0,0 +1,2 @@ +include(../tests.pri) +exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/core/qwebenginecookiestoreclient/resources/content.html b/tests/auto/core/qwebenginecookiestoreclient/resources/content.html new file mode 100644 index 000000000..360ad65ef --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/resources/content.html @@ -0,0 +1,5 @@ +<html> +<body> +<a>This is test content</a> +</body> +</html> diff --git a/tests/auto/core/qwebenginecookiestoreclient/resources/index.html b/tests/auto/core/qwebenginecookiestoreclient/resources/index.html new file mode 100644 index 000000000..d41866712 --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/resources/index.html @@ -0,0 +1,38 @@ +<html> + <head> + <script type="text/javascript"> + function generateCookieString(key, value, options) { + key = key.replace(/[^#$&+\^`|]/g, encodeURIComponent); + key = key.replace(/\(/g, '%28').replace(/\)/g, '%29'); + value = (value + '').replace(/[^!#$&-+\--:<-\[\]-~]/g, encodeURIComponent); + options = options || {}; + + var cookieString = key + '=' + value; + cookieString += options.path ? '; Path=' + options.path : ''; + cookieString += options.domain ? '; Domain=' + options.domain : ''; + cookieString += options.expires ? '; Expires=' + options.expires.toUTCString() : ''; + cookieString += options.secure ? '; Secure' : ''; + + console.log(cookieString) + return cookieString; +}; +function setCookie() { + var name = "SessionCookie" + var value = "QtWebEngineCookieTest" + document.cookie = generateCookieString(name, value, {}) + + name = "CookieWithExpiresField" + value = "QtWebEngineCookieTest" + var daysValid = 10; + var date = new Date(); + date.setTime(date.getTime() + (daysValid*24*60*60*1000)); + var expires = date; + var options = {}; + options.expires = expires; + document.cookie = generateCookieString(name, value, options) +} +</script> + </head> + <body onload="setCookie()"> + </body> +</html> diff --git a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp new file mode 100644 index 000000000..0f007d643 --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../widgets/util.h" +#include <QtTest/QtTest> +#include <QtWebEngineCore/qwebenginecallback.h> +#include <QtWebEngineCore/qwebenginecookiestoreclient.h> +#include <QtWebEngineWidgets/qwebenginepage.h> +#include <QtWebEngineWidgets/qwebengineprofile.h> +#include <QtWebEngineWidgets/qwebengineview.h> + +class tst_QWebEngineCookieStoreClient : public QObject +{ + Q_OBJECT + +public: + tst_QWebEngineCookieStoreClient(); + ~tst_QWebEngineCookieStoreClient(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void cookieSignals(); + void setAndDeleteCookie(); + void batchCookieTasks(); +}; + +tst_QWebEngineCookieStoreClient::tst_QWebEngineCookieStoreClient() +{ +} + +tst_QWebEngineCookieStoreClient::~tst_QWebEngineCookieStoreClient() +{ +} + +void tst_QWebEngineCookieStoreClient::init() +{ +} + +void tst_QWebEngineCookieStoreClient::cleanup() +{ +} + +void tst_QWebEngineCookieStoreClient::initTestCase() +{ +} + +void tst_QWebEngineCookieStoreClient::cleanupTestCase() +{ +} + +void tst_QWebEngineCookieStoreClient::cookieSignals() +{ + QWebEngineView view; + QWebEngineCookieStoreClient client; + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + QSignalSpy cookieAddedSpy(&client, SIGNAL(cookieAdded(const QNetworkCookie &))); + QSignalSpy cookieRemovedSpy(&client, SIGNAL(cookieRemoved(const QNetworkCookie &))); + + view.page()->profile()->setCookieStoreClient(&client); + + view.load(QUrl("qrc:///resources/index.html")); + + QTRY_COMPARE(loadSpy.count(), 1); + QVariant success = loadSpy.takeFirst().takeFirst(); + QVERIFY(success.toBool()); + QTRY_COMPARE(cookieAddedSpy.count(), 2); + + // try whether updating a cookie to be expired results in that cookie being removed. + QNetworkCookie expiredCookie(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=delete; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=///resources")).first()); + client.setCookie(expiredCookie, QUrl("qrc:///resources/index.html")); + QTRY_COMPARE(cookieRemovedSpy.count(), 1); + cookieRemovedSpy.clear(); + + // try removing the other cookie. + QNetworkCookie nonSessionCookie(QNetworkCookie::parseCookies(QByteArrayLiteral("CookieWithExpiresField=QtWebEngineCookieTest; path=///resources")).first()); + client.deleteCookie(nonSessionCookie, QUrl("qrc:///resources/index.html")); + QTRY_COMPARE(cookieRemovedSpy.count(), 1); +} + +void tst_QWebEngineCookieStoreClient::setAndDeleteCookie() +{ + QWebEngineView view; + QWebEngineCookieStoreClient client; + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + QSignalSpy cookieAddedSpy(&client, SIGNAL(cookieAdded(const QNetworkCookie &))); + QSignalSpy cookieRemovedSpy(&client, SIGNAL(cookieRemoved(const QNetworkCookie &))); + + QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first()); + QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first()); + QNetworkCookie cookie3(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=QtWebEngineCookieTest; Path=///resources")).first()); + QNetworkCookie expiredCookie3(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=delete; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=///resources")).first()); + + // check if pending cookies are set and removed + client.setCookieWithCallback(cookie1, [](bool success) { QVERIFY(success); }); + client.setCookieWithCallback(cookie2, [](bool success) { QVERIFY(success); }); + client.deleteCookie(cookie1); + + view.page()->profile()->setCookieStoreClient(&client); + view.load(QUrl("qrc:///resources/content.html")); + + QTRY_COMPARE(loadSpy.count(), 1); + QVariant success = loadSpy.takeFirst().takeFirst(); + QVERIFY(success.toBool()); + QTRY_COMPARE(cookieAddedSpy.count(), 2); + QTRY_COMPARE(cookieRemovedSpy.count(), 1); + cookieAddedSpy.clear(); + cookieRemovedSpy.clear(); + + client.setCookieWithCallback(cookie3, [](bool success) { QVERIFY(success); }); + // updating a cookie with an expired 'expires' field should remove the cookie with the same name + client.setCookieWithCallback(expiredCookie3, [](bool success) { QVERIFY(success); }); + client.deleteCookie(cookie2); + QTRY_COMPARE(cookieAddedSpy.count(), 1); + QTRY_COMPARE(cookieRemovedSpy.count(), 2); +} + +void tst_QWebEngineCookieStoreClient::batchCookieTasks() +{ + QWebEngineView view; + QWebEngineCookieStoreClient client; + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + QSignalSpy cookieAddedSpy(&client, SIGNAL(cookieAdded(const QNetworkCookie &))); + QSignalSpy cookieRemovedSpy(&client, SIGNAL(cookieRemoved(const QNetworkCookie &))); + + QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first()); + QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first()); + + int capture = 0; + + client.setCookieWithCallback(cookie1, [&capture](bool success) { QVERIFY(success); ++capture; }); + client.setCookieWithCallback(cookie2, [&capture](bool success) { QVERIFY(success); ++capture; }); + + view.page()->profile()->setCookieStoreClient(&client); + view.load(QUrl("qrc:///resources/index.html")); + + QTRY_COMPARE(loadSpy.count(), 1); + QVariant success = loadSpy.takeFirst().takeFirst(); + QVERIFY(success.toBool()); + QTRY_COMPARE(cookieAddedSpy.count(), 4); + QTRY_COMPARE(cookieRemovedSpy.count(), 0); + QTRY_COMPARE(capture, 2); + capture = 0; + + cookieAddedSpy.clear(); + cookieRemovedSpy.clear(); + + client.getAllCookies([&capture](const QByteArray& cookieLine) { + ++capture; + QCOMPARE(QNetworkCookie::parseCookies(cookieLine).count(), 4); + }); + + client.deleteSessionCookiesWithCallback([&capture](int numDeleted) { + ++capture; + QCOMPARE(numDeleted, 3); + }); + + client.deleteAllCookiesWithCallback([&capture](int numDeleted) { + ++capture; + QCOMPARE(numDeleted, 1); + }); + + QTRY_COMPARE(capture, 3); +} + +QTEST_MAIN(tst_QWebEngineCookieStoreClient) +#include "tst_qwebenginecookiestoreclient.moc" diff --git a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc new file mode 100644 index 000000000..afeae268b --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>resources/index.html</file> + <file>resources/content.html</file> +</qresource> +</RCC> diff --git a/tests/auto/core/tests.pri b/tests/auto/core/tests.pri new file mode 100644 index 000000000..7046487db --- /dev/null +++ b/tests/auto/core/tests.pri @@ -0,0 +1,18 @@ +TEMPLATE = app + +# FIXME: Re-enable once we want to run tests on the CI +# CONFIG += testcase + +CONFIG += c++11 + +VPATH += $$_PRO_FILE_PWD_ +TARGET = tst_$$TARGET + +SOURCES += $${TARGET}.cpp +INCLUDEPATH += $$PWD + +QT += testlib network webenginewidgets widgets +osx: CONFIG -= app_bundle + +# This define is used by some tests to look up resources in the source tree +DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD/\\\" |