1/* 2 * Copyright (C) 2012 Intel Corporation. All rights reserved. 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/EWK2UnitTestServer.h" 30#include <sys/stat.h> 31#include <sys/types.h> 32#include <stdio.h> 33#include <stdlib.h> 34#include <unistd.h> 35 36using namespace EWK2UnitTest; 37using namespace WTF; 38 39extern EWK2UnitTestEnvironment* environment; 40 41static const char serverSuggestedFilename[] = "webkit-downloaded-file"; 42static const char testFilePath[] = "/test.pdf"; 43 44class EWK2DownloadJobTest : public EWK2UnitTestBase { 45public: 46 struct DownloadTestData { 47 const char* fileUrl; 48 const char* destinationPath; 49 }; 50 51 static bool fileExists(const char* path) 52 { 53 struct stat buf; 54 return !stat(path, &buf); 55 } 56 57 static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, void*) 58 { 59 if (message->method != SOUP_METHOD_GET) { 60 soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); 61 return; 62 } 63 64 Eina_Strbuf* filePath = eina_strbuf_new(); 65 eina_strbuf_append(filePath, TEST_RESOURCES_DIR); 66 eina_strbuf_append(filePath, path); 67 68 Eina_File* f = eina_file_open(eina_strbuf_string_get(filePath), false); 69 eina_strbuf_free(filePath); 70 if (!f) { 71 soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); 72 soup_message_body_complete(message->response_body); 73 return; 74 } 75 76 size_t fileSize = eina_file_size_get(f); 77 78 void* contents = eina_file_map_all(f, EINA_FILE_POPULATE); 79 if (!contents) { 80 soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); 81 soup_message_body_complete(message->response_body); 82 return; 83 } 84 85 soup_message_set_status(message, SOUP_STATUS_OK); 86 87 Eina_Strbuf* contentDisposition = eina_strbuf_new(); 88 eina_strbuf_append_printf(contentDisposition, "filename=%s", serverSuggestedFilename); 89 soup_message_headers_append(message->response_headers, "Content-Disposition", eina_strbuf_string_get(contentDisposition)); 90 eina_strbuf_free(contentDisposition); 91 92 soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, contents, fileSize); 93 soup_message_body_complete(message->response_body); 94 95 eina_file_map_free(f, contents); 96 eina_file_close(f); 97 } 98 99 static void on_download_requested(void* userData, Evas_Object* webview, void* eventInfo) 100 { 101 DownloadTestData* testData = static_cast<DownloadTestData*>(userData); 102 Ewk_Download_Job* download = static_cast<Ewk_Download_Job*>(eventInfo); 103 ASSERT_EQ(EWK_DOWNLOAD_JOB_STATE_NOT_STARTED, ewk_download_job_state_get(download)); 104 ASSERT_EQ(0, ewk_download_job_estimated_progress_get(download)); 105 ASSERT_EQ(0, ewk_download_job_elapsed_time_get(download)); 106 ASSERT_EQ(0, ewk_download_job_received_data_size_get(download)); 107 108 Ewk_Url_Request* request = ewk_download_job_request_get(download); 109 ASSERT_TRUE(request); 110 EXPECT_STREQ(testData->fileUrl, ewk_url_request_url_get(request)); 111 112 Ewk_Url_Response* response = ewk_download_job_response_get(download); 113 ASSERT_TRUE(response); 114 EXPECT_STREQ("application/pdf", ewk_url_response_mime_type_get(response)); 115 116 EXPECT_STREQ(serverSuggestedFilename, ewk_download_job_suggested_filename_get(download)); 117 118 ASSERT_FALSE(fileExists(testData->destinationPath)); 119 ewk_download_job_destination_set(download, testData->destinationPath); 120 EXPECT_STREQ(testData->destinationPath, ewk_download_job_destination_get(download)); 121 } 122 123 static void on_download_cancelled(void* userData, Evas_Object* webview, void* eventInfo) 124 { 125 fprintf(stderr, "Download was cancelled.\n"); 126 ecore_main_loop_quit(); 127 FAIL(); 128 } 129 130 static void on_download_failed(void* userData, Evas_Object* webview, void* eventInfo) 131 { 132 Ewk_Download_Job_Error* downloadError = static_cast<Ewk_Download_Job_Error*>(eventInfo); 133 fprintf(stderr, "Download error: %s\n", ewk_error_description_get(downloadError->error)); 134 ecore_main_loop_quit(); 135 FAIL(); 136 } 137 138 static void on_download_finished(void* userData, Evas_Object* webview, void* eventInfo) 139 { 140 DownloadTestData* testData = static_cast<DownloadTestData*>(userData); 141 Ewk_Download_Job* download = static_cast<Ewk_Download_Job*>(eventInfo); 142 143 ASSERT_EQ(1, ewk_download_job_estimated_progress_get(download)); 144 ASSERT_EQ(EWK_DOWNLOAD_JOB_STATE_FINISHED, ewk_download_job_state_get(download)); 145 ASSERT_GT(ewk_download_job_elapsed_time_get(download), 0); 146 ASSERT_GT(ewk_download_job_received_data_size_get(download), 0); 147 148 ASSERT_TRUE(fileExists(testData->destinationPath)); 149 150 ecore_main_loop_quit(); 151 } 152}; 153 154TEST_F(EWK2DownloadJobTest, ewk_download) 155{ 156 std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>(); 157 httpServer->run(serverCallback); 158 159 CString fileUrl = httpServer->getURLForPath(testFilePath); 160 161 char destinationDirectory[] = "/tmp/ewk2_download_job-XXXXXX"; 162 ASSERT_TRUE(mkdtemp(destinationDirectory)); 163 char destinationPath[64]; 164 snprintf(destinationPath, sizeof(destinationPath), "%s/pdf-file", destinationDirectory); 165 166 DownloadTestData userData = { fileUrl.data(), destinationPath }; 167 ASSERT_FALSE(fileExists(destinationPath)); 168 169 evas_object_smart_callback_add(webView(), "download,request", on_download_requested, &userData); 170 evas_object_smart_callback_add(webView(), "download,cancel", on_download_cancelled, &userData); 171 evas_object_smart_callback_add(webView(), "download,failed", on_download_failed, &userData); 172 evas_object_smart_callback_add(webView(), "download,finished", on_download_finished, &userData); 173 174 // Download test pdf 175 ewk_view_url_set(webView(), fileUrl.data()); 176 ecore_main_loop_begin(); 177 178 // Clean up 179 unlink(destinationPath); 180 rmdir(destinationDirectory); 181} 182