Changeset View
Changeset View
Standalone View
Standalone View
webenginepart/autotests/webenginepartcookiejar_test.cpp
Show All 26 Lines | |||||
27 | #include <QTest> | 27 | #include <QTest> | ||
28 | 28 | | |||
29 | #include <QNetworkCookie> | 29 | #include <QNetworkCookie> | ||
30 | #include <QWebEngineCookieStore> | 30 | #include <QWebEngineCookieStore> | ||
31 | #include <QWebEngineProfile> | 31 | #include <QWebEngineProfile> | ||
32 | #include <QDBusInterface> | 32 | #include <QDBusInterface> | ||
33 | #include <QDBusReply> | 33 | #include <QDBusReply> | ||
34 | 34 | | |||
35 | #include <algorithm> | ||||
36 | | ||||
37 | //Cookie expiration dates returned by KCookieServer always have msecs set to 0 | ||||
38 | static QDateTime currentDateTime(){return QDateTime::fromSecsSinceEpoch(QDateTime::currentMSecsSinceEpoch()/1000);} | ||||
39 | | ||||
40 | namespace QTest { | ||||
41 | template <> | ||||
42 | char *toString(const QNetworkCookie &cookie){ | ||||
43 | QByteArray ba = "QNetworkCookie{"; | ||||
44 | ba += "\nname: " + cookie.name(); | ||||
45 | ba += "\ndomain: " + (cookie.domain().isEmpty() ? "<EMPTY>" : cookie.domain()); | ||||
46 | ba += "\npath: " + (cookie.path().isEmpty() ? "<EMPTY>" : cookie.path()); | ||||
47 | ba += "\nvalue: " + cookie.value(); | ||||
48 | ba += "\nexpiration: " + (cookie.expirationDate().isValid() ? QString::number(cookie.expirationDate().toMSecsSinceEpoch()) : "<INVALID>"); | ||||
49 | ba += "\nsecure: " + QString::number(cookie.isSecure()); | ||||
50 | ba += "\nhttp: only" + QString::number(cookie.isHttpOnly()); | ||||
51 | return qstrdup(ba.data()); | ||||
52 | } | ||||
53 | } | ||||
54 | | ||||
35 | QTEST_MAIN(TestWebEnginePartCookieJar); | 55 | QTEST_MAIN(TestWebEnginePartCookieJar); | ||
36 | 56 | | |||
37 | void TestWebEnginePartCookieJar::initTestCase() | 57 | void TestWebEnginePartCookieJar::initTestCase() | ||
38 | { | 58 | { | ||
39 | m_cookieName = "webenginepartcookiejartest"; | 59 | m_cookieName = "webenginepartcookiejartest"; | ||
40 | } | 60 | } | ||
41 | 61 | | |||
42 | void TestWebEnginePartCookieJar::init() | 62 | void TestWebEnginePartCookieJar::init() | ||
▲ Show 20 Lines • Show All 198 Lines • ▼ Show 20 Line(s) | |||||
241 | 261 | | |||
242 | void TestWebEnginePartCookieJar::testCookieRemovedFromStoreAreRemovedFromKCookieServer() | 262 | void TestWebEnginePartCookieJar::testCookieRemovedFromStoreAreRemovedFromKCookieServer() | ||
243 | { | 263 | { | ||
244 | QFETCH(const QNetworkCookie, cookie); | 264 | QFETCH(const QNetworkCookie, cookie); | ||
245 | QFETCH(const QString, name); | 265 | QFETCH(const QString, name); | ||
246 | QFETCH(const QString, domain); | 266 | QFETCH(const QString, domain); | ||
247 | QFETCH(const QString, host); | 267 | QFETCH(const QString, host); | ||
248 | 268 | | |||
249 | const QString url = "https://" + host; | | |||
250 | | ||||
251 | //cookie is in the "format" used by QWebEngineCookieStore, which means that, if the domain should be empty, | | |||
252 | //it is stored as a domain not starting with a dot. KCookieServer, instead, wants cookies without domains | | |||
253 | //to actually have no domain, so we have to change it | | |||
254 | QNetworkCookie kcookieServerCookie(cookie); | | |||
255 | if (!kcookieServerCookie.domain().startsWith('.')) { | | |||
256 | kcookieServerCookie.setDomain(QString()); | | |||
257 | } | | |||
258 | const QByteArray setCookie = "Set-Cookie: " + kcookieServerCookie.toRawForm(); | | |||
259 | | ||||
260 | //Add cookie to KCookieServer | 269 | //Add cookie to KCookieServer | ||
261 | QDBusMessage rep = m_server->call(QDBus::Block, "addCookies", url, setCookie, static_cast<qlonglong>(0)); | 270 | QDBusError e = addCookieToKCookieServer(cookie, host); | ||
262 | QVERIFY2(!m_server->lastError().isValid(), qPrintable(m_server->lastError().message())); | 271 | QVERIFY2(!e.isValid(), qPrintable(m_server->lastError().message())); | ||
263 | 272 | | |||
264 | //Ensure cookie has been added to KCookieServer | 273 | //Ensure cookie has been added to KCookieServer | ||
265 | QDBusReply<QStringList> reply = m_server->call(QDBus::Block, "findCookies", QVariant::fromValue(QList<int>{2}), domain, host, "", ""); | 274 | QDBusReply<QStringList> reply = m_server->call(QDBus::Block, "findCookies", QVariant::fromValue(QList<int>{2}), domain, host, "", ""); | ||
266 | QVERIFY2(reply.isValid(), qPrintable(reply.error().message())); | 275 | QVERIFY2(reply.isValid(), qPrintable(reply.error().message())); | ||
267 | QStringList cookies = reply.value(); | 276 | QStringList cookies = reply.value(); | ||
268 | QVERIFY2(cookies.contains(name), "Cookie wasn't added to server"); | 277 | QVERIFY2(cookies.contains(name), "Cookie wasn't added to server"); | ||
269 | 278 | | |||
270 | //Emit QWebEngineCookieStore::cookieRemoved signal and check that cookie has indeed been removed | 279 | //Emit QWebEngineCookieStore::cookieRemoved signal and check that cookie has indeed been removed | ||
271 | emit m_store->cookieRemoved(cookie); | 280 | emit m_store->cookieRemoved(cookie); | ||
272 | reply = m_server->call(QDBus::Block, "findCookies", QVariant::fromValue(QList<int>{2}), domain, "", "", ""); | 281 | reply = m_server->call(QDBus::Block, "findCookies", QVariant::fromValue(QList<int>{2}), domain, "", "", ""); | ||
273 | QVERIFY2(reply.isValid(), qPrintable(reply.error().message())); | 282 | QVERIFY2(reply.isValid(), qPrintable(reply.error().message())); | ||
274 | cookies = reply.value(); | 283 | cookies = reply.value(); | ||
275 | QVERIFY2(!cookies.contains(name), "Cookie wasn't removed from server"); | 284 | QVERIFY2(!cookies.contains(name), "Cookie wasn't removed from server"); | ||
276 | } | 285 | } | ||
286 | | ||||
287 | QDBusError TestWebEnginePartCookieJar::addCookieToKCookieServer(const QNetworkCookie& _cookie, const QString& host) | ||||
288 | { | ||||
289 | QNetworkCookie cookie(_cookie); | ||||
290 | QUrl url; | ||||
291 | url.setHost(host); | ||||
292 | url.setScheme(cookie.isSecure() ? "https" : "http"); | ||||
293 | if (!cookie.domain().startsWith('.')) { | ||||
294 | cookie.setDomain(QString()); | ||||
295 | } | ||||
296 | const QByteArray setCookie = "Set-Cookie: " + cookie.toRawForm(); | ||||
297 | m_server->call(QDBus::Block, "addCookies", url.toString(), setCookie, static_cast<qlonglong>(0)); | ||||
298 | return m_server->lastError(); | ||||
299 | } | ||||
300 | | ||||
301 | void TestWebEnginePartCookieJar::testPersistentCookiesAreAddedToStoreOnCreation() | ||||
302 | { | ||||
303 | delete m_jar; | ||||
304 | QDateTime exp = QDateTime::currentDateTime().addYears(1); | ||||
305 | QString baseCookieName = m_cookieName + "-startup"; | ||||
306 | QList<CookieData> data { | ||||
307 | {baseCookieName + "-persistent", "test-value", ".yyy.xxx.com", "/abc/def/", "zzz.yyy.xxx.com", currentDateTime().addYears(1), true}, | ||||
308 | {baseCookieName + "-no-path", "test-value", ".yyy.xxx.com", "", "zzz.yyy.xxx.com", currentDateTime().addYears(1), true}, | ||||
309 | {baseCookieName + "-no-domain", "test-value", "", "/abc/def/", "zzz.yyy.xxx.com", currentDateTime().addYears(1), true}, | ||||
310 | {baseCookieName + "-no-secure", "test-value", ".yyy.xxx.com", "/abc/def/", "zzz.yyy.xxx.com", currentDateTime().addYears(1), false} | ||||
311 | }; | ||||
312 | QList<QNetworkCookie> expected; | ||||
313 | for(const CookieData &d: data){ | ||||
314 | QNetworkCookie c = d.cookie(); | ||||
315 | QDBusError e = addCookieToKCookieServer(c, d.host); | ||||
316 | QVERIFY2(!e.isValid(), qPrintable(e.message())); | ||||
317 | //In case of an empty domain, WebEnginePartCookieJar will use QNetworkCookie::normalize on the cookie | ||||
318 | if (c.domain().isEmpty()) { | ||||
319 | c.setDomain(d.host); | ||||
320 | } | ||||
321 | expected << c; | ||||
322 | } | ||||
323 | m_jar = new WebEnginePartCookieJar(m_profile, this); | ||||
324 | QList<QNetworkCookie> cookiesInsertedIntoJar; | ||||
325 | for(const QNetworkCookie &c: qAsConst(m_jar->m_testCookies)){ | ||||
dfaure: qAsConst | |||||
326 | if(QString(c.name()).startsWith(baseCookieName)) { | ||||
327 | cookiesInsertedIntoJar << c; | ||||
328 | } | ||||
329 | } | ||||
330 | | ||||
331 | //Ensure that cookies in the two lists are in the same order before comparing them | ||||
332 | //(the order in cookiesInsertedIntoJar depends on the order KCookieServer::findCookies | ||||
333 | //returns them) | ||||
334 | auto sortLambda = [](const QNetworkCookie &c1, const QNetworkCookie &c2){ | ||||
dfaure: Const ref missing for c1 and c2 | |||||
335 | return c1.name() < c2.name(); | ||||
336 | }; | ||||
337 | std::sort(cookiesInsertedIntoJar.begin(), cookiesInsertedIntoJar.end(), sortLambda); | ||||
338 | std::sort(expected.begin(), expected.end(), sortLambda); | ||||
339 | | ||||
340 | QCOMPARE(cookiesInsertedIntoJar, expected); | ||||
341 | } | ||||
342 | | ||||
343 | void TestWebEnginePartCookieJar::testSessionCookiesAreNotAddedToStoreOnCreation() | ||||
344 | { | ||||
345 | delete m_jar; | ||||
346 | CookieData data{m_cookieName + "-startup-session", "test-value", ".yyy.xxx.com", "/abc/def", "zzz.yyy.xxx.com", QDateTime(), true}; | ||||
347 | QDBusError e = addCookieToKCookieServer(data.cookie(), data.host); | ||||
348 | QVERIFY2(!e.isValid(), qPrintable(e.message())); | ||||
349 | m_jar = new WebEnginePartCookieJar(m_profile, this); | ||||
350 | QList<QNetworkCookie> cookiesInsertedIntoJar; | ||||
351 | for(const QNetworkCookie &c: qAsConst(m_jar->m_testCookies)) { | ||||
dfaure: qAsConst | |||||
352 | if (c.name() == data.name) { | ||||
353 | cookiesInsertedIntoJar << c; | ||||
354 | } | ||||
355 | } | ||||
356 | QVERIFY2(cookiesInsertedIntoJar.isEmpty(), "Session cookies inserted into cookie store"); | ||||
357 | } | ||||
358 | |
qAsConst