1/*
2 * Copyright (C) 2012 Samsung Electronics
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#include "UnitTestUtils/EWK2UnitTestBase.h"
29#include "UnitTestUtils/EWK2UnitTestEnvironment.h"
30#include "UnitTestUtils/EWK2UnitTestServer.h"
31#include "ewk_security_origin_private.h"
32#include <EWebKit2.h>
33#include <Ecore.h>
34#include <wtf/PassOwnPtr.h>
35
36using namespace EWK2UnitTest;
37
38extern EWK2UnitTestEnvironment* environment;
39
40struct OriginData {
41 Eina_List* originList;
42 Ewk_Application_Cache_Manager* manager;
43 bool didReceiveOriginsCallback;
44 bool isSynchronized;
45 unsigned timeoutSeconds;
46 const char* expectedProtocol;
47 const char* expectedHost;
48 const unsigned expectedPort;
49
50 OriginData(Ewk_Application_Cache_Manager* manager, const char* protocol, const char* host, const unsigned port)
51 : originList(0)
52 , manager(manager)
53 , didReceiveOriginsCallback(false)
54 , isSynchronized(false)
55 , timeoutSeconds(10)
56 , expectedProtocol(protocol)
57 , expectedHost(host)
58 , expectedPort(port)
59 { }
60};
61
62const char* applicationCacheHtml =
63 "<html manifest='test.appcache'>"
64 "<head>"
65 "<title>application cache test</title>"
66 "<script type='text/javascript'>"
67 "setTimeout(function() { document.getElementById('clock').value = new Date(); }, 1000);"
68 "</script>"
69 "<link rel='stylesheet' href='clock.css'>"
70 "</head>"
71 "<body>"
72 "<p> The time is: <output id='clock'></output></p>"
73 "</body>"
74 "</html>";
75const char* applicationCacheManifest = "CACHE MANIFEST\n"
76 "application_cache.html\n"
77 "clock.css";
78const char* applicationCacheCss = "output { font:2em sans-serif; }";
79static const char applicationCacheHtmlFile[] = "/application_cache.html";
80static const char applicationCacheManifestFile[] = "/test.appcache";
81static const char applicationCacheCssFile[] = "/clock.css";
82
83static void getApplicationCacheOriginsCallback(Eina_List* origins, Ewk_Error* error, void* userData)
84{
85 ASSERT_FALSE(error);
86
87 OriginData* originData = static_cast<OriginData*>(userData);
88 originData->didReceiveOriginsCallback = true;
89
90 Eina_List* l;
91 void* data;
92 EINA_LIST_FOREACH(origins, l, data) {
93 originData->originList = eina_list_append(originData->originList, data);
94 Ewk_Security_Origin* origin = static_cast<Ewk_Security_Origin*>(data);
95 if (!strcmp(ewk_security_origin_protocol_get(origin), originData->expectedProtocol)
96 && !strcmp(ewk_security_origin_host_get(origin), originData->expectedHost)
97 && ewk_security_origin_port_get(origin) == originData->expectedPort) {
98 originData->isSynchronized = true;
99 ecore_main_loop_quit();
100 }
101 }
102}
103static void serverCallback(SoupServer*, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
104{
105 if (message->method != SOUP_METHOD_GET) {
106 soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
107 return;
108 }
109
110 soup_message_set_status(message, SOUP_STATUS_OK);
111 Eina_Strbuf* body = eina_strbuf_new();
112
113 if (!strcmp(path, applicationCacheHtmlFile)) {
114 eina_strbuf_append_printf(body, applicationCacheHtml, 0);
115 const size_t bodyLength = eina_strbuf_length_get(body);
116 soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, eina_strbuf_string_steal(body), bodyLength);
117 } else if (!strcmp(path, applicationCacheManifestFile)) {
118 eina_strbuf_append_printf(body, applicationCacheManifest, 0);
119 const size_t bodyLength = eina_strbuf_length_get(body);
120 soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, eina_strbuf_string_steal(body), bodyLength);
121 } else if (!strcmp(path, applicationCacheCssFile)) {
122 eina_strbuf_append_printf(body, applicationCacheCss, 0);
123 const size_t bodyLength = eina_strbuf_length_get(body);
124 soup_message_body_append(message->response_body, SOUP_MEMORY_TAKE, eina_strbuf_string_steal(body), bodyLength);
125 } else
126 soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
127
128 eina_strbuf_free(body);
129 soup_message_body_complete(message->response_body);
130}
131
132static bool timerCallback(void* userData)
133{
134 OriginData* originData = static_cast<OriginData*>(userData);
135
136 if (originData->isSynchronized || !--(originData->timeoutSeconds)) {
137 ecore_main_loop_quit();
138
139 return ECORE_CALLBACK_CANCEL;
140 }
141
142 if (originData->didReceiveOriginsCallback) {
143 originData->didReceiveOriginsCallback = false;
144 ewk_application_cache_manager_origins_get(originData->manager, getApplicationCacheOriginsCallback, originData);
145 }
146
147 return ECORE_CALLBACK_RENEW;
148}
149
150TEST_F(EWK2UnitTestBase, ewk_application_cache_manager_origins_get)
151{
152 Evas_Object* view = webView();
153 OwnPtr<EWK2UnitTestServer> httpServer = adoptPtr(new EWK2UnitTestServer);
154 httpServer->run(serverCallback);
155
156 ASSERT_TRUE(loadUrlSync(httpServer->getURLForPath(applicationCacheHtmlFile).data()));
157
158 OriginData originData(ewk_context_application_cache_manager_get(ewk_view_context_get(view)), "http", "127.0.0.1", httpServer->getPort());
159 ASSERT_TRUE(ewk_application_cache_manager_origins_get(originData.manager, getApplicationCacheOriginsCallback, &originData));
160 Ecore_Timer* application_cache_timer = ecore_timer_add(1, reinterpret_cast<Ecore_Task_Cb>(timerCallback), &originData);
161
162 ecore_main_loop_begin();
163 if (application_cache_timer)
164 ecore_timer_del(application_cache_timer);
165
166 ASSERT_TRUE(originData.isSynchronized);
167 ASSERT_LE(1, eina_list_count(originData.originList));
168}