1/*
2 * Copyright (C) 2017 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2,1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21
22#include "WebKitTestServer.h"
23#include "WebViewTest.h"
24#include <glib/gstdio.h>
25
26static WebKitTestServer* kServer;
27
28static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
29{
30 if (message->method != SOUP_METHOD_GET) {
31 soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
32 return;
33 }
34
35 if (g_str_equal(path, "/empty")) {
36 static const char* emptyHTML = "<html><body></body></html>";
37 soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar; Max-Age=60");
38 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, emptyHTML, strlen(emptyHTML));
39 soup_message_body_complete(message->response_body);
40 soup_message_set_status(message, SOUP_STATUS_OK);
41 } else if (g_str_equal(path, "/appcache")) {
42 static const char* appcacheHTML = "<html manifest=appcache.manifest><body></body></html>";
43 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheHTML, strlen(appcacheHTML));
44 soup_message_body_complete(message->response_body);
45 soup_message_set_status(message, SOUP_STATUS_OK);
46 } else if (g_str_equal(path, "/appcache.manifest")) {
47 static const char* appcacheManifest = "CACHE MANIFEST\nCACHE:\nappcache/foo.txt\n";
48 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, appcacheManifest, strlen(appcacheManifest));
49 soup_message_body_complete(message->response_body);
50 soup_message_set_status(message, SOUP_STATUS_OK);
51 } else if (g_str_equal(path, "/appcache/foo.txt")) {
52 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, "foo", 3);
53 soup_message_body_complete(message->response_body);
54 soup_message_set_status(message, SOUP_STATUS_OK);
55 } else if (g_str_equal(path, "/sessionstorage")) {
56 static const char* sessionStorageHTML = "<html><body onload=\"sessionStorage.foo = 'bar';\"></body></html>";
57 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, sessionStorageHTML, strlen(sessionStorageHTML));
58 soup_message_body_complete(message->response_body);
59 soup_message_set_status(message, SOUP_STATUS_OK);
60 } else if (g_str_equal(path, "/localstorage")) {
61 static const char* localStorageHTML = "<html><body onload=\"localStorage.foo = 'bar';\"></body></html>";
62 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, localStorageHTML, strlen(localStorageHTML));
63 soup_message_body_complete(message->response_body);
64 soup_message_set_status(message, SOUP_STATUS_OK);
65 } else if (g_str_equal(path, "/enumeratedevices")) {
66 static const char* enumerateDevicesHTML = "<html><body onload=\"navigator.mediaDevices.enumerateDevices().then(function(devices) { document.title = 'Finished'; })\"></body></html>";
67 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, enumerateDevicesHTML, strlen(enumerateDevicesHTML));
68 soup_message_body_complete(message->response_body);
69 soup_message_set_status(message, SOUP_STATUS_OK);
70 } else
71 soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
72}
73
74class WebsiteDataTest : public WebViewTest {
75public:
76 MAKE_GLIB_TEST_FIXTURE(WebsiteDataTest);
77
78
79 WebsiteDataTest()
80 : m_manager(webkit_web_context_get_website_data_manager(webkit_web_view_get_context(m_webView)))
81 {
82 g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(m_manager));
83 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_manager));
84 // WebsiteDataStore creates a new WebProcessPool when used before any secondary process has been created.
85 // Ensure we have a web process by always loading about:blank here.
86 loadURI("about:blank");
87 waitUntilLoadFinished();
88 }
89
90 ~WebsiteDataTest()
91 {
92 g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
93 }
94
95 GList* fetch(WebKitWebsiteDataTypes types)
96 {
97 if (m_dataList) {
98 g_list_free_full(m_dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
99 m_dataList = nullptr;
100 }
101 webkit_website_data_manager_fetch(m_manager, types, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
102 WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData);
103 test->m_dataList = webkit_website_data_manager_fetch_finish(test->m_manager, result, nullptr);
104 test->quitMainLoop();
105 }, this);
106 g_main_loop_run(m_mainLoop);
107 return m_dataList;
108 }
109
110 void remove(WebKitWebsiteDataTypes types, GList* dataList)
111 {
112 webkit_website_data_manager_remove(m_manager, types, dataList, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
113 WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData);
114 g_assert_true(webkit_website_data_manager_remove_finish(test->m_manager, result, nullptr));
115 test->quitMainLoop();
116 }, this);
117 g_main_loop_run(m_mainLoop);
118 }
119
120 void clear(WebKitWebsiteDataTypes types, GTimeSpan timeSpan)
121 {
122 webkit_website_data_manager_clear(m_manager, types, timeSpan, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
123 WebsiteDataTest* test = static_cast<WebsiteDataTest*>(userData);
124 g_assert_true(webkit_website_data_manager_clear_finish(test->m_manager, result, nullptr));
125 test->quitMainLoop();
126 }, this);
127 g_main_loop_run(m_mainLoop);
128 }
129
130 WebKitWebsiteDataManager* m_manager;
131 GList* m_dataList { nullptr };
132};
133
134static void testWebsiteDataConfiguration(WebsiteDataTest* test, gconstpointer)
135{
136 // Base directories are not used by TestMain.
137 g_assert_null(webkit_website_data_manager_get_base_data_directory(test->m_manager));
138 g_assert_null(webkit_website_data_manager_get_base_cache_directory(test->m_manager));
139
140 GUniquePtr<char> localStorageDirectory(g_build_filename(Test::dataDirectory(), "local-storage", nullptr));
141 g_assert_cmpstr(localStorageDirectory.get(), ==, webkit_website_data_manager_get_local_storage_directory(test->m_manager));
142 g_assert_true(g_file_test(localStorageDirectory.get(), G_FILE_TEST_IS_DIR));
143
144 test->loadURI(kServer->getURIForPath("/empty").data());
145 test->waitUntilLoadFinished();
146 test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr);
147 GUniquePtr<char> indexedDBDirectory(g_build_filename(Test::dataDirectory(), "indexeddb", nullptr));
148 g_assert_cmpstr(indexedDBDirectory.get(), ==, webkit_website_data_manager_get_indexeddb_directory(test->m_manager));
149 g_assert_true(g_file_test(indexedDBDirectory.get(), G_FILE_TEST_IS_DIR));
150
151 GUniquePtr<char> webSQLDirectory(g_build_filename(Test::dataDirectory(), "websql", nullptr));
152 g_assert_cmpstr(webSQLDirectory.get(), ==, webkit_website_data_manager_get_websql_directory(test->m_manager));
153 test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);", nullptr);
154 g_assert_true(g_file_test(webSQLDirectory.get(), G_FILE_TEST_IS_DIR));
155
156 test->loadURI(kServer->getURIForPath("/appcache").data());
157 test->waitUntilLoadFinished();
158 GUniquePtr<char> applicationCacheDirectory(g_build_filename(Test::dataDirectory(), "appcache", nullptr));
159 g_assert_cmpstr(applicationCacheDirectory.get(), ==, webkit_website_data_manager_get_offline_application_cache_directory(test->m_manager));
160 GUniquePtr<char> applicationCacheDatabase(g_build_filename(applicationCacheDirectory.get(), "ApplicationCache.db", nullptr));
161 unsigned triesCount = 4;
162 while (!g_file_test(applicationCacheDatabase.get(), G_FILE_TEST_IS_REGULAR) && --triesCount)
163 test->wait(0.25);
164 g_assert_cmpuint(triesCount, >, 0);
165
166 GUniquePtr<char> diskCacheDirectory(g_build_filename(Test::dataDirectory(), "disk-cache", nullptr));
167 g_assert_cmpstr(diskCacheDirectory.get(), ==, webkit_website_data_manager_get_disk_cache_directory(test->m_manager));
168 g_assert_true(g_file_test(diskCacheDirectory.get(), G_FILE_TEST_IS_DIR));
169
170 // Clear all persistent caches, since the data dir is common to all test cases.
171 static const WebKitWebsiteDataTypes persistentCaches = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DISK_CACHE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE
172 | WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES | WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE | WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
173 test->clear(persistentCaches, 0);
174 g_assert_null(test->fetch(persistentCaches));
175
176 // The default context should have a different manager with different configuration.
177 WebKitWebsiteDataManager* defaultManager = webkit_web_context_get_website_data_manager(webkit_web_context_get_default());
178 g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(defaultManager));
179 g_assert_true(test->m_manager != defaultManager);
180 g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(test->m_manager), !=, webkit_website_data_manager_get_local_storage_directory(defaultManager));
181 g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(test->m_manager), !=, webkit_website_data_manager_get_indexeddb_directory(defaultManager));
182 g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_disk_cache_directory(defaultManager));
183 g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(test->m_manager), !=, webkit_website_data_manager_get_offline_application_cache_directory(defaultManager));
184 g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(test->m_manager), !=, webkit_website_data_manager_get_websql_directory(defaultManager));
185
186 // Using Test::dataDirectory() we get the default configuration but for a differrent prefix.
187 GRefPtr<WebKitWebsiteDataManager> baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(), nullptr));
188 g_assert_true(WEBKIT_IS_WEBSITE_DATA_MANAGER(baseDataManager.get()));
189
190 localStorageDirectory.reset(g_build_filename(Test::dataDirectory(), "localstorage", nullptr));
191 g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get());
192
193 indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", "indexeddb", nullptr));
194 g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get());
195
196 applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "applications", nullptr));
197 g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get());
198
199 webSQLDirectory.reset(g_build_filename(Test::dataDirectory(), "databases", nullptr));
200 g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get());
201
202 g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory());
203
204 // Any specific configuration provided takes precedence over base dirs.
205 indexedDBDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomindexeddb", nullptr));
206 applicationCacheDirectory.reset(g_build_filename(Test::dataDirectory(), "mycustomappcache", nullptr));
207 baseDataManager = adoptGRef(webkit_website_data_manager_new("base-data-directory", Test::dataDirectory(), "base-cache-directory", Test::dataDirectory(),
208 "indexeddb-directory", indexedDBDirectory.get(), "offline-application-cache-directory", applicationCacheDirectory.get(), nullptr));
209 g_assert_cmpstr(webkit_website_data_manager_get_indexeddb_directory(baseDataManager.get()), ==, indexedDBDirectory.get());
210 g_assert_cmpstr(webkit_website_data_manager_get_offline_application_cache_directory(baseDataManager.get()), ==, applicationCacheDirectory.get());
211 // The result should be the same as previous manager.
212 g_assert_cmpstr(webkit_website_data_manager_get_local_storage_directory(baseDataManager.get()), ==, localStorageDirectory.get());
213 g_assert_cmpstr(webkit_website_data_manager_get_websql_directory(baseDataManager.get()), ==, webSQLDirectory.get());
214 g_assert_cmpstr(webkit_website_data_manager_get_disk_cache_directory(baseDataManager.get()), ==, Test::dataDirectory());
215}
216
217static void ephemeralViewloadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test)
218{
219 if (loadEvent != WEBKIT_LOAD_FINISHED)
220 return;
221 g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(ephemeralViewloadChanged), test);
222 test->quitMainLoop();
223}
224
225static void testWebsiteDataEphemeral(WebViewTest* test, gconstpointer)
226{
227 GRefPtr<WebKitWebsiteDataManager> manager = adoptGRef(webkit_website_data_manager_new_ephemeral());
228 g_assert_true(webkit_website_data_manager_is_ephemeral(manager.get()));
229 g_assert_null(webkit_website_data_manager_get_base_data_directory(manager.get()));
230 g_assert_null(webkit_website_data_manager_get_base_cache_directory(manager.get()));
231 g_assert_null(webkit_website_data_manager_get_local_storage_directory(manager.get()));
232 g_assert_null(webkit_website_data_manager_get_disk_cache_directory(manager.get()));
233 g_assert_null(webkit_website_data_manager_get_offline_application_cache_directory(manager.get()));
234 g_assert_null(webkit_website_data_manager_get_indexeddb_directory(manager.get()));
235 g_assert_null(webkit_website_data_manager_get_websql_directory(manager.get()));
236
237 // Configuration is ignored when is-ephemeral is used.
238 manager = adoptGRef(WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "base-data-directory", Test::dataDirectory(), "is-ephemeral", TRUE, nullptr)));
239 g_assert_true(webkit_website_data_manager_is_ephemeral(manager.get()));
240 g_assert_null(webkit_website_data_manager_get_base_data_directory(manager.get()));
241
242 // Non persistent data can be queried in an ephemeral manager.
243 GRefPtr<WebKitWebContext> webContext = adoptGRef(webkit_web_context_new_with_website_data_manager(manager.get()));
244 g_assert_true(webkit_web_context_is_ephemeral(webContext.get()));
245 auto webView = Test::adoptView(Test::createWebView(webContext.get()));
246 g_assert_true(webkit_web_view_is_ephemeral(webView.get()));
247 g_assert_true(webkit_web_view_get_website_data_manager(webView.get()) == manager.get());
248
249 g_signal_connect(webView.get(), "load-changed", G_CALLBACK(ephemeralViewloadChanged), test);
250 webkit_web_view_load_uri(webView.get(), kServer->getURIForPath("/empty").data());
251 g_main_loop_run(test->m_mainLoop);
252
253 webkit_website_data_manager_fetch(manager.get(), WEBKIT_WEBSITE_DATA_MEMORY_CACHE, nullptr, [](GObject* manager, GAsyncResult* result, gpointer userData) {
254 auto* test = static_cast<WebViewTest*>(userData);
255 GList* dataList = webkit_website_data_manager_fetch_finish(WEBKIT_WEBSITE_DATA_MANAGER(manager), result, nullptr);
256 g_assert_nonnull(dataList);
257 g_assert_cmpuint(g_list_length(dataList), ==, 1);
258 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data);
259 g_assert_nonnull(data);
260 WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
261 g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
262 webkit_security_origin_unref(origin);
263 g_list_free_full(dataList, reinterpret_cast<GDestroyNotify>(webkit_website_data_unref));
264 test->quitMainLoop();
265 }, test);
266 g_main_loop_run(test->m_mainLoop);
267}
268
269static void testWebsiteDataCache(WebsiteDataTest* test, gconstpointer)
270{
271 static const WebKitWebsiteDataTypes cacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
272 GList* dataList = test->fetch(cacheTypes);
273 g_assert_null(dataList);
274
275 test->loadURI(kServer->getURIForPath("/empty").data());
276 test->waitUntilLoadFinished();
277
278 // Disk cache delays the storing of initial resources for 1 second to avoid
279 // affecting early page load. So, wait 1 second here to make sure resources
280 // have already been stored.
281 test->wait(1);
282
283 dataList = test->fetch(cacheTypes);
284 g_assert_nonnull(dataList);
285 g_assert_cmpuint(g_list_length(dataList), ==, 1);
286 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data);
287 g_assert_nonnull(data);
288 WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
289 g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
290 webkit_security_origin_unref(origin);
291 g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheTypes);
292 // Memory cache size is unknown.
293 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_MEMORY_CACHE), ==, 0);
294 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_DISK_CACHE), >, 0);
295
296 // Try again but only getting disk cache.
297 dataList = test->fetch(WEBKIT_WEBSITE_DATA_DISK_CACHE);
298 g_assert_nonnull(dataList);
299 g_assert_cmpuint(g_list_length(dataList), ==, 1);
300 data = static_cast<WebKitWebsiteData*>(dataList->data);
301 g_assert_nonnull(data);
302 g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE);
303 g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE);
304
305 GUniquePtr<char> fileURL(g_strdup_printf("file://%s/simple.html", Test::getResourcesDir(Test::WebKit2Resources).data()));
306 test->loadURI(fileURL.get());
307 test->waitUntilLoadFinished();
308
309 fileURL.reset(g_strdup_printf("file://%s/simple2.html", Test::getResourcesDir(Test::WebKit2Resources).data()));
310 test->loadURI(fileURL.get());
311 test->waitUntilLoadFinished();
312
313 // Local files are grouped.
314 dataList = test->fetch(cacheTypes);
315 g_assert_nonnull(dataList);
316 g_assert_cmpuint(g_list_length(dataList), ==, 2);
317 GList* itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int {
318 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(const_cast<gpointer>(item));
319 return g_strcmp0(webkit_website_data_get_name(data), "Local files");
320 });
321 g_assert_nonnull(itemList);
322 data = static_cast<WebKitWebsiteData*>(itemList->data);
323 g_assert_nonnull(data);
324 g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_MEMORY_CACHE);
325 // Local files are never stored in disk cache.
326 g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE);
327
328 // Clear data modified since the last microsecond should not clear anything.
329 // Use disk-cache because memory cache ignores the modified since.
330 test->clear(WEBKIT_WEBSITE_DATA_DISK_CACHE, 1);
331 dataList = test->fetch(cacheTypes);
332 g_assert_nonnull(dataList);
333 g_assert_cmpuint(g_list_length(dataList), ==, 2);
334
335 // Remove memory cache only for local files.
336 itemList = g_list_find_custom(dataList, nullptr, [](gconstpointer item, gconstpointer) -> int {
337 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(const_cast<gpointer>(item));
338 return g_strcmp0(webkit_website_data_get_name(data), "Local files");
339 });
340 g_assert_nonnull(itemList);
341 GList removeList = { itemList->data, nullptr, nullptr };
342 test->remove(WEBKIT_WEBSITE_DATA_MEMORY_CACHE, &removeList);
343 dataList = test->fetch(cacheTypes);
344 g_assert_nonnull(dataList);
345 g_assert_cmpuint(g_list_length(dataList), ==, 1);
346 data = static_cast<WebKitWebsiteData*>(dataList->data);
347 g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_DISK_CACHE);
348
349 // Clear all.
350 test->clear(cacheTypes, 0);
351 dataList = test->fetch(cacheTypes);
352 g_assert_null(dataList);
353}
354
355static void testWebsiteDataStorage(WebsiteDataTest* test, gconstpointer)
356{
357 static const WebKitWebsiteDataTypes storageTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_SESSION_STORAGE | WEBKIT_WEBSITE_DATA_LOCAL_STORAGE);
358 GList* dataList = test->fetch(storageTypes);
359 g_assert_null(dataList);
360
361 test->loadURI(kServer->getURIForPath("/sessionstorage").data());
362 test->waitUntilLoadFinished();
363
364 test->loadURI(kServer->getURIForPath("/localstorage").data());
365 test->waitUntilLoadFinished();
366
367 // Local storage uses a 1 second timer to update the database.
368 test->wait(1);
369
370 dataList = test->fetch(storageTypes);
371 g_assert_nonnull(dataList);
372 g_assert_cmpuint(g_list_length(dataList), ==, 1);
373 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data);
374 g_assert_nonnull(data);
375 WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
376 g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
377 webkit_security_origin_unref(origin);
378 g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes);
379 // Storage sizes are unknown.
380 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_SESSION_STORAGE), ==, 0);
381 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_LOCAL_STORAGE), ==, 0);
382
383 // Get also cached data, and clear it.
384 static const WebKitWebsiteDataTypes cacheAndStorageTypes = static_cast<WebKitWebsiteDataTypes>(storageTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
385 dataList = test->fetch(cacheAndStorageTypes);
386 g_assert_nonnull(dataList);
387 g_assert_cmpuint(g_list_length(dataList), ==, 1);
388 data = static_cast<WebKitWebsiteData*>(dataList->data);
389 g_assert_nonnull(data);
390 g_assert_cmpuint(webkit_website_data_get_types(data), ==, cacheAndStorageTypes);
391 test->clear(static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE), 0);
392
393 // Get all types again, but only storage is retrieved now.
394 dataList = test->fetch(cacheAndStorageTypes);
395 g_assert_nonnull(dataList);
396 g_assert_cmpuint(g_list_length(dataList), ==, 1);
397 data = static_cast<WebKitWebsiteData*>(dataList->data);
398 g_assert_nonnull(data);
399 g_assert_cmpuint(webkit_website_data_get_types(data), ==, storageTypes);
400
401 // Remove the session storage.
402 GList removeList = { data, nullptr, nullptr };
403 test->remove(WEBKIT_WEBSITE_DATA_SESSION_STORAGE, &removeList);
404 dataList = test->fetch(storageTypes);
405 g_assert_nonnull(dataList);
406 g_assert_cmpuint(g_list_length(dataList), ==, 1);
407 data = static_cast<WebKitWebsiteData*>(dataList->data);
408 g_assert_false(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_SESSION_STORAGE);
409 g_assert_true(webkit_website_data_get_types(data) & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE);
410
411 // Clear all.
412 test->clear(cacheAndStorageTypes, 0);
413 dataList = test->fetch(cacheAndStorageTypes);
414 g_assert_null(dataList);
415}
416
417static void testWebsiteDataDatabases(WebsiteDataTest* test, gconstpointer)
418{
419 static const WebKitWebsiteDataTypes databaseTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES | WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES);
420 GList* dataList = test->fetch(databaseTypes);
421 g_assert_null(dataList);
422
423 test->loadURI(kServer->getURIForPath("/empty").data());
424 test->waitUntilLoadFinished();
425 test->runJavaScriptAndWaitUntilFinished("window.indexedDB.open('TestDatabase');", nullptr);
426
427 dataList = test->fetch(databaseTypes);
428 g_assert_nonnull(dataList);
429 g_assert_cmpuint(g_list_length(dataList), ==, 1);
430 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data);
431 g_assert_nonnull(data);
432 WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
433 g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
434 webkit_security_origin_unref(origin);
435 g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES);
436 // Database sizes are unknown.
437 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0);
438
439 test->runJavaScriptAndWaitUntilFinished("db = openDatabase(\"TestDatabase\", \"1.0\", \"TestDatabase\", 1);", nullptr);
440 dataList = test->fetch(databaseTypes);
441 g_assert_nonnull(dataList);
442 g_assert_cmpuint(g_list_length(dataList), ==, 1);
443 data = static_cast<WebKitWebsiteData*>(dataList->data);
444 g_assert_nonnull(data);
445 g_assert_cmpuint(webkit_website_data_get_types(data), ==, databaseTypes);
446 // Database sizes are unknown.
447 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES), ==, 0);
448 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES), ==, 0);
449
450 // Remove all databases at once.
451 GList removeList = { data, nullptr, nullptr };
452 test->remove(databaseTypes, &removeList);
453 dataList = test->fetch(databaseTypes);
454 g_assert_null(dataList);
455
456 // Clear all.
457 static const WebKitWebsiteDataTypes cacheAndDatabaseTypes = static_cast<WebKitWebsiteDataTypes>(databaseTypes | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
458 test->clear(cacheAndDatabaseTypes, 0);
459 dataList = test->fetch(cacheAndDatabaseTypes);
460 g_assert_null(dataList);
461}
462
463static void testWebsiteDataAppcache(WebsiteDataTest* test, gconstpointer)
464{
465 GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
466 g_assert_null(dataList);
467
468 test->loadURI(kServer->getURIForPath("/appcache").data());
469 test->waitUntilLoadFinished();
470
471 test->wait(1);
472 dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
473 g_assert_nonnull(dataList);
474 g_assert_cmpuint(g_list_length(dataList), ==, 1);
475 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data);
476 g_assert_nonnull(data);
477 WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
478 g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
479 webkit_security_origin_unref(origin);
480 g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
481 // Appcache size is unknown.
482 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE), ==, 0);
483
484 GList removeList = { data, nullptr, nullptr };
485 test->remove(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE, &removeList);
486 dataList = test->fetch(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE);
487 g_assert_null(dataList);
488
489 // Clear all.
490 static const WebKitWebsiteDataTypes cacheAndAppcacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
491 test->clear(cacheAndAppcacheTypes, 0);
492 dataList = test->fetch(cacheAndAppcacheTypes);
493 g_assert_null(dataList);
494}
495
496static void testWebsiteDataCookies(WebsiteDataTest* test, gconstpointer)
497{
498 GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES);
499 g_assert_null(dataList);
500
501 test->loadURI(kServer->getURIForPath("/empty").data());
502 test->waitUntilLoadFinished();
503
504 dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES);
505 g_assert_nonnull(dataList);
506 g_assert_cmpuint(g_list_length(dataList), ==, 1);
507 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data);
508 g_assert_nonnull(data);
509 g_assert_cmpstr(webkit_website_data_get_name(data), ==, "127.0.0.1");
510 g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_COOKIES);
511 // Cookies size is unknown.
512 g_assert_cmpuint(webkit_website_data_get_size(data, WEBKIT_WEBSITE_DATA_COOKIES), ==, 0);
513
514 GList removeList = { data, nullptr, nullptr };
515 test->remove(WEBKIT_WEBSITE_DATA_COOKIES, &removeList);
516 dataList = test->fetch(WEBKIT_WEBSITE_DATA_COOKIES);
517 g_assert_null(dataList);
518
519 // Clear all.
520 static const WebKitWebsiteDataTypes cacheAndCookieTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_COOKIES | WEBKIT_WEBSITE_DATA_MEMORY_CACHE | WEBKIT_WEBSITE_DATA_DISK_CACHE);
521 test->clear(cacheAndCookieTypes, 0);
522 dataList = test->fetch(cacheAndCookieTypes);
523 g_assert_null(dataList);
524}
525
526static void testWebsiteDataDeviceIdHashSalt(WebsiteDataTest* test, gconstpointer)
527{
528 WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView);
529 gboolean enabled = webkit_settings_get_enable_media_stream(settings);
530 webkit_settings_set_enable_media_stream(settings, TRUE);
531
532 test->clear(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT, 0);
533
534 GList* dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
535 g_assert_null(dataList);
536
537 test->loadURI(kServer->getURIForPath("/enumeratedevices").data());
538 test->waitUntilTitleChangedTo("Finished");
539
540 dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
541 g_assert_nonnull(dataList);
542
543 g_assert_cmpuint(g_list_length(dataList), ==, 1);
544 WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(dataList->data);
545 g_assert_nonnull(data);
546 WebKitSecurityOrigin* origin = webkit_security_origin_new_for_uri(kServer->getURIForPath("/").data());
547 g_assert_cmpstr(webkit_website_data_get_name(data), ==, webkit_security_origin_get_host(origin));
548 webkit_security_origin_unref(origin);
549 g_assert_cmpuint(webkit_website_data_get_types(data), ==, WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
550
551 GList removeList = { data, nullptr, nullptr };
552 test->remove(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT, &removeList);
553 dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
554 g_assert_null(dataList);
555
556 // Test removing the cookies.
557 test->loadURI(kServer->getURIForPath("/enumeratedevices").data());
558 test->waitUntilTitleChangedTo("Finished");
559
560 dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
561 g_assert_nonnull(dataList);
562 data = static_cast<WebKitWebsiteData*>(dataList->data);
563 g_assert_nonnull(data);
564
565 GList removeCookieList = { data, nullptr, nullptr };
566 test->remove(WEBKIT_WEBSITE_DATA_COOKIES, &removeCookieList);
567 dataList = test->fetch(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
568 g_assert_null(dataList);
569
570 // Clear all.
571 static const WebKitWebsiteDataTypes cacheAndAppcacheTypes = static_cast<WebKitWebsiteDataTypes>(WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
572 test->clear(cacheAndAppcacheTypes, 0);
573 dataList = test->fetch(cacheAndAppcacheTypes);
574 g_assert_null(dataList);
575
576 webkit_settings_set_enable_media_stream(settings, enabled);
577}
578
579void beforeAll()
580{
581 kServer = new WebKitTestServer();
582 kServer->run(serverCallback);
583
584 WebsiteDataTest::add("WebKitWebsiteData", "configuration", testWebsiteDataConfiguration);
585 WebViewTest::add("WebKitWebsiteData", "ephemeral", testWebsiteDataEphemeral);
586 WebsiteDataTest::add("WebKitWebsiteData", "cache", testWebsiteDataCache);
587 WebsiteDataTest::add("WebKitWebsiteData", "storage", testWebsiteDataStorage);
588 WebsiteDataTest::add("WebKitWebsiteData", "databases", testWebsiteDataDatabases);
589 WebsiteDataTest::add("WebKitWebsiteData", "appcache", testWebsiteDataAppcache);
590 WebsiteDataTest::add("WebKitWebsiteData", "cookies", testWebsiteDataCookies);
591 WebsiteDataTest::add("WebKitWebsiteData", "deviceidhashsalt", testWebsiteDataDeviceIdHashSalt);
592}
593
594void afterAll()
595{
596 delete kServer;
597}
598