1/*
2 * Copyright (C) 2013-2014 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 <cstdarg>
25#include <wtf/glib/GRefPtr.h>
26#include <wtf/glib/GUniquePtr.h>
27
28static WebKitTestServer* kServer;
29
30// These are all here so that they can be changed easily, if necessary.
31static const char* kTestHTML =
32"<html>\n"
33" <head><link rel=\"stylesheet\" type=\"text/css\" href=\"/extra.css\"></head>\n"
34" <body>\n"
35" <div id=\"styledElement\">Sweet stylez!</div>\n"
36" <div id=\"otherElement\">Blocked stylez!</div>\n"
37" </body>\n"
38"</html>";
39
40static const char* kTestCSS =
41"div#otherElement {\n"
42" font-weight: bold;\n"
43"}\n";
44
45static const char* kInjectedStyleSheet = "#styledElement { font-weight: bold; }";
46static const char* kStyleSheetTestScript = "getComputedStyle(document.getElementById('styledElement'))['font-weight']";
47static const char* kStyleSheetTestScriptResult = "bold";
48static const char* kInjectedScript = "document.write('<div id=\"item\">Generated by a script</div>')";
49static const char* kScriptTestScript = "document.getElementById('item').innerText";
50static const char* kScriptTestScriptResult = "Generated by a script";
51static const char* kScriptTestCSSBlocked = "getComputedStyle(document.getElementById('otherElement'))['font-weight']";
52static const char* kScriptTestCSSBlockedResult = "normal";
53static const char* kJSONFilter =
54"[\n"
55" {\n"
56" \"trigger\": {\n"
57" \"url-filter\": \".*\",\n"
58" \"resource-type\": [\"style-sheet\"]\n"
59" },\n"
60" \"action\": {\n"
61" \"type\": \"block\"\n"
62" }\n"
63" }\n"
64"]\n";
65
66static void testWebViewNewWithUserContentManager(Test* test, gconstpointer)
67{
68 GRefPtr<WebKitUserContentManager> userContentManager1 = adoptGRef(webkit_user_content_manager_new());
69 test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(userContentManager1.get()));
70 auto webView1 = Test::adoptView(Test::createWebView(userContentManager1.get()));
71 g_assert_true(webkit_web_view_get_user_content_manager(webView1.get()) == userContentManager1.get());
72
73 auto webView2 = Test::adoptView(Test::createWebView());
74 g_assert_true(webkit_web_view_get_user_content_manager(webView2.get()) != userContentManager1.get());
75}
76
77static bool isStyleSheetInjectedForURLAtPath(WebViewTest* test, const char* path, const char* world = nullptr)
78{
79 test->loadURI(kServer->getURIForPath(path).data());
80 test->waitUntilLoadFinished();
81
82 GUniqueOutPtr<GError> error;
83 WebKitJavascriptResult* javascriptResult = world ? test->runJavaScriptInWorldAndWaitUntilFinished(kStyleSheetTestScript, world, &error.outPtr())
84 : test->runJavaScriptAndWaitUntilFinished(kStyleSheetTestScript, &error.outPtr());
85 g_assert_nonnull(javascriptResult);
86 g_assert_no_error(error.get());
87
88 GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult));
89 return !g_strcmp0(resultString.get(), kStyleSheetTestScriptResult);
90}
91
92static bool isScriptInjectedForURLAtPath(WebViewTest* test, const char* path, const char* world = nullptr)
93{
94 test->loadURI(kServer->getURIForPath(path).data());
95 test->waitUntilLoadFinished();
96
97 GUniqueOutPtr<GError> error;
98 WebKitJavascriptResult* javascriptResult = world ? test->runJavaScriptInWorldAndWaitUntilFinished(kScriptTestScript, world, &error.outPtr())
99 : test->runJavaScriptAndWaitUntilFinished(kScriptTestScript, &error.outPtr());
100 if (javascriptResult) {
101 g_assert_no_error(error.get());
102
103 GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult));
104 return !g_strcmp0(resultString.get(), kScriptTestScriptResult);
105 }
106 return false;
107}
108
109static void fillURLListFromPaths(char** list, const char* path, ...)
110{
111 va_list argumentList;
112 va_start(argumentList, path);
113
114 int i = 0;
115 while (path) {
116 // FIXME: We must use a wildcard for the host here until http://wkbug.com/112476 is fixed.
117 // Until that time patterns with port numbers in them will not properly match URLs with port numbers.
118 list[i++] = g_strdup_printf("http://*/%s*", path);
119 path = va_arg(argumentList, const char*);
120 }
121}
122
123static void removeOldInjectedContentAndResetLists(WebKitUserContentManager* userContentManager, char** whitelist, char** blacklist)
124{
125 webkit_user_content_manager_remove_all_style_sheets(userContentManager);
126 webkit_user_content_manager_remove_all_scripts(userContentManager);
127 webkit_user_content_manager_remove_all_filters(userContentManager);
128
129 while (*whitelist) {
130 g_free(*whitelist);
131 *whitelist = 0;
132 whitelist++;
133 }
134
135 while (*blacklist) {
136 g_free(*blacklist);
137 *blacklist = 0;
138 blacklist++;
139 }
140}
141
142static void testUserContentManagerInjectedStyleSheet(WebViewTest* test, gconstpointer)
143{
144 char* whitelist[3] = { 0, 0, 0 };
145 char* blacklist[3] = { 0, 0, 0 };
146
147 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
148
149 // Without a whitelist or a blacklist all URLs should have the injected style sheet.
150 static const char* randomPath = "somerandompath";
151 g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath));
152 WebKitUserStyleSheet* styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, nullptr, nullptr);
153 webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
154 webkit_user_style_sheet_unref(styleSheet);
155 g_assert_true(isStyleSheetInjectedForURLAtPath(test, randomPath));
156
157 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
158
159 g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));
160 styleSheet = webkit_user_style_sheet_new_for_world(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, "WebExtensionTestScriptWorld", nullptr, nullptr);
161 webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
162 webkit_user_style_sheet_unref(styleSheet);
163 g_assert_true(isStyleSheetInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));
164
165 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
166
167 fillURLListFromPaths(blacklist, randomPath, 0);
168 styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, nullptr, blacklist);
169 webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
170 webkit_user_style_sheet_unref(styleSheet);
171 g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath));
172 g_assert_true(isStyleSheetInjectedForURLAtPath(test, "someotherrandompath"));
173
174 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
175
176 static const char* inTheWhiteList = "inthewhitelist";
177 static const char* notInWhitelist = "notinthewhitelist";
178 static const char* inTheWhiteListAndBlackList = "inthewhitelistandblacklist";
179
180 fillURLListFromPaths(whitelist, inTheWhiteList, inTheWhiteListAndBlackList, 0);
181 fillURLListFromPaths(blacklist, inTheWhiteListAndBlackList, 0);
182 styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, whitelist, blacklist);
183 webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
184 webkit_user_style_sheet_unref(styleSheet);
185 g_assert_true(isStyleSheetInjectedForURLAtPath(test, inTheWhiteList));
186 g_assert_false(isStyleSheetInjectedForURLAtPath(test, inTheWhiteListAndBlackList));
187 g_assert_false(isStyleSheetInjectedForURLAtPath(test, notInWhitelist));
188
189 // It's important to clean up the environment before other tests.
190 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
191}
192
193static void testUserContentManagerInjectedScript(WebViewTest* test, gconstpointer)
194{
195 char* whitelist[3] = { 0, 0, 0 };
196 char* blacklist[3] = { 0, 0, 0 };
197
198 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
199
200 // Without a whitelist or a blacklist all URLs should have the injected script.
201 static const char* randomPath = "somerandompath";
202 g_assert_false(isScriptInjectedForURLAtPath(test, randomPath));
203 WebKitUserScript* script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, nullptr, nullptr);
204 webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
205 webkit_user_script_unref(script);
206 g_assert_true(isScriptInjectedForURLAtPath(test, randomPath));
207
208 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
209
210 g_assert_false(isScriptInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));
211 script = webkit_user_script_new_for_world(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, "WebExtensionTestScriptWorld", nullptr, nullptr);
212 webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
213 webkit_user_script_unref(script);
214 g_assert_true(isScriptInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));
215
216 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
217
218 fillURLListFromPaths(blacklist, randomPath, 0);
219 script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, nullptr, blacklist);
220 webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
221 webkit_user_script_unref(script);
222 g_assert_false(isScriptInjectedForURLAtPath(test, randomPath));
223 g_assert_true(isScriptInjectedForURLAtPath(test, "someotherrandompath"));
224
225 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
226
227 static const char* inTheWhiteList = "inthewhitelist";
228 static const char* notInWhitelist = "notinthewhitelist";
229 static const char* inTheWhiteListAndBlackList = "inthewhitelistandblacklist";
230
231 fillURLListFromPaths(whitelist, inTheWhiteList, inTheWhiteListAndBlackList, 0);
232 fillURLListFromPaths(blacklist, inTheWhiteListAndBlackList, 0);
233 script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, whitelist, blacklist);
234 webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
235 webkit_user_script_unref(script);
236 g_assert_true(isScriptInjectedForURLAtPath(test, inTheWhiteList));
237 g_assert_false(isScriptInjectedForURLAtPath(test, inTheWhiteListAndBlackList));
238 g_assert_false(isScriptInjectedForURLAtPath(test, notInWhitelist));
239
240 // It's important to clean up the environment before other tests.
241 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
242}
243
244class UserScriptMessageTest : public WebViewTest {
245public:
246 MAKE_GLIB_TEST_FIXTURE(UserScriptMessageTest);
247
248 UserScriptMessageTest()
249 : m_userScriptMessage(nullptr)
250 {
251 }
252
253 ~UserScriptMessageTest()
254 {
255 if (m_userScriptMessage)
256 webkit_javascript_result_unref(m_userScriptMessage);
257 }
258
259 bool registerHandler(const char* handlerName, const char* worldName = nullptr)
260 {
261 return worldName ? webkit_user_content_manager_register_script_message_handler_in_world(m_userContentManager.get(), handlerName, worldName)
262 : webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), handlerName);
263 }
264
265 void unregisterHandler(const char* handlerName, const char* worldName = nullptr)
266 {
267 return worldName ? webkit_user_content_manager_unregister_script_message_handler_in_world(m_userContentManager.get(), handlerName, worldName)
268 : webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), handlerName);
269 }
270
271 static void scriptMessageReceived(WebKitUserContentManager* userContentManager, WebKitJavascriptResult* jsResult, UserScriptMessageTest* test)
272 {
273 g_signal_handlers_disconnect_by_func(userContentManager, reinterpret_cast<gpointer>(scriptMessageReceived), test);
274 if (!test->m_waitForScriptRun)
275 g_main_loop_quit(test->m_mainLoop);
276
277 g_assert_null(test->m_userScriptMessage);
278 test->m_userScriptMessage = webkit_javascript_result_ref(jsResult);
279 }
280
281 WebKitJavascriptResult* waitUntilMessageReceived(const char* handlerName)
282 {
283 if (m_userScriptMessage) {
284 webkit_javascript_result_unref(m_userScriptMessage);
285 m_userScriptMessage = nullptr;
286 }
287
288 GUniquePtr<char> signalName(g_strdup_printf("script-message-received::%s", handlerName));
289 g_signal_connect(m_userContentManager.get(), signalName.get(), G_CALLBACK(scriptMessageReceived), this);
290
291 g_main_loop_run(m_mainLoop);
292 g_assert_false(m_waitForScriptRun);
293 g_assert_nonnull(m_userScriptMessage);
294 return m_userScriptMessage;
295 }
296
297 static void runJavaScriptFinished(GObject*, GAsyncResult* result, UserScriptMessageTest* test)
298 {
299 g_assert_true(test->m_waitForScriptRun);
300 test->m_waitForScriptRun = false;
301 g_main_loop_quit(test->m_mainLoop);
302 }
303
304 WebKitJavascriptResult* postMessageAndWaitUntilReceived(const char* handlerName, const char* javascriptValueAsText, const char* worldName = nullptr)
305 {
306 GUniquePtr<char> javascriptSnippet(g_strdup_printf("window.webkit.messageHandlers.%s.postMessage(%s);", handlerName, javascriptValueAsText));
307 m_waitForScriptRun = true;
308 if (worldName)
309 webkit_web_view_run_javascript_in_world(m_webView, javascriptSnippet.get(), worldName, nullptr, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptFinished), this);
310 else
311 webkit_web_view_run_javascript(m_webView, javascriptSnippet.get(), nullptr, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptFinished), this);
312 return waitUntilMessageReceived(handlerName);
313 }
314
315private:
316 WebKitJavascriptResult* m_userScriptMessage;
317 bool m_waitForScriptRun { false };
318};
319
320static void testUserContentManagerScriptMessageReceived(UserScriptMessageTest* test, gconstpointer)
321{
322 g_assert_true(test->registerHandler("msg"));
323
324 // Trying to register the same handler a second time must fail.
325 g_assert_false(test->registerHandler("msg"));
326
327 test->loadHtml("<html></html>", nullptr);
328 test->waitUntilLoadFinished();
329
330 // Check that the "window.webkit.messageHandlers" namespace exists.
331 GUniqueOutPtr<GError> error;
332 WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", &error.outPtr());
333 g_assert_nonnull(javascriptResult);
334 g_assert_no_error(error.get());
335 GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
336 g_assert_cmpstr(valueString.get(), ==, "y");
337
338 // Check that the "document.webkit.messageHandlers.msg" namespace exists.
339 javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr());
340 g_assert_nonnull(javascriptResult);
341 g_assert_no_error(error.get());
342 valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
343 g_assert_cmpstr(valueString.get(), ==, "y");
344
345 valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'user message'")));
346 g_assert_cmpstr(valueString.get(), ==, "user message");
347
348 // Messages should arrive despite of other handlers being registered.
349 g_assert_true(test->registerHandler("anotherHandler"));
350
351 // Check that the "document.webkit.messageHandlers.msg" namespace still exists.
352 javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr());
353 g_assert_nonnull(javascriptResult);
354 g_assert_no_error(error.get());
355 valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
356 g_assert_cmpstr(valueString.get(), ==, "y");
357
358 // Check that the "document.webkit.messageHandlers.anotherHandler" namespace exists.
359 javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.anotherHandler ? 'y' : 'n';", &error.outPtr());
360 g_assert_nonnull(javascriptResult);
361 g_assert_no_error(error.get());
362 valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
363 g_assert_cmpstr(valueString.get(), ==, "y");
364
365 valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'handler: msg'")));
366 g_assert_cmpstr(valueString.get(), ==, "handler: msg");
367
368 valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("anotherHandler", "'handler: anotherHandler'")));
369 g_assert_cmpstr(valueString.get(), ==, "handler: anotherHandler");
370
371 // Unregistering a handler and re-registering again under the same name should work.
372 test->unregisterHandler("msg");
373
374 javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg.postMessage('42');", &error.outPtr());
375 g_assert_null(javascriptResult);
376 g_assert_nonnull(error.get());
377
378 // Re-registering a handler that has been unregistered must work
379 g_assert_true(test->registerHandler("msg"));
380 valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'handler: msg'")));
381 g_assert_cmpstr(valueString.get(), ==, "handler: msg");
382
383 test->unregisterHandler("anotherHandler");
384}
385
386static void testUserContentManagerScriptMessageInWorldReceived(UserScriptMessageTest* test, gconstpointer)
387{
388 g_assert_true(test->registerHandler("msg"));
389
390 test->loadHtml("<html></html>", nullptr);
391 test->waitUntilLoadFinished();
392
393 // Check that the "window.webkit.messageHandlers" namespace doesn't exist in isolated worlds.
394 GUniqueOutPtr<GError> error;
395 WebKitJavascriptResult* javascriptResult = test->runJavaScriptInWorldAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", "WebExtensionTestScriptWorld", &error.outPtr());
396 g_assert_null(javascriptResult);
397 g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);
398 test->unregisterHandler("msg");
399
400 g_assert_true(test->registerHandler("msg", "WebExtensionTestScriptWorld"));
401
402 // Check that the "window.webkit.messageHandlers" namespace exists in the world.
403 javascriptResult = test->runJavaScriptInWorldAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", "WebExtensionTestScriptWorld", &error.outPtr());
404 g_assert_nonnull(javascriptResult);
405 g_assert_no_error(error.get());
406 GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
407 g_assert_cmpstr(valueString.get(), ==, "y");
408
409 valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'user message'", "WebExtensionTestScriptWorld")));
410 g_assert_cmpstr(valueString.get(), ==, "user message");
411
412 // Post message in main world should fail.
413 javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg.postMessage('42');", &error.outPtr());
414 g_assert_null(javascriptResult);
415 g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);
416
417 test->unregisterHandler("msg", "WebExtensionTestScriptWorld");
418}
419
420#if PLATFORM(GTK)
421static void testUserContentManagerScriptMessageFromDOMBindings(UserScriptMessageTest* test, gconstpointer)
422{
423 g_assert_true(test->registerHandler("dom"));
424
425 test->loadHtml("<html>1</html>", nullptr);
426 WebKitJavascriptResult* javascriptResult = test->waitUntilMessageReceived("dom");
427 g_assert_nonnull(javascriptResult);
428 GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
429 g_assert_cmpstr(valueString.get(), ==, "DocumentLoaded");
430
431 test->unregisterHandler("dom");
432}
433#endif
434
435static bool isCSSBlockedForURLAtPath(WebViewTest* test, const char* path)
436{
437 test->loadURI(kServer->getURIForPath(path).data());
438 test->waitUntilLoadFinished();
439
440 GUniqueOutPtr<GError> error;
441 WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished(kScriptTestCSSBlocked, &error.outPtr());
442 g_assert_nonnull(javascriptResult);
443 g_assert_no_error(error.get());
444
445 GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
446 return !g_strcmp0(valueString.get(), kScriptTestCSSBlockedResult);
447}
448
449static WebKitUserContentFilter* getUserContentFilter(WebViewTest* test)
450{
451 GUniquePtr<char> filtersPath(g_build_filename(test->dataDirectory(), "filters", nullptr));
452 WebKitUserContentFilterStore* store = webkit_user_content_filter_store_new(filtersPath.get());
453 test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(store));
454
455 struct Data {
456 GMainLoop* mainLoop;
457 WebKitUserContentFilter* filter;
458 };
459 Data data { test->m_mainLoop, nullptr, };
460
461 GRefPtr<GBytes> source = adoptGRef(g_bytes_new_static(kJSONFilter, strlen(kJSONFilter)));
462 webkit_user_content_filter_store_save(store, "TestFilter", source.get(), nullptr, [](GObject* sourceObject, GAsyncResult* result, void* userData) {
463 auto* data = static_cast<Data*>(userData);
464 GUniqueOutPtr<GError> error;
465 data->filter = webkit_user_content_filter_store_save_finish(WEBKIT_USER_CONTENT_FILTER_STORE(sourceObject), result, &error.outPtr());
466 g_assert_nonnull(data->filter);
467 g_assert_no_error(error.get());
468 g_main_loop_quit(data->mainLoop);
469 }, &data);
470 g_main_loop_run(data.mainLoop);
471
472 g_object_unref(store);
473
474 g_assert_nonnull(data.filter);
475 return data.filter;
476}
477
478static void testUserContentManagerContentFilter(WebViewTest* test, gconstpointer)
479{
480 char* whitelist[] = { nullptr, nullptr, nullptr };
481 char* blacklist[] = { nullptr, nullptr, nullptr };
482
483 removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), whitelist, blacklist);
484
485 static const char* somePath = "somepath";
486 g_assert_false(isCSSBlockedForURLAtPath(test, somePath));
487
488 WebKitUserContentFilter* filter = getUserContentFilter(test);
489 webkit_user_content_manager_add_filter(test->m_userContentManager.get(), filter);
490 g_assert_true(isCSSBlockedForURLAtPath(test, somePath));
491
492 webkit_user_content_manager_remove_filter(test->m_userContentManager.get(), filter);
493 g_assert_false(isCSSBlockedForURLAtPath(test, somePath));
494
495 webkit_user_content_filter_unref(filter);
496}
497
498static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
499{
500 soup_message_set_status(message, SOUP_STATUS_OK);
501 if (!g_strcmp0(path, "/extra.css"))
502 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kTestCSS, strlen(kTestCSS));
503 else
504 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, kTestHTML, strlen(kTestHTML));
505 soup_message_body_complete(message->response_body);
506}
507
508void beforeAll()
509{
510 kServer = new WebKitTestServer();
511 kServer->run(serverCallback);
512
513 Test::add("WebKitWebView", "new-with-user-content-manager", testWebViewNewWithUserContentManager);
514 WebViewTest::add("WebKitUserContentManager", "injected-style-sheet", testUserContentManagerInjectedStyleSheet);
515 WebViewTest::add("WebKitUserContentManager", "injected-script", testUserContentManagerInjectedScript);
516 UserScriptMessageTest::add("WebKitUserContentManager", "script-message-received", testUserContentManagerScriptMessageReceived);
517 UserScriptMessageTest::add("WebKitUserContentManager", "script-message-in-world-received", testUserContentManagerScriptMessageInWorldReceived);
518#if PLATFORM(GTK)
519 UserScriptMessageTest::add("WebKitUserContentManager", "script-message-from-dom-bindings", testUserContentManagerScriptMessageFromDOMBindings);
520#endif
521 WebViewTest::add("WebKitUserContentManager", "content-filter", testUserContentManagerContentFilter);
522}
523
524void afterAll()
525{
526 delete kServer;
527}
528