1/*
2 * Copyright (C) 2012 Intel Corporation. All rights reserved.
3 * Copyright (C) 2012 Samsung Electronics
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28
29#include "EwkView.h"
30#include "UnitTestUtils/EWK2UnitTestBase.h"
31#include "UnitTestUtils/EWK2UnitTestServer.h"
32#include "ewk_context_private.h"
33#include "ewk_view_private.h"
34#include <wtf/text/CString.h>
35
36using namespace EWK2UnitTest;
37
38extern EWK2UnitTestEnvironment* environment;
39
40static const char htmlReply[] = "<html><head><title>Foo</title></head><body>Bar</body></html>";
41
42static bool finishTest = false;
43static constexpr double testTimeoutSeconds = 2.0;
44
45class EWK2ContextTest : public EWK2UnitTestBase {
46public:
47    static void schemeRequestCallback(Ewk_Url_Scheme_Request* request, void* userData)
48    {
49        const char* scheme = ewk_url_scheme_request_scheme_get(request);
50        ASSERT_STREQ("fooscheme", scheme);
51        const char* url = ewk_url_scheme_request_url_get(request);
52        ASSERT_STREQ("fooscheme:MyPath", url);
53        const char* path = ewk_url_scheme_request_path_get(request);
54        ASSERT_STREQ("MyPath", path);
55        ASSERT_TRUE(ewk_url_scheme_request_finish(request, htmlReply, strlen(htmlReply), "text/html"));
56
57        finishTest = true;
58    }
59};
60
61class EWK2ContextTestMultipleProcesses : public EWK2UnitTestBase {
62protected:
63    EWK2ContextTestMultipleProcesses()
64    {
65        m_multipleProcesses = true;
66    }
67};
68
69TEST_F(EWK2ContextTest, ewk_context_default_get)
70{
71    Ewk_Context* defaultContext = ewk_context_default_get();
72    ASSERT_TRUE(defaultContext);
73    ASSERT_EQ(defaultContext, ewk_context_default_get());
74}
75
76TEST_F(EWK2UnitTestBase, ewk_context_application_cache_manager_get)
77{
78    Ewk_Context* context = ewk_view_context_get(webView());
79    Ewk_Application_Cache_Manager* applicationCacheManager = ewk_context_application_cache_manager_get(context);
80    ASSERT_TRUE(applicationCacheManager);
81    ASSERT_EQ(applicationCacheManager, ewk_context_application_cache_manager_get(context));
82}
83
84TEST_F(EWK2ContextTest, ewk_context_cookie_manager_get)
85{
86    Ewk_Context* context = ewk_view_context_get(webView());
87    Ewk_Cookie_Manager* cookieManager = ewk_context_cookie_manager_get(context);
88    ASSERT_TRUE(cookieManager);
89    ASSERT_EQ(cookieManager, ewk_context_cookie_manager_get(context));
90}
91
92TEST_F(EWK2ContextTest, ewk_context_database_manager_get)
93{
94    Ewk_Context* context = ewk_view_context_get(webView());
95    Ewk_Database_Manager* databaseManager = ewk_context_database_manager_get(context);
96    ASSERT_TRUE(databaseManager);
97    ASSERT_EQ(databaseManager, ewk_context_database_manager_get(context));
98}
99
100TEST_F(EWK2ContextTest, ewk_context_favicon_database_get)
101{
102    Ewk_Context* context = ewk_view_context_get(webView());
103    Ewk_Favicon_Database* faviconDatabase = ewk_context_favicon_database_get(context);
104    ASSERT_TRUE(faviconDatabase);
105    ASSERT_EQ(faviconDatabase, ewk_context_favicon_database_get(context));
106}
107
108TEST_F(EWK2ContextTest, ewk_context_storage_manager_get)
109{
110    Ewk_Context* context = ewk_view_context_get(webView());
111    Ewk_Storage_Manager* storageManager = ewk_context_storage_manager_get(context);
112    ASSERT_TRUE(storageManager);
113    ASSERT_EQ(storageManager, ewk_context_storage_manager_get(context));
114}
115
116TEST_F(EWK2ContextTest, ewk_context_url_scheme_register)
117{
118#if ENABLE(CUSTOM_PROTOCOL)
119    ewk_context_url_scheme_register(ewk_view_context_get(webView()), "fooscheme", schemeRequestCallback, 0);
120    ewk_view_url_set(webView(), "fooscheme:MyPath");
121
122    ASSERT_TRUE(waitUntilTrue(finishTest, testTimeoutSeconds));
123#endif
124}
125
126TEST_F(EWK2ContextTest, ewk_context_cache_model)
127{
128    Ewk_Context* context = ewk_view_context_get(webView());
129
130    ASSERT_EQ(EWK_CACHE_MODEL_DOCUMENT_VIEWER, ewk_context_cache_model_get(context));
131
132    ASSERT_TRUE(ewk_context_cache_model_set(context, EWK_CACHE_MODEL_DOCUMENT_BROWSER));
133    ASSERT_EQ(EWK_CACHE_MODEL_DOCUMENT_BROWSER, ewk_context_cache_model_get(context));
134
135    ASSERT_TRUE(ewk_context_cache_model_set(context, EWK_CACHE_MODEL_PRIMARY_WEBBROWSER));
136    ASSERT_EQ(EWK_CACHE_MODEL_PRIMARY_WEBBROWSER, ewk_context_cache_model_get(context));
137
138    ASSERT_TRUE(ewk_context_cache_model_set(context, EWK_CACHE_MODEL_DOCUMENT_VIEWER));
139    ASSERT_EQ(EWK_CACHE_MODEL_DOCUMENT_VIEWER, ewk_context_cache_model_get(context));
140}
141
142TEST_F(EWK2ContextTest, ewk_context_web_process_model)
143{
144    Ewk_Context* context = ewk_view_context_get(webView());
145
146    ASSERT_EQ(EWK_PROCESS_MODEL_SHARED_SECONDARY, ewk_context_process_model_get(context));
147
148    Ewk_Page_Group* pageGroup = ewk_view_page_group_get(webView());
149    Evas* evas = ecore_evas_get(backingStore());
150    Evas_Smart* smart = evas_smart_class_new(&(ewkViewClass()->sc));
151
152    Evas_Object* webView1 = ewk_view_smart_add(evas, smart, context, pageGroup);
153    Evas_Object* webView2 = ewk_view_smart_add(evas, smart, context, pageGroup);
154
155    PlatformProcessIdentifier webView1WebProcessID = toImpl(EWKViewGetWKView(webView1))->page()->process().processIdentifier();
156    PlatformProcessIdentifier webView2WebProcessID = toImpl(EWKViewGetWKView(webView2))->page()->process().processIdentifier();
157
158    ASSERT_EQ(webView1WebProcessID, webView2WebProcessID);
159}
160
161TEST_F(EWK2ContextTestMultipleProcesses, ewk_context_web_process_model)
162{
163    Ewk_Context* context = ewk_view_context_get(webView());
164
165    ASSERT_EQ(EWK_PROCESS_MODEL_MULTIPLE_SECONDARY, ewk_context_process_model_get(context));
166
167    Ewk_Page_Group* pageGroup = ewk_view_page_group_get(webView());
168    Evas* evas = ecore_evas_get(backingStore());
169    Evas_Smart* smart = evas_smart_class_new(&(ewkViewClass()->sc));
170
171    Evas_Object* webView1 = ewk_view_smart_add(evas, smart, context, pageGroup);
172    Evas_Object* webView2 = ewk_view_smart_add(evas, smart, context, pageGroup);
173
174    PlatformProcessIdentifier webView1WebProcessID = toImpl(EWKViewGetWKView(webView1))->page()->process().processIdentifier();
175    PlatformProcessIdentifier webView2WebProcessID = toImpl(EWKViewGetWKView(webView2))->page()->process().processIdentifier();
176
177    ASSERT_NE(webView1WebProcessID, webView2WebProcessID);
178}
179
180TEST_F(EWK2ContextTest, ewk_context_network_process_model)
181{
182    Ewk_Context* context = ewk_view_context_get(webView());
183
184    ASSERT_EQ(EWK_PROCESS_MODEL_SHARED_SECONDARY, ewk_context_process_model_get(context));
185
186    Ewk_Page_Group* pageGroup = ewk_view_page_group_get(webView());
187    Evas* evas = ecore_evas_get(backingStore());
188    Evas_Smart* smart = evas_smart_class_new(&(ewkViewClass()->sc));
189
190    Evas_Object* webView1 = ewk_view_smart_add(evas, smart, context, pageGroup);
191    Evas_Object* webView2 = ewk_view_smart_add(evas, smart, context, pageGroup);
192
193    PlatformProcessIdentifier webView1WebProcessID = toImpl(EWKViewGetWKView(webView1))->page()->process().processIdentifier();
194    PlatformProcessIdentifier webView2WebProcessID = toImpl(EWKViewGetWKView(webView2))->page()->process().processIdentifier();
195
196    ASSERT_EQ(webView1WebProcessID, webView2WebProcessID);
197
198    ASSERT_TRUE(toImpl(EWKViewGetWKView(webView1))->page()->process().context().networkProcess() == nullptr);
199    ASSERT_TRUE(toImpl(EWKViewGetWKView(webView2))->page()->process().context().networkProcess() == nullptr);
200}
201
202
203TEST_F(EWK2ContextTestMultipleProcesses, ewk_context_network_process_model)
204{
205    Ewk_Context* context = ewk_view_context_get(webView());
206
207    ASSERT_EQ(EWK_PROCESS_MODEL_MULTIPLE_SECONDARY, ewk_context_process_model_get(context));
208
209    Ewk_Page_Group* pageGroup = ewk_view_page_group_get(webView());
210    Evas* evas = ecore_evas_get(backingStore());
211    Evas_Smart* smart = evas_smart_class_new(&(ewkViewClass()->sc));
212
213    Evas_Object* webView1 = ewk_view_smart_add(evas, smart, context, pageGroup);
214    Evas_Object* webView2 = ewk_view_smart_add(evas, smart, context, pageGroup);
215
216    PlatformProcessIdentifier webView1WebProcessID = toImpl(EWKViewGetWKView(webView1))->page()->process().processIdentifier();
217    PlatformProcessIdentifier webView2WebProcessID = toImpl(EWKViewGetWKView(webView2))->page()->process().processIdentifier();
218    PlatformProcessIdentifier webView1NetworkProcessID = toImpl(EWKViewGetWKView(webView1))->page()->process().context().networkProcess()->processIdentifier();
219    PlatformProcessIdentifier webView2NetworkProcessID = toImpl(EWKViewGetWKView(webView2))->page()->process().context().networkProcess()->processIdentifier();
220
221    ASSERT_NE(webView1WebProcessID, webView2WebProcessID);
222    ASSERT_NE(webView1WebProcessID, webView1NetworkProcessID);
223    ASSERT_NE(webView1WebProcessID, webView2NetworkProcessID);
224}
225
226TEST_F(EWK2ContextTest, ewk_context_new)
227{
228    Ewk_Context* context = ewk_context_new();
229    ASSERT_TRUE(context);
230    ewk_object_unref(context);
231}
232
233TEST_F(EWK2ContextTest, ewk_context_new_with_injected_bundle_path)
234{
235    Ewk_Context* context = ewk_context_new_with_injected_bundle_path(environment->injectedBundleSample());
236    ASSERT_TRUE(context);
237    ewk_object_unref(context);
238}
239
240TEST_F(EWK2ContextTest, ewk_context_additional_plugin_path_set)
241{
242    Ewk_Context* context = ewk_view_context_get(webView());
243
244    ASSERT_FALSE(ewk_context_additional_plugin_path_set(context, 0));
245
246    ASSERT_TRUE(ewk_context_additional_plugin_path_set(context, "/plugins"));
247
248    /* FIXME: Get additional plugin path and compare with the path. */
249}
250
251static char* s_acceptLanguages = nullptr;
252
253static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
254{
255    if (message->method != SOUP_METHOD_GET) {
256        soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
257        return;
258    }
259
260    soup_message_set_status(message, SOUP_STATUS_OK);
261    s_acceptLanguages = strdup(soup_message_headers_get_one(message->request_headers, "Accept-Language"));
262
263    soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, s_acceptLanguages, strlen(s_acceptLanguages));
264    soup_message_body_complete(message->response_body);
265}
266
267TEST_F(EWK2UnitTestBase, ewk_context_preferred_languages)
268{
269    Eina_List* acceptLanguages;
270    acceptLanguages = eina_list_append(acceptLanguages, "ko_kr");
271    acceptLanguages = eina_list_append(acceptLanguages, "fr");
272    acceptLanguages = eina_list_append(acceptLanguages, "en");
273
274    ewk_context_preferred_languages_set(acceptLanguages);
275
276    std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>();
277    httpServer->run(serverCallback);
278
279    ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
280    ASSERT_STREQ("ko-kr, fr;q=0.90, en;q=0.80", s_acceptLanguages);
281    free(s_acceptLanguages);
282
283    ewk_context_preferred_languages_set(nullptr);
284    ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath("/index.html").data()));
285    ASSERT_STREQ("en-US", s_acceptLanguages);
286    free(s_acceptLanguages);
287}
288