06c781564301041105c2126ec647c5ab527078d1
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / efl / tests / test_ewk2_cookie_manager.cpp
1 /*
2  * Copyright (C) 2012 Igalia S.L.
3  * Copyright (C) 2012 Intel Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22
23 #include "UnitTestUtils/EWK2UnitTestBase.h"
24 #include "UnitTestUtils/EWK2UnitTestServer.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28
29 using namespace EWK2UnitTest;
30 using namespace WTF;
31
32 extern EWK2UnitTestEnvironment* environment;
33
34 static const char FIRST_PARTY_DOMAIN[] = "127.0.0.1";
35 static const char THIRD_PARTY_DOMAIN[] = "localhost";
36 static const char INDEX_HTML_STRING[] =
37     "<html><body>"
38     " <p>EFLWebKit2 Cookie Manager test</p>"
39     " <img src='http://localhost:%u/image.png' width=5 height=5></img>"
40     "</body></html>";
41
42 class EWK2CookieManagerTest : public EWK2UnitTestBase {
43 public:
44     static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
45     {
46         if (message->method != SOUP_METHOD_GET) {
47             soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
48             return;
49         }
50
51         soup_message_set_status(message, SOUP_STATUS_OK);
52         if (!strcmp(path, "/index.html")) {
53             Eina_Strbuf* buffer = eina_strbuf_new();
54             eina_strbuf_append_printf(buffer, INDEX_HTML_STRING, soup_server_get_port(server));
55             soup_message_headers_replace(message->response_headers, "Set-Cookie", "foo=bar; Max-Age=60");
56             soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, eina_strbuf_string_steal(buffer), eina_strbuf_length_get(buffer));
57             eina_strbuf_free(buffer);
58         } else if (!strcmp(path, "/image.png"))
59             soup_message_headers_replace(message->response_headers, "Set-Cookie", "baz=qux; Max-Age=60");
60         else
61             soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
62
63         soup_message_body_complete(message->response_body);
64     }
65
66     static void getAcceptPolicyCallback(Ewk_Cookie_Accept_Policy policy, Ewk_Error* error, void* event_info)
67     {
68         ASSERT_FALSE(error);
69         Ewk_Cookie_Accept_Policy* ret = static_cast<Ewk_Cookie_Accept_Policy*>(event_info);
70         *ret = policy;
71         ecore_main_loop_quit();
72     }
73
74     static void getHostnamesWithCookiesCallback(Eina_List* hostnames, Ewk_Error* error, void* event_info)
75     {
76         ASSERT_FALSE(error);
77
78         Eina_List** ret = static_cast<Eina_List**>(event_info);
79         Eina_List* l;
80         void* data;
81         EINA_LIST_FOREACH(hostnames, l, data)
82             *ret = eina_list_append(*ret, eina_stringshare_ref(static_cast<char*>(data)));
83         ecore_main_loop_quit();
84     }
85
86     static int compareHostNames(const void* hostName1, const void* hostName2)
87     {
88         return strcmp(static_cast<const char*>(hostName1), static_cast<const char*>(hostName2));
89     }
90
91     static void onCookiesChanged(void *eventInfo)
92     {
93         bool* cookiesChanged = static_cast<bool*>(eventInfo);
94         *cookiesChanged = true;
95     }
96
97 protected:
98     Ewk_Cookie_Accept_Policy getAcceptPolicy(Ewk_Cookie_Manager* manager)
99     {
100         Ewk_Cookie_Accept_Policy policy = EWK_COOKIE_ACCEPT_POLICY_ALWAYS;
101         ewk_cookie_manager_async_accept_policy_get(manager, getAcceptPolicyCallback, &policy);
102         ecore_main_loop_begin();
103         return policy;
104     }
105
106     Eina_List* getHostnamesWithCookies(Ewk_Cookie_Manager* manager)
107     {
108         Eina_List* ret = 0;
109         ewk_cookie_manager_async_hostnames_with_cookies_get(manager, getHostnamesWithCookiesCallback, &ret);
110         ecore_main_loop_begin();
111         return ret;
112     }
113
114     void freeHostNames(Eina_List* hostnames)
115     {
116         void* data;
117         EINA_LIST_FREE(hostnames, data)
118             eina_stringshare_del(static_cast<char*>(data));
119     }
120
121     int countHostnamesWithCookies(Ewk_Cookie_Manager* manager)
122     {
123         Eina_List* hostnames = getHostnamesWithCookies(manager);
124         int count = eina_list_count(hostnames);
125         freeHostNames(hostnames);
126         return count;
127     }
128 };
129
130 TEST_F(EWK2CookieManagerTest, ewk_cookie_manager_accept_policy)
131 {
132     std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>();
133     httpServer->run(serverCallback);
134
135     Ewk_Cookie_Manager* cookieManager = ewk_context_cookie_manager_get(ewk_view_context_get(webView()));
136     ASSERT_TRUE(cookieManager);
137
138     // Default policy is EWK_COOKIE_ACCEPT_POLICY_NO_THIRD_PARTY.
139     ASSERT_EQ(EWK_COOKIE_ACCEPT_POLICY_NO_THIRD_PARTY, getAcceptPolicy(cookieManager));
140     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
141
142     Eina_List* hostnames = getHostnamesWithCookies(cookieManager);
143     ASSERT_EQ(1, eina_list_count(hostnames));
144     ASSERT_STREQ(FIRST_PARTY_DOMAIN, static_cast<char*>(eina_list_nth(hostnames, 0)));
145     freeHostNames(hostnames);
146     ewk_cookie_manager_cookies_clear(cookieManager);
147
148     // Change policy to EWK_COOKIE_ACCEPT_POLICY_ALWAYS
149     ewk_cookie_manager_accept_policy_set(cookieManager, EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
150     ASSERT_EQ(EWK_COOKIE_ACCEPT_POLICY_ALWAYS, getAcceptPolicy(cookieManager));
151     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
152
153     hostnames = getHostnamesWithCookies(cookieManager);
154     ASSERT_EQ(2, eina_list_count(hostnames));
155     hostnames = eina_list_sort(hostnames, eina_list_count(hostnames), compareHostNames);
156     ASSERT_STREQ(FIRST_PARTY_DOMAIN, static_cast<char*>(eina_list_nth(hostnames, 0)));
157     ASSERT_STREQ(THIRD_PARTY_DOMAIN, static_cast<char*>(eina_list_nth(hostnames, 1)));
158     freeHostNames(hostnames);
159     ewk_cookie_manager_cookies_clear(cookieManager);
160
161     // Change policy to EWK_COOKIE_ACCEPT_POLICY_NEVER
162     ewk_cookie_manager_accept_policy_set(cookieManager, EWK_COOKIE_ACCEPT_POLICY_NEVER);
163     ASSERT_EQ(EWK_COOKIE_ACCEPT_POLICY_NEVER, getAcceptPolicy(cookieManager));
164     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
165     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
166 }
167
168 TEST_F(EWK2CookieManagerTest, ewk_cookie_manager_changes_watch)
169 {
170     std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>();
171     httpServer->run(serverCallback);
172
173     Ewk_Cookie_Manager* cookieManager = ewk_context_cookie_manager_get(ewk_view_context_get(webView()));
174     ASSERT_TRUE(cookieManager);
175
176     ewk_cookie_manager_accept_policy_set(cookieManager, EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
177     ASSERT_EQ(EWK_COOKIE_ACCEPT_POLICY_ALWAYS, getAcceptPolicy(cookieManager));
178
179     // Watch for changes
180     bool cookiesChanged = false;
181     ewk_cookie_manager_changes_watch(cookieManager, onCookiesChanged, &cookiesChanged);
182
183     // Check for cookie changes notifications
184     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
185
186     ASSERT_TRUE(waitUntilTrue(cookiesChanged));
187
188     cookiesChanged = false;
189     ewk_cookie_manager_cookies_clear(cookieManager);
190     ASSERT_TRUE(waitUntilTrue(cookiesChanged));
191
192     // Stop watching for notifications
193     ewk_cookie_manager_changes_watch(cookieManager, 0, 0);
194     cookiesChanged = false;
195     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
196     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
197     ASSERT_FALSE(cookiesChanged);
198
199     // Watch again for notifications
200     ewk_cookie_manager_changes_watch(cookieManager, onCookiesChanged, &cookiesChanged);
201
202     // Make sure we don't get notifications when loading setting an existing persistent storage
203     char storageDirectory[] = "/tmp/ewk2_cookie_manager-XXXXXX";
204     ASSERT_TRUE(mkdtemp(storageDirectory));
205     char textStorage1[64];
206     snprintf(textStorage1, sizeof(textStorage1), "%s/txt-cookie1", storageDirectory);
207     char textStorage2[64];
208     snprintf(textStorage2, sizeof(textStorage2), "%s/txt-cookie2", storageDirectory);
209
210     ewk_cookie_manager_persistent_storage_set(cookieManager, textStorage1, EWK_COOKIE_PERSISTENT_STORAGE_TEXT);
211     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
212     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
213
214     cookiesChanged = false;
215     ewk_cookie_manager_persistent_storage_set(cookieManager, textStorage2, EWK_COOKIE_PERSISTENT_STORAGE_TEXT);
216     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
217
218     ewk_cookie_manager_persistent_storage_set(cookieManager, textStorage1, EWK_COOKIE_PERSISTENT_STORAGE_TEXT);
219     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
220
221     ASSERT_FALSE(cookiesChanged);
222
223     // Final clean up.
224     ewk_cookie_manager_changes_watch(cookieManager, 0, 0);
225     unlink(textStorage1);
226     unlink(textStorage2);
227     rmdir(storageDirectory);
228 }
229
230 TEST_F(EWK2CookieManagerTest, ewk_cookie_manager_cookies_delete)
231 {
232     std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>();
233     httpServer->run(serverCallback);
234
235     Ewk_Cookie_Manager* cookieManager = ewk_context_cookie_manager_get(ewk_view_context_get(webView()));
236     ASSERT_TRUE(cookieManager);
237
238     ewk_cookie_manager_accept_policy_set(cookieManager, EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
239     ASSERT_EQ(EWK_COOKIE_ACCEPT_POLICY_ALWAYS, getAcceptPolicy(cookieManager));
240
241     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
242     Eina_List* hostnames = getHostnamesWithCookies(cookieManager);
243     ASSERT_EQ(2, eina_list_count(hostnames));
244     freeHostNames(hostnames);
245
246     // Delete first party cookie
247     ewk_cookie_manager_hostname_cookies_clear(cookieManager, FIRST_PARTY_DOMAIN);
248     hostnames = getHostnamesWithCookies(cookieManager);
249     ASSERT_EQ(1, eina_list_count(hostnames));
250     ASSERT_STREQ(THIRD_PARTY_DOMAIN, static_cast<char*>(eina_list_nth(hostnames, 0)));
251     freeHostNames(hostnames);
252
253     // Delete third party cookie
254     ewk_cookie_manager_hostname_cookies_clear(cookieManager, THIRD_PARTY_DOMAIN);
255     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
256
257     // Get all cookies again
258     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
259     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
260
261     // Clear all cookies
262     ewk_cookie_manager_cookies_clear(cookieManager);
263     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
264 }
265
266 TEST_F(EWK2CookieManagerTest, DISABLED_ewk_cookie_manager_permanent_storage)
267 {
268     std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>();
269     httpServer->run(serverCallback);
270
271     // Generate unique names for cookie storages.
272     char storageDirectory[] = "/tmp/ewk2_cookie_manager-XXXXXX";
273     ASSERT_TRUE(mkdtemp(storageDirectory));
274     char textStorage[64];
275     snprintf(textStorage, sizeof(textStorage), "%s/txt-cookie", storageDirectory);
276     char sqliteStorage[64];
277     snprintf(sqliteStorage, sizeof(sqliteStorage), "%s/sqlite-cookie", storageDirectory);
278
279     Ewk_Cookie_Manager* cookieManager = ewk_context_cookie_manager_get(ewk_view_context_get(webView()));
280     ASSERT_TRUE(cookieManager);
281
282     ewk_cookie_manager_accept_policy_set(cookieManager, EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
283     ASSERT_EQ(EWK_COOKIE_ACCEPT_POLICY_ALWAYS, getAcceptPolicy(cookieManager));
284
285     // Text storage using a new file.
286     ewk_cookie_manager_persistent_storage_set(cookieManager, textStorage, EWK_COOKIE_PERSISTENT_STORAGE_TEXT);
287     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
288
289     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
290     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
291
292     // SQLite storage using a new file.
293     ewk_cookie_manager_persistent_storage_set(cookieManager, sqliteStorage, EWK_COOKIE_PERSISTENT_STORAGE_SQLITE);
294     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
295
296     ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
297     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
298
299     // Text storage using an existing file.
300     ewk_cookie_manager_persistent_storage_set(cookieManager, textStorage, EWK_COOKIE_PERSISTENT_STORAGE_TEXT);
301     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
302     ewk_cookie_manager_cookies_clear(cookieManager);
303     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
304
305     // SQLite storage with an existing file.
306     ewk_cookie_manager_persistent_storage_set(cookieManager, sqliteStorage, EWK_COOKIE_PERSISTENT_STORAGE_SQLITE);
307     ASSERT_EQ(2, countHostnamesWithCookies(cookieManager));
308     ewk_cookie_manager_cookies_clear(cookieManager);
309     ASSERT_EQ(0, countHostnamesWithCookies(cookieManager));
310
311     // Final clean up.
312     unlink(textStorage);
313     unlink(sqliteStorage);
314     rmdir(storageDirectory);
315 }