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
30using namespace EWK2UnitTest;
31
32static const char storageHTML[] =
33    "<html><head><title>original title</title></head>"
34    "<body>"
35    "<script type='text/javascript'>"
36    " localStorage.setItem('item', 'storage');"
37    "</script>"
38    "</body></html>";
39
40class EWK2StorageManagerTest : public EWK2UnitTestBase {
41public:
42    struct OriginData {
43        Eina_List* originList;
44        Ewk_Storage_Manager* manager;
45        bool didReceiveOriginsCallback;
46        bool isSynchronized;
47        unsigned timeToCheck;
48
49        OriginData()
50            : originList(0)
51            , manager(0)
52            , didReceiveOriginsCallback(false)
53            , isSynchronized(false)
54            , timeToCheck(10)
55        { }
56    };
57
58    static void getStorageOriginsCallback(Eina_List* origins, void* userData)
59    {
60        OriginData* originData = static_cast<OriginData*>(userData);
61        originData->didReceiveOriginsCallback = true;
62
63        Eina_List* l;
64        void* data;
65        EINA_LIST_FOREACH(origins, l, data) {
66            Ewk_Security_Origin* origin = static_cast<Ewk_Security_Origin*>(data);
67            if (!strcmp(ewk_security_origin_protocol_get(origin), "http")
68                && !strcmp(ewk_security_origin_host_get(origin), "www.storagetest.com")
69                && !ewk_security_origin_port_get(origin)) {
70                    originData->originList = origins;
71                    originData->isSynchronized = true;
72                    return;
73            }
74        }
75        void* originItem;
76        EINA_LIST_FREE(origins, originItem)
77            ewk_object_unref(static_cast<Ewk_Object*>(originItem));
78    }
79
80    static Eina_Bool timerCallback(void* userData)
81    {
82        OriginData* originData = static_cast<OriginData*>(userData);
83
84        if (originData->isSynchronized || !--(originData->timeToCheck)) {
85            ecore_main_loop_quit();
86            return ECORE_CALLBACK_CANCEL;
87        }
88
89        if (originData->didReceiveOriginsCallback) {
90            originData->didReceiveOriginsCallback = false;
91            ewk_storage_manager_origins_async_get(originData->manager, getStorageOriginsCallback, originData);
92        }
93
94        return ECORE_CALLBACK_RENEW;
95    }
96
97protected:
98    bool checkOrigin(Eina_List* origins, Ewk_Security_Origin** origin, const char* protocol, const char* host, uint32_t port)
99    {
100        Eina_List* l;
101        void* data;
102        EINA_LIST_FOREACH(origins, l, data) {
103            *origin = static_cast<Ewk_Security_Origin*>(data);
104            if (!strcmp(ewk_security_origin_protocol_get(*origin), protocol)
105                && !strcmp(ewk_security_origin_host_get(*origin), host)
106                && !ewk_security_origin_port_get(*origin))
107                return true;
108        }
109
110        return false;
111    }
112
113    Ewk_Security_Origin* getOrigin(Eina_List* origins, Ewk_Security_Origin** origin, const char* protocol, const char* host, uint32_t port)
114    {
115        Eina_List* l;
116        void* data;
117        EINA_LIST_FOREACH(origins, l, data) {
118            *origin = static_cast<Ewk_Security_Origin*>(data);
119            if (!strcmp(ewk_security_origin_protocol_get(*origin), protocol)
120                && !strcmp(ewk_security_origin_host_get(*origin), host)
121                && !ewk_security_origin_port_get(*origin)) {
122                return *origin;
123            }
124        }
125
126        return nullptr;
127    }
128};
129
130TEST_F(EWK2StorageManagerTest, ewk_storage_manager_origins_async_get)
131{
132    Evas_Object* view = webView();
133
134    OriginData originData;
135    originData.manager = ewk_context_storage_manager_get(ewk_view_context_get(view));
136    ewk_storage_manager_entries_clear(originData.manager);
137
138    ewk_view_html_string_load(view, storageHTML, "http://www.storagetest.com", 0);
139    ASSERT_TRUE(waitUntilLoadFinished());
140
141    ASSERT_TRUE(ewk_storage_manager_origins_async_get(originData.manager, getStorageOriginsCallback, &originData));
142    Ecore_Timer* storageTimer = ecore_timer_add(1, timerCallback, &originData);
143
144    ecore_main_loop_begin();
145    storageTimer = nullptr;
146
147    ASSERT_TRUE(originData.isSynchronized);
148    ASSERT_EQ(1, eina_list_count(originData.originList));
149
150    void* originItem;
151    EINA_LIST_FREE(originData.originList, originItem)
152        ewk_object_unref(static_cast<Ewk_Object*>(originItem));
153}
154
155TEST_F(EWK2StorageManagerTest, ewk_storage_manager_entries_for_origin_delete)
156{
157    Evas_Object* view = webView();
158
159    OriginData originData;
160    originData.manager = ewk_context_storage_manager_get(ewk_view_context_get(view));
161    ewk_storage_manager_entries_clear(originData.manager);
162
163    ewk_view_html_string_load(view, storageHTML, "http://www.storagetest1.com", 0);
164    ASSERT_TRUE(waitUntilLoadFinished());
165    ewk_view_html_string_load(view, storageHTML, "http://www.storagetest2.com", 0);
166    ASSERT_TRUE(waitUntilLoadFinished());
167    ewk_view_html_string_load(view, storageHTML, "http://www.storagetest.com", 0);
168    ASSERT_TRUE(waitUntilLoadFinished());
169
170    ASSERT_TRUE(ewk_storage_manager_origins_async_get(originData.manager, getStorageOriginsCallback, &originData));
171    Ecore_Timer* storageTimer = ecore_timer_add(1, timerCallback, &originData);
172
173    ecore_main_loop_begin();
174    storageTimer = nullptr;
175
176    ASSERT_TRUE(originData.isSynchronized);
177    Ewk_Security_Origin* origin = 0;
178    ASSERT_TRUE(checkOrigin(originData.originList, &origin, "http", "www.storagetest1.com", 0));
179    ASSERT_EQ(3, eina_list_count(originData.originList));
180
181    ewk_storage_manager_entries_for_origin_del(originData.manager, getOrigin(originData.originList, &origin, "http", "www.storagetest1.com", 0));
182
183    void* originItem;
184    EINA_LIST_FREE(originData.originList, originItem)
185        ewk_object_unref(static_cast<Ewk_Object*>(originItem));
186
187    ASSERT_TRUE(ewk_storage_manager_origins_async_get(originData.manager, getStorageOriginsCallback, &originData));
188
189    storageTimer = ecore_timer_add(1, timerCallback, &originData);
190
191    ecore_main_loop_begin();
192    storageTimer = nullptr;
193
194    ASSERT_TRUE(originData.isSynchronized);
195    ASSERT_EQ(2, eina_list_count(originData.originList));
196    ASSERT_FALSE(checkOrigin(originData.originList, &origin, "http", "www.storagetest1.com", 0));
197
198    EINA_LIST_FREE(originData.originList, originItem)
199        ewk_object_unref(static_cast<Ewk_Object*>(originItem));
200}
201