Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2009 Jan Michael Alonzo
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 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 <glib.h>
     21 #include <gtk/gtk.h>
     22 #include <libsoup/soup.h>
     23 #include <string.h>
     24 #include <webkit/webkit.h>
     25 
     26 #if GTK_CHECK_VERSION(2, 14, 0)
     27 
     28 #define INDEX_HTML "<html></html>"
     29 #define MAIN_HTML "<html><head><script language=\"javascript\" src=\"/javascript.js\"></script></head><body><h1>hah</h1></html>"
     30 #define JAVASCRIPT "function blah () { var a = 1; }"
     31 
     32 GMainLoop* loop;
     33 SoupSession *session;
     34 char *base_uri;
     35 WebKitWebResource* main_resource;
     36 WebKitWebResource* sub_resource;
     37 
     38 typedef struct {
     39     WebKitWebResource* webResource;
     40     WebKitWebView* webView;
     41 } WebResourceFixture;
     42 
     43 /* For real request testing */
     44 static void
     45 server_callback (SoupServer *server, SoupMessage *msg,
     46                  const char *path, GHashTable *query,
     47                  SoupClientContext *context, gpointer data)
     48 {
     49     if (msg->method != SOUP_METHOD_GET) {
     50         soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
     51         return;
     52     }
     53 
     54     soup_message_set_status (msg, SOUP_STATUS_OK);
     55 
     56     /* Redirect */
     57     if (g_str_equal (path, "/")) {
     58         soup_message_set_status (msg, SOUP_STATUS_MOVED_PERMANENTLY);
     59 
     60         soup_message_headers_append (msg->response_headers,
     61                                      "Location", "/index.html");
     62     } else if (g_str_equal (path, "/index.html")) {
     63         soup_message_body_append (msg->response_body,
     64                                   SOUP_MEMORY_COPY,
     65                                   INDEX_HTML,
     66                                   strlen (INDEX_HTML));
     67     } else if (g_str_equal (path, "/main.html")) {
     68         soup_message_body_append (msg->response_body,
     69                                   SOUP_MEMORY_COPY,
     70                                   MAIN_HTML,
     71                                   strlen (MAIN_HTML));
     72     } else if (g_str_equal (path, "/javascript.js")) {
     73         soup_message_body_append (msg->response_body,
     74                                   SOUP_MEMORY_COPY,
     75                                   JAVASCRIPT,
     76                                   strlen (JAVASCRIPT));
     77     }
     78 
     79 
     80     soup_message_body_complete (msg->response_body);
     81 }
     82 
     83 static void web_resource_fixture_setup(WebResourceFixture* fixture, gconstpointer data)
     84 {
     85     fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
     86     g_object_ref_sink(fixture->webView);
     87     const gchar* webData = "<html></html>";
     88     fixture->webResource = webkit_web_resource_new(webData, strlen(webData), "http://example.com/", "text/html", "utf8", "Example.com");
     89     g_assert(fixture->webResource);
     90 }
     91 
     92 static void web_resource_fixture_teardown(WebResourceFixture* fixture, gconstpointer data)
     93 {
     94     g_assert(fixture->webResource);
     95     g_object_unref(fixture->webResource);
     96     g_object_unref(fixture->webView);
     97 }
     98 
     99 static void test_webkit_web_resource_get_url(WebResourceFixture* fixture, gconstpointer data)
    100 {
    101     gchar* url;
    102     g_object_get(G_OBJECT(fixture->webResource), "uri", &url, NULL);
    103     g_assert_cmpstr(url, ==, "http://example.com/");
    104     g_assert_cmpstr(webkit_web_resource_get_uri(fixture->webResource) ,==,"http://example.com/");
    105     g_free(url);
    106 }
    107 
    108 static void test_webkit_web_resource_get_data(WebResourceFixture* fixture, gconstpointer data)
    109 {
    110     GString* charData = webkit_web_resource_get_data(fixture->webResource);
    111     g_assert_cmpstr(charData->str, ==, "<html></html>");
    112 }
    113 
    114 static void test_webkit_web_resource_get_mime_type(WebResourceFixture* fixture, gconstpointer data)
    115 {
    116     gchar* mime_type;
    117     g_object_get(G_OBJECT(fixture->webResource), "mime-type", &mime_type, NULL);
    118     g_assert_cmpstr(mime_type, ==, "text/html");
    119     g_assert_cmpstr(webkit_web_resource_get_mime_type(fixture->webResource),==,"text/html");
    120     g_free(mime_type);
    121 }
    122 
    123 static void test_webkit_web_resource_get_encoding(WebResourceFixture* fixture, gconstpointer data)
    124 {
    125     gchar* text_encoding;
    126     g_object_get(G_OBJECT(fixture->webResource), "encoding", &text_encoding, NULL);
    127     g_assert_cmpstr(text_encoding, ==, "utf8");
    128     g_assert_cmpstr(webkit_web_resource_get_encoding(fixture->webResource),==,"utf8");
    129     g_free(text_encoding);
    130 }
    131 
    132 static void test_webkit_web_resource_get_frame_name(WebResourceFixture* fixture, gconstpointer data)
    133 {
    134     gchar* frame_name;
    135     g_object_get(G_OBJECT(fixture->webResource), "frame-name", &frame_name, NULL);
    136     g_assert_cmpstr(frame_name, ==, "Example.com");
    137     g_assert_cmpstr(webkit_web_resource_get_frame_name(fixture->webResource),==,"Example.com");
    138     g_free(frame_name);
    139 }
    140 
    141 static void resource_request_starting_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebKitWebResource* web_resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response, gpointer data)
    142 {
    143     gint* been_there = data;
    144     *been_there = *been_there + 1;
    145 
    146     if (*been_there == 1) {
    147         g_assert(!main_resource);
    148         main_resource = g_object_ref(web_resource);
    149 
    150         g_assert_cmpstr(webkit_web_resource_get_uri(web_resource), ==, base_uri);
    151 
    152         /* This should be a redirect, so the response must be NULL */
    153         g_assert(!response);
    154     } else if (*been_there == 2) {
    155         char* uri = g_strdup_printf("%sindex.html", base_uri);
    156 
    157         g_assert_cmpstr(webkit_web_resource_get_uri(web_resource), ==, uri);
    158 
    159         /* Cancel the request. */
    160         webkit_network_request_set_uri(request, "about:blank");
    161 
    162         g_free(uri);
    163     }
    164 }
    165 
    166 static void notify_load_status_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
    167 {
    168     if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED) {
    169         gboolean* been_there = data;
    170         *been_there = TRUE;
    171 
    172         g_assert_cmpstr(webkit_web_view_get_uri(web_view), ==, "about:blank");
    173 
    174         g_main_loop_quit(loop);
    175     }
    176 }
    177 
    178 static void test_web_resource_loading()
    179 {
    180     WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
    181     gint been_to_resource_request_starting = 0;
    182     gboolean been_to_load_finished = FALSE;
    183     WebKitWebFrame* web_frame;
    184     WebKitWebDataSource* data_source;
    185 
    186     loop = g_main_loop_new(NULL, TRUE);
    187 
    188     g_object_ref_sink(web_view);
    189 
    190     g_signal_connect(web_view, "resource-request-starting",
    191                      G_CALLBACK(resource_request_starting_cb),
    192                      &been_to_resource_request_starting);
    193 
    194     g_signal_connect(web_view, "notify::load-status",
    195                      G_CALLBACK(notify_load_status_cb),
    196                      &been_to_load_finished);
    197 
    198     webkit_web_view_load_uri(web_view, base_uri);
    199 
    200     /* We won't get finished immediately, because of the redirect */
    201     g_main_loop_run(loop);
    202 
    203     web_frame = webkit_web_view_get_main_frame(web_view);
    204     data_source = webkit_web_frame_get_data_source(web_frame);
    205 
    206     g_assert(main_resource);
    207     g_assert(webkit_web_data_source_get_main_resource(data_source) == main_resource);
    208     g_object_unref(main_resource);
    209 
    210     g_assert_cmpint(been_to_resource_request_starting, ==, 2);
    211     g_assert_cmpint(been_to_load_finished, ==, TRUE);
    212 
    213     g_object_unref(web_view);
    214     g_main_loop_unref(loop);
    215 }
    216 
    217 static void resource_request_starting_sub_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebKitWebResource* web_resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response, gpointer data)
    218 {
    219     if (!main_resource)
    220         main_resource = g_object_ref(web_resource);
    221     else if (!sub_resource)
    222       sub_resource = g_object_ref(web_resource);
    223 }
    224 
    225 static void notify_load_status_sub_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
    226 {
    227     if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED)
    228         g_main_loop_quit(loop);
    229 }
    230 
    231 static gboolean idle_quit_loop_cb(gpointer data)
    232 {
    233     g_main_loop_quit(loop);
    234     return FALSE;
    235 }
    236 
    237 static void test_web_resource_sub_resource_loading()
    238 {
    239     WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
    240     WebKitWebFrame* web_frame;
    241     WebKitWebDataSource* data_source;
    242     GList* sub_resources;
    243     char* uri = g_strdup_printf("%smain.html", base_uri);
    244 
    245     main_resource = NULL;
    246 
    247     loop = g_main_loop_new(NULL, TRUE);
    248 
    249     g_object_ref_sink(web_view);
    250 
    251     g_signal_connect(web_view, "resource-request-starting",
    252                      G_CALLBACK(resource_request_starting_sub_cb),
    253                      NULL);
    254 
    255     g_signal_connect(web_view, "notify::load-status",
    256                      G_CALLBACK(notify_load_status_sub_cb),
    257                      NULL);
    258 
    259     webkit_web_view_load_uri(web_view, uri);
    260 
    261     g_main_loop_run(loop);
    262 
    263     /* The main resource should be loaded; now let's wait for the sub-resource to load */
    264     g_idle_add(idle_quit_loop_cb, NULL);
    265     g_main_loop_run(loop);
    266 
    267     g_assert(main_resource && sub_resource);
    268     g_assert(main_resource != sub_resource);
    269 
    270     web_frame = webkit_web_view_get_main_frame(web_view);
    271     data_source = webkit_web_frame_get_data_source(web_frame);
    272 
    273     g_assert(webkit_web_data_source_get_main_resource(data_source) == main_resource);
    274     g_object_unref(main_resource);
    275 
    276     sub_resources = webkit_web_data_source_get_subresources(data_source);
    277     // Expected resources: javascripts.js, favicon.ico
    278     g_assert(sub_resources);
    279     g_assert(sub_resources->next);
    280     g_assert(!sub_resources->next->next);
    281 
    282     // Test that the object we got from the data source is the same
    283     // that went through resource-request-starting. Note that the order is
    284     // not important (and not guaranteed since the resources are stored in a
    285     // hashtable).
    286     g_assert(WEBKIT_WEB_RESOURCE(sub_resources->data) == sub_resource
    287              || WEBKIT_WEB_RESOURCE(sub_resources->next->data) == sub_resource);
    288 
    289     g_object_unref(web_view);
    290     g_main_loop_unref(loop);
    291 }
    292 
    293 int main(int argc, char** argv)
    294 {
    295     SoupServer* server;
    296     SoupURI* soup_uri;
    297 
    298     g_thread_init(NULL);
    299     gtk_test_init(&argc, &argv, NULL);
    300 
    301     server = soup_server_new(SOUP_SERVER_PORT, 0, NULL);
    302     soup_server_run_async(server);
    303 
    304     soup_server_add_handler(server, NULL, server_callback, NULL, NULL);
    305 
    306     soup_uri = soup_uri_new("http://127.0.0.1/");
    307     soup_uri_set_port(soup_uri, soup_server_get_port(server));
    308 
    309     base_uri = soup_uri_to_string(soup_uri, FALSE);
    310     soup_uri_free(soup_uri);
    311 
    312     g_test_bug_base("https://bugs.webkit.org/");
    313     g_test_add("/webkit/webresource/get_url",
    314                WebResourceFixture, 0, web_resource_fixture_setup,
    315                test_webkit_web_resource_get_url, web_resource_fixture_teardown);
    316     g_test_add("/webkit/webresource/get_mime_type",
    317                WebResourceFixture, 0, web_resource_fixture_setup,
    318                test_webkit_web_resource_get_mime_type, web_resource_fixture_teardown);
    319     g_test_add("/webkit/webresource/get_text_encoding_name",
    320                WebResourceFixture, 0, web_resource_fixture_setup,
    321                test_webkit_web_resource_get_encoding, web_resource_fixture_teardown);
    322     g_test_add("/webkit/webresource/get_frame_name",
    323                WebResourceFixture, 0, web_resource_fixture_setup,
    324                test_webkit_web_resource_get_frame_name, web_resource_fixture_teardown);
    325     g_test_add("/webkit/webresource/get_data",
    326                WebResourceFixture, 0, web_resource_fixture_setup,
    327                test_webkit_web_resource_get_data, web_resource_fixture_teardown);
    328 
    329     g_test_add_func("/webkit/webresource/loading", test_web_resource_loading);
    330     g_test_add_func("/webkit/webresource/sub_resource_loading", test_web_resource_sub_resource_loading);
    331 
    332     return g_test_run ();
    333 }
    334 
    335 #else
    336 int main(int argc, char** argv)
    337 {
    338     g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
    339     return 0;
    340 }
    341 
    342 #endif
    343