blob: c26e53471bf1162bd92cf90abb0e395a4eec1a51 [file] [log] [blame]
/*
* Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2,1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <errno.h>
#include <unistd.h>
#include <glib/gstdio.h>
#include <webkit/webkit.h>
#if GTK_CHECK_VERSION(2, 14, 0)
GMainLoop* loop;
char* temporaryFilename = NULL;
WebKitDownload* theDownload = NULL;
static void
test_webkit_download_create(void)
{
WebKitNetworkRequest* request;
WebKitDownload* download;
const gchar* uri = "http://example.com";
gchar* tmpDir;
request = webkit_network_request_new(uri);
download = webkit_download_new(request);
g_object_unref(request);
g_assert_cmpstr(webkit_download_get_uri(download), ==, uri);
g_assert(webkit_download_get_network_request(download) == request);
g_assert(g_strrstr(uri, webkit_download_get_suggested_filename(download)));
g_assert(webkit_download_get_status(download) == WEBKIT_DOWNLOAD_STATUS_CREATED);
g_assert(!webkit_download_get_total_size(download));
g_assert(!webkit_download_get_current_size(download));
g_assert(!webkit_download_get_progress(download));
g_assert(!webkit_download_get_elapsed_time(download));
tmpDir = g_filename_to_uri(g_get_tmp_dir(), NULL, NULL);
webkit_download_set_destination_uri(download, tmpDir);
g_assert_cmpstr(tmpDir, ==, webkit_download_get_destination_uri(download));;
g_free(tmpDir);
g_object_unref(download);
}
static gboolean
navigation_policy_decision_requested_cb(WebKitWebView* web_view,
WebKitWebFrame* web_frame,
WebKitNetworkRequest* request,
WebKitWebNavigationAction* action,
WebKitWebPolicyDecision* decision,
gpointer data)
{
webkit_web_policy_decision_download(decision);
return TRUE;
}
static void
notify_status_cb(GObject* object, GParamSpec* pspec, gpointer data)
{
WebKitDownload* download = WEBKIT_DOWNLOAD(object);
switch (webkit_download_get_status(download)) {
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
case WEBKIT_DOWNLOAD_STATUS_ERROR:
g_main_loop_quit(loop);
break;
case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
g_assert_not_reached();
break;
default:
break;
}
}
static gboolean
set_filename(gchar* filename)
{
gchar *uri = g_filename_to_uri(filename, NULL, NULL);
webkit_download_set_destination_uri(theDownload, uri);
g_free(uri);
webkit_download_start(theDownload);
return FALSE;
}
static void
handle_download_requested_cb(WebKitDownload* download,
gboolean* beenThere,
gboolean asynch)
{
theDownload = download;
*beenThere = TRUE;
if (temporaryFilename) {
if (asynch) {
g_idle_add((GSourceFunc)set_filename, temporaryFilename);
} else {
gchar *uri = g_filename_to_uri(temporaryFilename, NULL, NULL);
if (uri)
webkit_download_set_destination_uri(download, uri);
g_free(uri);
}
}
g_signal_connect(download, "notify::status",
G_CALLBACK(notify_status_cb), NULL);
}
static gboolean
download_requested_cb(WebKitWebView* web_view,
WebKitDownload* download,
gboolean* beenThere)
{
handle_download_requested_cb(download, beenThere, FALSE);
return TRUE;
}
static gboolean
download_requested_asynch_cb(WebKitWebView* web_view,
WebKitDownload* download,
gboolean* beenThere)
{
handle_download_requested_cb(download, beenThere, TRUE);
return TRUE;
}
static void
test_webkit_download_perform(gboolean asynch)
{
WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
GCallback downloadRequestCallback = NULL;
g_object_ref_sink(G_OBJECT(webView));
g_signal_connect(webView, "navigation-policy-decision-requested",
G_CALLBACK(navigation_policy_decision_requested_cb),
NULL);
if (asynch)
downloadRequestCallback = G_CALLBACK(download_requested_asynch_cb);
else
downloadRequestCallback = G_CALLBACK(download_requested_cb);
gboolean beenThere = FALSE;
g_signal_connect(webView, "download-requested",
downloadRequestCallback, &beenThere);
/* Preparation; FIXME: we should move this code to a test
* utilities file, because we have a very similar one in
* testwebframe.c */
GError *error = NULL;
gchar* filename;
int fd = g_file_open_tmp("webkit-testwebdownload-XXXXXX", &filename, &error);
close(fd);
if (error)
g_critical("Failed to open a temporary file for writing: %s.", error->message);
if (g_unlink(filename) == -1)
g_critical("Failed to delete the temporary file: %s.", g_strerror(errno));
theDownload = NULL;
temporaryFilename = filename;
loop = g_main_loop_new(NULL, TRUE);
webkit_web_view_load_uri(webView, "http://gnome.org/");
g_main_loop_run(loop);
g_assert_cmpint(beenThere, ==, TRUE);
g_assert_cmpint(g_file_test(temporaryFilename, G_FILE_TEST_IS_REGULAR), ==, TRUE);
g_unlink(temporaryFilename);
g_free(temporaryFilename);
temporaryFilename = NULL;
g_main_loop_unref(loop);
g_object_unref(webView);
}
static void
test_webkit_download_synch(void)
{
test_webkit_download_perform(FALSE);
}
static void
test_webkit_download_asynch(void)
{
test_webkit_download_perform(TRUE);
}
static gboolean mime_type_policy_decision_requested_cb(WebKitWebView* view, WebKitWebFrame* frame,
WebKitNetworkRequest* request, const char* mime_type,
WebKitWebPolicyDecision* decision, gpointer data)
{
webkit_web_policy_decision_download(decision);
return TRUE;
}
static void idle_quit_loop_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
{
if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED ||
webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FAILED)
g_main_loop_quit(loop);
}
static void
test_webkit_download_data(void)
{
gboolean beenThere = FALSE;
WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
g_object_ref_sink(webView);
g_signal_connect(webView, "download-requested",
G_CALLBACK(download_requested_cb),
&beenThere);
g_signal_connect(webView, "notify::load-status",
G_CALLBACK(idle_quit_loop_cb),
NULL);
g_signal_connect(webView, "mime-type-policy-decision-requested",
G_CALLBACK(mime_type_policy_decision_requested_cb),
NULL);
loop = g_main_loop_new(NULL, TRUE);
/* We're testing for a crash, so just not crashing is a pass */
webkit_web_view_load_uri(webView, "data:application/octect-stream,");
g_main_loop_run(loop);
g_assert_cmpint(beenThere, ==, TRUE);
g_main_loop_unref(loop);
g_object_unref(webView);
}
static void notifyDownloadStatusCallback(GObject *object, GParamSpec *pspec, gpointer data)
{
WebKitDownload *download = WEBKIT_DOWNLOAD(object);
WebKitNetworkResponse *response = webkit_download_get_network_response(download);
SoupMessage *message = webkit_network_response_get_message(response);
switch (webkit_download_get_status(download)) {
case WEBKIT_DOWNLOAD_STATUS_ERROR:
g_assert_cmpint(message->status_code, ==, 404);
g_main_loop_quit(loop);
break;
case WEBKIT_DOWNLOAD_STATUS_FINISHED:
case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
g_assert_not_reached();
break;
default:
break;
}
}
static void serverCallback(SoupServer *server, SoupMessage *message, const char *path, GHashTable *query, SoupClientContext *context, gpointer userData)
{
if (message->method != SOUP_METHOD_GET) {
soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED);
return;
}
soup_message_set_status(message, SOUP_STATUS_NOT_FOUND);
soup_message_body_complete(message->response_body);
}
static void test_webkit_download_not_found(void)
{
SoupServer *server = soup_server_new(SOUP_SERVER_PORT, 0, NULL);
soup_server_run_async(server);
soup_server_add_handler(server, NULL, serverCallback, NULL, NULL);
SoupURI *baseURI = soup_uri_new("http://127.0.0.1/");
soup_uri_set_port(baseURI, soup_server_get_port(server));
SoupURI *uri = soup_uri_new_with_base(baseURI, "/foo");
char *uriString = soup_uri_to_string(uri, FALSE);
soup_uri_free(uri);
loop = g_main_loop_new(NULL, TRUE);
WebKitNetworkRequest *request = webkit_network_request_new(uriString);
g_free (uriString);
WebKitDownload *download = webkit_download_new(request);
g_object_unref(request);
webkit_download_set_destination_uri(download, "file:///tmp/foo");
g_signal_connect(download, "notify::status", G_CALLBACK(notifyDownloadStatusCallback), NULL);
webkit_download_start(download);
g_main_loop_run(loop);
g_object_unref(download);
g_main_loop_unref(loop);
soup_uri_free(baseURI);
g_object_unref(server);
}
int main(int argc, char** argv)
{
gtk_test_init(&argc, &argv, NULL);
g_test_bug_base("https://bugs.webkit.org/");
g_test_add_func("/webkit/download/create", test_webkit_download_create);
g_test_add_func("/webkit/download/synch", test_webkit_download_synch);
g_test_add_func("/webkit/download/asynch", test_webkit_download_asynch);
g_test_add_func("/webkit/download/data", test_webkit_download_data);
g_test_add_func("/webkit/download/not-found", test_webkit_download_not_found);
return g_test_run ();
}
#else
int main(int argc, char** argv)
{
g_critical("You will need at least GTK+ 2.14.0 to run the unit tests.");
return 0;
}
#endif