/*
 * Copyright (C) 2012, 2014 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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 "config.h"

#include "WebKitTestServer.h"
#include "WebViewTest.h"
#include <glib/gstdio.h>
#include <libsoup/soup.h>
#include <string.h>
#include <wtf/Vector.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>

class DownloadTest: public Test {
public:
    MAKE_GLIB_TEST_FIXTURE(DownloadTest);

    enum DownloadEvent {
        Started,
        ReceivedResponse,
        CreatedDestination,
        ReceivedData,
        Failed,
        Finished
    };

    static void receivedResponseCallback(WebKitDownload* download, GParamSpec*, DownloadTest* test)
    {
        g_assert_nonnull(webkit_download_get_response(download));
        test->receivedResponse(download);
    }

    static void createdDestinationCallback(WebKitDownload* download, const gchar* destination, DownloadTest* test)
    {
        g_assert_nonnull(webkit_download_get_destination(download));
#if ENABLE(2022_GLIB_API)
        g_assert_true(g_path_is_absolute(destination));
        const char* destinationPath = destination;
#else
        // Old API always passes a URI to created-destination for backwards compatibility.
        g_assert_true(g_str_has_prefix(destination, "file://"));
        GUniquePtr<char> filename(g_filename_from_uri(destination, nullptr, nullptr));
        const char* destinationPath = filename.get();
#endif
        g_assert_cmpstr(webkit_download_get_destination(download), ==, destinationPath);
        GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(destinationPath));
        g_assert_true(g_file_query_exists(file.get(), nullptr));
        test->createdDestination(download);
    }

    static void receivedDataCallback(WebKitDownload* download, guint64 dataLength, DownloadTest* test)
    {
        test->receivedData(download, dataLength);
    }

    static void finishedCallback(WebKitDownload* download, DownloadTest* test)
    {
        test->finished(download);
    }

    static void failedCallback(WebKitDownload* download, GError* error, DownloadTest* test)
    {
        g_assert_nonnull(error);

        const char* destination = webkit_download_get_destination(download);
        if (destination) {
            GUniquePtr<char> tempFilePath(g_strconcat(destination, ".wkdownload", nullptr));
            GRefPtr<GFile> tempFile = adoptGRef(g_file_new_for_path(tempFilePath.get()));
            g_assert_false(g_file_query_exists(tempFile.get(), nullptr));
        }

        test->failed(download, error);
    }

    static gboolean decideDestinationCallback(WebKitDownload* download, const gchar* suggestedFilename, DownloadTest* test)
    {
        g_assert_nonnull(suggestedFilename);
        test->decideDestination(download, suggestedFilename);
        return TRUE;
    }

    static void downloadStartedCallback(DownloadTest* test, WebKitDownload* download)
    {
        g_assert_nonnull(webkit_download_get_request(download));
        test->started(download);
        g_signal_connect(download, "notify::response", G_CALLBACK(receivedResponseCallback), test);
        g_signal_connect(download, "created-destination", G_CALLBACK(createdDestinationCallback), test);
        g_signal_connect(download, "received-data", G_CALLBACK(receivedDataCallback), test);
        g_signal_connect(download, "finished", G_CALLBACK(finishedCallback), test);
        g_signal_connect(download, "failed", G_CALLBACK(failedCallback), test);
        g_signal_connect(download, "decide-destination", G_CALLBACK(decideDestinationCallback), test);
    }

    DownloadTest()
        : m_mainLoop(g_main_loop_new(nullptr, TRUE))
        , m_downloadSize(0)
        , m_allowOverwrite(false)
    {
#if ENABLE(2022_GLIB_API)
        g_signal_connect_swapped(m_networkSession.get(), "download-started", G_CALLBACK(downloadStartedCallback), this);
#else
        g_signal_connect_swapped(m_webContext.get(), "download-started", G_CALLBACK(downloadStartedCallback), this);
#endif
    }

    ~DownloadTest()
    {
#if ENABLE(2022_GLIB_API)
        g_signal_handlers_disconnect_matched(m_networkSession.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
#else
        g_signal_handlers_disconnect_matched(m_webContext.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
#endif
        g_main_loop_unref(m_mainLoop);
    }

    virtual void started(WebKitDownload* download)
    {
        m_downloadSize = 0;
        m_downloadEvents.clear();
        m_downloadEvents.append(Started);
    }

    virtual void receivedResponse(WebKitDownload* download)
    {
        m_downloadEvents.append(ReceivedResponse);
    }

    virtual void createdDestination(WebKitDownload* download)
    {
        m_downloadEvents.append(CreatedDestination);
    }

    virtual void receivedData(WebKitDownload* download, guint64 dataLength)
    {
        m_downloadSize += dataLength;
        if (!m_downloadEvents.contains(ReceivedData))
            m_downloadEvents.append(ReceivedData);
    }

    virtual void finished(WebKitDownload* download)
    {
        g_assert_cmpuint(m_downloadSize, ==, webkit_download_get_received_data_length(download));
        m_downloadEvents.append(Finished);
        g_main_loop_quit(m_mainLoop);
    }

    virtual void failed(WebKitDownload* download, GError* error)
    {
        m_downloadEvents.append(Failed);
    }

    virtual void decideDestination(WebKitDownload* download, const gchar* suggestedFilename)
    {
        GUniquePtr<char> destination(g_build_filename(Test::dataDirectory(), suggestedFilename, nullptr));
        webkit_download_set_destination(download, destination.get());
    }

    GRefPtr<WebKitDownload> downloadURIAndWaitUntilFinished(const CString& requestURI)
    {
#if ENABLE(2022_GLIB_API)
        GRefPtr<WebKitDownload> download = adoptGRef(webkit_network_session_download_uri(m_networkSession.get(), requestURI.data()));
#else
        GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_context_download_uri(m_webContext.get(), requestURI.data()));
#endif
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));

        g_assert_false(webkit_download_get_allow_overwrite(download.get()));
        webkit_download_set_allow_overwrite(download.get(), m_allowOverwrite);
        g_assert_cmpint(webkit_download_get_allow_overwrite(download.get()), ==, m_allowOverwrite);

        WebKitURIRequest* request = webkit_download_get_request(download.get());
        g_assert_nonnull(request);
        ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, requestURI);

        g_main_loop_run(m_mainLoop);

        return download;
    }

    void checkDestinationAndDeleteFile(WebKitDownload* download, const char* expectedName)
    {
        if (!webkit_download_get_destination(download))
            return;
        GRefPtr<GFile> destFile = adoptGRef(g_file_new_for_path(webkit_download_get_destination(download)));
        GUniquePtr<char> destBasename(g_file_get_basename(destFile.get()));
        g_assert_cmpstr(destBasename.get(), ==, expectedName);

        g_file_delete(destFile.get(), nullptr, nullptr);
    }

    GMainLoop* m_mainLoop;
    Vector<DownloadEvent> m_downloadEvents;
    guint64 m_downloadSize;
    bool m_allowOverwrite;
};

static GRefPtr<WebKitDownload> downloadLocalFileSuccessfully(DownloadTest* test, const char* filename)
{
    GUniquePtr<char> sourcePath(g_build_filename(Test::getResourcesDir().data(), filename, nullptr));
    GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get()));
    GRefPtr<GFileInfo> sourceInfo = adoptGRef(g_file_query_info(source.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), 0, 0));
    GUniquePtr<char> sourceURI(g_file_get_uri(source.get()));
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished(sourceURI.get());
    g_assert_null(webkit_download_get_web_view(download.get()));

    Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
    g_assert_cmpint(events.size(), ==, 5);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::CreatedDestination);
    g_assert_cmpint(events[3], ==, DownloadTest::ReceivedData);
    g_assert_cmpint(events[4], ==, DownloadTest::Finished);

    WebKitURIRequest* request = webkit_download_get_request(download.get());
    g_assert_nonnull(request);
    g_assert_cmpstr(webkit_uri_request_get_uri(request), ==, sourceURI.get());

    g_assert_cmpint(test->m_downloadSize, ==, g_file_info_get_size(sourceInfo.get()));
    g_assert_nonnull(webkit_download_get_destination(download.get()));
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1);

    return download;
}

static void testDownloadLocalFile(DownloadTest* test, gconstpointer)
{
    static const char* filename = "test.pdf";
    GRefPtr<WebKitDownload> download = downloadLocalFileSuccessfully(test, filename);
    test->checkDestinationAndDeleteFile(download.get(), filename);
}

static void createFileAtDestination(const char* filename)
{
    GUniquePtr<char> path(g_build_filename(Test::dataDirectory(), filename, nullptr));
    GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.get()));
    GUniqueOutPtr<GError> error;
    g_file_create(file.get(), G_FILE_CREATE_NONE, nullptr, &error.outPtr());
    g_assert_no_error(error.get());
    g_assert_true(g_file_query_exists(file.get(), nullptr));
}

static void testDownloadOverwriteDestinationAllowed(DownloadTest* test, gconstpointer)
{
    static const char* filename = "test.pdf";
    createFileAtDestination(filename);

    test->m_allowOverwrite = true;
    GRefPtr<WebKitDownload> download = downloadLocalFileSuccessfully(test, filename);
    test->checkDestinationAndDeleteFile(download.get(), filename);
}

class DownloadErrorTest: public DownloadTest {
public:
    MAKE_GLIB_TEST_FIXTURE(DownloadErrorTest);

    enum ExpectedError {
        NetworkError,
        DownloadCancelled,
        InvalidDestination,
        DestinationExists
    };

    DownloadErrorTest()
        : m_expectedError(NetworkError)
    {
    }

    void receivedResponse(WebKitDownload* download)
    {
        DownloadTest::receivedResponse(download);
    }

    void createdDestination(WebKitDownload* download)
    {
        if (m_expectedError == DownloadCancelled)
            webkit_download_cancel(download);
        else
            g_assert_not_reached();
    }

    void failed(WebKitDownload* download, GError* error)
    {
        g_assert_error(error, WEBKIT_DOWNLOAD_ERROR, expectedErrorToWebKitDownloadError(m_expectedError));
        DownloadTest::failed(download, error);
    }

    void decideDestination(WebKitDownload* download, const gchar* suggestedFilename)
    {
        if (m_expectedError != InvalidDestination) {
            DownloadTest::decideDestination(download, suggestedFilename);
            return;
        }
        webkit_download_set_destination(download, "/foo/bar");
    }

    static WebKitDownloadError expectedErrorToWebKitDownloadError(ExpectedError expected)
    {
        switch (expected) {
        case NetworkError:
            return WEBKIT_DOWNLOAD_ERROR_NETWORK;
        case DownloadCancelled:
            return WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER;
        case InvalidDestination:
            return WEBKIT_DOWNLOAD_ERROR_DESTINATION;
        case DestinationExists:
            return WEBKIT_DOWNLOAD_ERROR_DESTINATION;
        default:
            g_assert_not_reached();
        }
    }

    ExpectedError m_expectedError;
};

static void testDownloadOverwriteDestinationDisallowed(DownloadErrorTest* test, gconstpointer)
{
    static const char* filename = "test.pdf";
    createFileAtDestination(filename);

    test->m_expectedError = DownloadErrorTest::DestinationExists;
    GUniquePtr<char> sourcePath(g_build_filename(Test::getResourcesDir().data(), filename, nullptr));
    GRefPtr<GFile> source = adoptGRef(g_file_new_for_path(sourcePath.get()));
    GUniquePtr<char> sourceURI(g_file_get_uri(source.get()));
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished(sourceURI.get());
    g_assert_null(webkit_download_get_web_view(download.get()));

    Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
    g_assert_cmpint(events.size(), ==, 4);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::Failed);
    g_assert_cmpint(events[3], ==, DownloadTest::Finished);
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 0);

    test->checkDestinationAndDeleteFile(download.get(), filename);
}

static void testDownloadLocalFileError(DownloadErrorTest* test, gconstpointer)
{
    test->m_expectedError = DownloadErrorTest::NetworkError;
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished("file:///foo/bar");
    g_assert_null(webkit_download_get_web_view(download.get()));

    Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
    g_assert_cmpint(events.size(), ==, 3);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::Failed);
    g_assert_cmpint(events[2], ==, DownloadTest::Finished);
    events.clear();
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);

    test->m_expectedError = DownloadErrorTest::InvalidDestination;
    GUniquePtr<char> path(g_build_filename(Test::getResourcesDir().data(), "test.pdf", nullptr));
    GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(path.get()));
    GUniquePtr<char> uri(g_file_get_uri(file.get()));
    download = test->downloadURIAndWaitUntilFinished(uri.get());
    g_assert_null(webkit_download_get_web_view(download.get()));

    g_assert_cmpint(events.size(), ==, 4);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::Failed);
    g_assert_cmpint(events[3], ==, DownloadTest::Finished);
    events.clear();
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);
    test->checkDestinationAndDeleteFile(download.get(), "bar");

    test->m_expectedError = DownloadErrorTest::DownloadCancelled;
    download = test->downloadURIAndWaitUntilFinished(uri.get());
    g_assert_null(webkit_download_get_web_view(download.get()));

    g_assert_cmpint(events.size(), ==, 4);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::Failed);
    g_assert_cmpint(events[3], ==, DownloadTest::Finished);
    events.clear();
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);
    test->checkDestinationAndDeleteFile(download.get(), "test.pdf");
}

static WebKitTestServer* kServer;
static const char* kServerSuggestedFilename = "webkit-downloaded-file";
static HashMap<CString, CString> s_userAgentMap;

static void addContentDispositionHTTPHeaderToResponse(SoupServerMessage* message)
{
    GUniquePtr<char> contentDisposition(g_strdup_printf("attachment; filename=%s", kServerSuggestedFilename));
    soup_message_headers_append(soup_server_message_get_response_headers(message), "Content-Disposition", contentDisposition.get());
}

static void writeNextChunk(SoupServerMessage* message)
{
    /* We need a big enough chunk for the sniffer to not block the load */
    static const char* chunk = "Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!"
        "Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!";
    soup_message_body_append(soup_server_message_get_response_body(message), SOUP_MEMORY_STATIC, chunk, strlen(chunk));
}

static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer)
{
    if (soup_server_message_get_method(message) != SOUP_METHOD_GET) {
        soup_server_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED, nullptr);
        return;
    }

    auto* responseHeaders = soup_server_message_get_response_headers(message);
    auto* responseBody = soup_server_message_get_response_body(message);
    soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);

    if (g_str_has_prefix(path, "/ua-"))
        s_userAgentMap.add(path, soup_message_headers_get_one(soup_server_message_get_request_headers(message), "User-Agent"));

    if (g_str_equal(path, "/cancel-after-destination")) {
        // Use an infinite message to make sure it's cancelled before it finishes.
        soup_message_headers_set_encoding(responseHeaders, SOUP_ENCODING_CHUNKED);
        addContentDispositionHTTPHeaderToResponse(message);
        g_signal_connect(message, "wrote_headers", G_CALLBACK(writeNextChunk), nullptr);
        g_signal_connect(message, "wrote_chunk", G_CALLBACK(writeNextChunk), nullptr);
        return;
    }

    if (g_str_equal(path, "/ua-test-redirect")) {
        soup_server_message_set_status(message, SOUP_STATUS_MOVED_PERMANENTLY, nullptr);
        soup_message_headers_append(responseHeaders, "Location", "/ua-test");
        return;
    }

    if (g_str_equal(path, "/unknown") || g_str_equal(path, "/ua-test"))
        path = "/test.pdf";
    else if (g_str_equal(path, "/text"))
        path = "/text";

    GUniquePtr<char> filePath(g_build_filename(Test::getResourcesDir().data(), path, nullptr));
    char* contents;
    gsize contentsLength;
    if (!g_file_get_contents(filePath.get(), &contents, &contentsLength, 0)) {
        soup_server_message_set_status(message, SOUP_STATUS_NOT_FOUND, nullptr);
        soup_message_body_complete(responseBody);
        return;
    }

    addContentDispositionHTTPHeaderToResponse(message);
    soup_message_body_append(responseBody, SOUP_MEMORY_TAKE, contents, contentsLength);
    soup_message_body_complete(responseBody);
}

static void testDownloadRemoteFile(DownloadTest* test, gconstpointer)
{
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/test.pdf"));
    g_assert_null(webkit_download_get_web_view(download.get()));

    Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
    g_assert_cmpint(events.size(), ==, 5);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::CreatedDestination);
    g_assert_cmpint(events[3], ==, DownloadTest::ReceivedData);
    g_assert_cmpint(events[4], ==, DownloadTest::Finished);
    events.clear();

    WebKitURIRequest* request = webkit_download_get_request(download.get());
    g_assert_nonnull(request);
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/test.pdf"));

    auto headers = webkit_uri_request_get_http_headers(request);
    g_assert_nonnull(soup_message_headers_get_one(headers, "User-Agent"));

    g_assert_nonnull(webkit_download_get_destination(download.get()));
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1);
    GUniquePtr<char> expectedFilename(g_strdup_printf("%s.pdf", kServerSuggestedFilename));
    test->checkDestinationAndDeleteFile(download.get(), expectedFilename.get());
}

static void testDownloadRemoteFileError(DownloadErrorTest* test, gconstpointer)
{
    test->m_expectedError = DownloadErrorTest::NetworkError;
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/foo"));
    g_assert_null(webkit_download_get_web_view(download.get()));

    Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
    g_assert_cmpint(events.size(), ==, 4);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::Failed);
    g_assert_cmpint(events[3], ==, DownloadTest::Finished);
    events.clear();
    WebKitURIResponse* response = webkit_download_get_response(download.get());
    g_assert_cmpuint(webkit_uri_response_get_status_code(response), ==, 404);
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);

    test->m_expectedError = DownloadErrorTest::InvalidDestination;
    download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/test.pdf"));
    g_assert_null(webkit_download_get_web_view(download.get()));

    g_assert_cmpint(events.size(), ==, 4);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::Failed);
    g_assert_cmpint(events[3], ==, DownloadTest::Finished);
    events.clear();
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);
    test->checkDestinationAndDeleteFile(download.get(), "bar");

    test->m_expectedError = DownloadErrorTest::DownloadCancelled;
    download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/cancel-after-destination"));
    g_assert_null(webkit_download_get_web_view(download.get()));

    g_assert_cmpint(events.size(), ==, 4);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::Failed);
    g_assert_cmpint(events[3], ==, DownloadTest::Finished);
    events.clear();
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), <, 1);
    // Check the intermediate file is deleted when the download is cancelled.
    GUniquePtr<char> intermediateFilePath(g_strdup_printf("%s.wkdownload", webkit_download_get_destination(download.get())));
    GRefPtr<GFile> intermediateFile = adoptGRef(g_file_new_for_path(intermediateFilePath.get()));
    g_assert_false(g_file_query_exists(intermediateFile.get(), nullptr));
}

class WebViewDownloadTest: public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(WebViewDownloadTest);

    static void downloadStartedCallback(WebViewDownloadTest* test, WebKitDownload* download)
    {
        test->m_download = download;
        test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download));
        g_signal_connect(download, "decide-destination", G_CALLBACK(downloadDecideDestinationCallback), test);
        g_signal_connect(download, "finished", G_CALLBACK(downloadFinishedCallback), test);
        test->quitMainLoop();
    }

    WebViewDownloadTest()
    {
#if ENABLE(2022_GLIB_API)
        g_signal_connect_swapped(webkit_web_view_get_network_session(m_webView.get()), "download-started", G_CALLBACK(downloadStartedCallback), this);
#else
        g_signal_connect_swapped(webkit_web_view_get_context(m_webView.get()), "download-started", G_CALLBACK(downloadStartedCallback), this);
#endif
    }

    ~WebViewDownloadTest()
    {
#if ENABLE(2022_GLIB_API)
        g_signal_handlers_disconnect_matched(webkit_web_view_get_network_session(m_webView.get()), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
#else
        g_signal_handlers_disconnect_matched(webkit_web_view_get_context(m_webView.get()), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
#endif
    }

    void waitUntilDownloadStarted()
    {
        m_download = nullptr;
        g_main_loop_run(m_mainLoop);
        g_assert_nonnull(m_download.get());
    }

    virtual void finishDecideDestination()
    {
        GUniquePtr<char> destination(g_build_filename(Test::dataDirectory(), m_suggestedFilename.data(), nullptr));
        webkit_download_set_destination(m_download.get(), destination.get());
    }

    static gboolean downloadDecideDestinationCallback(WebKitDownload* download, const gchar* suggestedFilename, WebViewDownloadTest* test)
    {
        if (test->m_shouldDelayDecideDestination)
            g_usleep(0.2 * G_USEC_PER_SEC);

        test->m_suggestedFilename = suggestedFilename;
        if (test->m_shouldAsynchronouslyDecideDestination) {
            g_idle_add(reinterpret_cast<GSourceFunc>(+[](WebViewDownloadTest* test) {
                test->finishDecideDestination();
                return G_SOURCE_REMOVE;
            }), test);
        } else
            test->finishDecideDestination();
        return TRUE;
    }

    static void downloadFinishedCallback(WebKitDownload* download, WebViewDownloadTest* test)
    {
        test->quitMainLoop();
    }

    void waitUntilDownloadFinished()
    {
        g_main_loop_run(m_mainLoop);
    }

#if PLATFORM(GTK)
#if ENABLE(2022_GLIB_API)
    static gboolean contextMenuCallback(WebKitWebView* webView, WebKitContextMenu* contextMenu, WebKitHitTestResult* hitTestResult, WebViewDownloadTest* test)
#else
    static gboolean contextMenuCallback(WebKitWebView* webView, WebKitContextMenu* contextMenu, GdkEvent*, WebKitHitTestResult* hitTestResult, WebViewDownloadTest* test)
#endif
    {
        g_assert_true(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult));
        GList* items = webkit_context_menu_get_items(contextMenu);
        for (GList* l = items; l; l = g_list_next(l)) {
            g_assert_true(WEBKIT_IS_CONTEXT_MENU_ITEM(l->data));
            auto* item = WEBKIT_CONTEXT_MENU_ITEM(l->data);
            if (webkit_context_menu_item_get_stock_action(item) == WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_LINK_TO_DISK) {
                test->m_contextMenuDownloadItem = item;
                break;
            }
        }
        test->quitMainLoop();
        return FALSE;
    }

    WebKitContextMenuItem* showContextMenuAndGetDownloadItem(int x, int y)
    {
        m_contextMenuDownloadItem = nullptr;
        auto id = g_signal_connect(m_webView.get(), "context-menu", G_CALLBACK(contextMenuCallback), this);
        RunLoop::mainSingleton().dispatch([this, x, y] {
            clickMouseButton(x, y, WebViewTest::MouseButton::Secondary);
        });
        g_main_loop_run(m_mainLoop);
        g_signal_handler_disconnect(m_webView.get(), id);
        return m_contextMenuDownloadItem.get();
    }
#endif

    GRefPtr<WebKitDownload> m_download;
    CString m_suggestedFilename;
    bool m_shouldDelayDecideDestination { false };
    bool m_shouldAsynchronouslyDecideDestination { false };
#if PLATFORM(GTK)
    GRefPtr<WebKitContextMenuItem> m_contextMenuDownloadItem;
#endif
};

static void testWebViewDownloadURI(WebViewDownloadTest* test, gconstpointer)
{
    GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_view_download_uri(test->webView(), kServer->getURIForPath("/test.pdf").data()));
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));
    test->waitUntilDownloadStarted();
    g_assert_true(test->webView() == webkit_download_get_web_view(download.get()));

    WebKitURIRequest* request = webkit_download_get_request(download.get());
    g_assert_nonnull(request);
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/test.pdf"));

    auto headers = webkit_uri_request_get_http_headers(request);
    g_assert_nonnull(soup_message_headers_get_one(headers, "User-Agent"));
    test->waitUntilDownloadFinished();

    GRefPtr<GFile> downloadFile = adoptGRef(g_file_new_for_path(webkit_download_get_destination(download.get())));
    GRefPtr<GFileInfo> downloadFileInfo = adoptGRef(g_file_query_info(downloadFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), nullptr, nullptr));
    g_assert_cmpint(g_file_info_get_size(downloadFileInfo.get()), >, 0);
    g_file_delete(downloadFile.get(), nullptr, nullptr);
}

static void testDownloadAsyncDecideDestination(WebViewDownloadTest* test, gconstpointer)
{
    test->m_shouldAsynchronouslyDecideDestination = true;
    testWebViewDownloadURI(test, nullptr);
}

class AsyncCancellationTest: public WebViewDownloadTest {
public:
    MAKE_GLIB_TEST_FIXTURE(AsyncCancellationTest);

    void finishDecideDestination() override
    {
        // Do not chain up because we want to test what happens when the destination is not set.
        // The webkit_download_cancel() alone should finish the async decide-destination decision.
        webkit_download_cancel(m_download.get());
    }

    static void downloadFailedCallback(WebKitDownload* download, GError *error, AsyncCancellationTest* test)
    {
        g_assert_error(error, WEBKIT_DOWNLOAD_ERROR, WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER);
        test->quitMainLoop();
    }

    void waitUntilDownloadFailed()
    {
        g_signal_connect(m_download.get(), "failed", G_CALLBACK(downloadFailedCallback), this);
        g_main_loop_run(m_mainLoop);
    }
};

static void testDownloadAsyncDecideDestinationCancel(AsyncCancellationTest* test, gconstpointer)
{
    test->m_shouldAsynchronouslyDecideDestination = true;

    GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_view_download_uri(test->webView(), kServer->getURIForPath("/test.pdf").data()));
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));
    test->waitUntilDownloadStarted();
    test->waitUntilDownloadFailed();

    g_assert_null(webkit_download_get_destination(download.get()));
}

class PolicyResponseDownloadTest: public WebViewDownloadTest {
public:
    MAKE_GLIB_TEST_FIXTURE(PolicyResponseDownloadTest);

    static gboolean decidePolicyCallback(WebKitWebView* webView, WebKitPolicyDecision* decision, WebKitPolicyDecisionType type, PolicyResponseDownloadTest* test)
    {
        if (type != WEBKIT_POLICY_DECISION_TYPE_RESPONSE)
            return FALSE;

        webkit_policy_decision_download(decision);
        return TRUE;
    }

    PolicyResponseDownloadTest()
    {
        g_signal_connect(m_webView.get(), "decide-policy", G_CALLBACK(decidePolicyCallback), this);
    }

    ~PolicyResponseDownloadTest()
    {
        g_signal_handlers_disconnect_matched(m_webView.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
    }

    void cancelDownloadAndWaitUntilFinished()
    {
        webkit_download_cancel(m_download.get());
        waitUntilDownloadFinished();
        m_download = nullptr;
    }
};

static void testPolicyResponseDownload(PolicyResponseDownloadTest* test, gconstpointer)
{
    CString requestURI = kServer->getURIForPath("/test.pdf").data();
    // Delay the DecideDestination to ensure that the load is aborted before the network task has became a download.
    // See https://bugs.webkit.org/show_bug.cgi?id=164220.
    test->m_shouldDelayDecideDestination = true;
    test->loadURI(requestURI.data());
    test->waitUntilDownloadStarted();

    WebKitURIRequest* request = webkit_download_get_request(test->m_download.get());
    g_assert_nonnull(request);
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, requestURI);

    g_assert_true(test->webView() == webkit_download_get_web_view(test->m_download.get()));

    auto headers = webkit_uri_request_get_http_headers(request);
    g_assert_nonnull(soup_message_headers_get_one(headers, "User-Agent"));
    test->waitUntilDownloadFinished();

    GRefPtr<GFile> downloadFile = adoptGRef(g_file_new_for_path(webkit_download_get_destination(test->m_download.get())));
    GRefPtr<GFileInfo> downloadFileInfo = adoptGRef(g_file_query_info(downloadFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), nullptr, nullptr));
    g_assert_cmpint(g_file_info_get_size(downloadFileInfo.get()), >, 0);
    g_file_delete(downloadFile.get(), nullptr, nullptr);
}

static void testPolicyResponseDownloadCancel(PolicyResponseDownloadTest* test, gconstpointer)
{
    CString requestURI = kServer->getURIForPath("/test.pdf").data();
    test->loadURI(requestURI.data());
    test->waitUntilDownloadStarted();

    WebKitURIRequest* request = webkit_download_get_request(test->m_download.get());
    g_assert_nonnull(request);
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, requestURI);

    g_assert_true(test->webView() == webkit_download_get_web_view(test->m_download.get()));

    auto headers = webkit_uri_request_get_http_headers(request);
    g_assert_nonnull(soup_message_headers_get_one(headers, "User-Agent"));
    test->cancelDownloadAndWaitUntilFinished();
}

static void testDownloadMIMEType(DownloadTest* test, gconstpointer)
{
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/unknown"));
    g_assert_null(webkit_download_get_web_view(download.get()));

    Vector<DownloadTest::DownloadEvent>& events = test->m_downloadEvents;
    g_assert_cmpint(events.size(), ==, 5);
    g_assert_cmpint(events[0], ==, DownloadTest::Started);
    g_assert_cmpint(events[1], ==, DownloadTest::ReceivedResponse);
    g_assert_cmpint(events[2], ==, DownloadTest::CreatedDestination);
    g_assert_cmpint(events[3], ==, DownloadTest::ReceivedData);
    g_assert_cmpint(events[4], ==, DownloadTest::Finished);
    events.clear();

    WebKitURIRequest* request = webkit_download_get_request(download.get());
    g_assert_true(WEBKIT_IS_URI_REQUEST(request));
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/unknown"));

    auto headers = webkit_uri_request_get_http_headers(request);
    g_assert_nonnull(soup_message_headers_get_one(headers, "User-Agent"));

    WebKitURIResponse* response = webkit_download_get_response(download.get());
    g_assert_true(WEBKIT_IS_URI_RESPONSE(response));
    g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "application/pdf");

    g_assert_nonnull(webkit_download_get_destination(download.get()));
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1);
    GUniquePtr<char> expectedFilename(g_strdup_printf("%s.pdf", kServerSuggestedFilename));
    test->checkDestinationAndDeleteFile(download.get(), expectedFilename.get());
}

static void testDownloadTextPlainMIMEType(DownloadTest* test, gconstpointer)
{
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/text"));
    g_assert_null(webkit_download_get_web_view(download.get()));

    WebKitURIRequest* request = webkit_download_get_request(download.get());
    g_assert_true(WEBKIT_IS_URI_REQUEST(request));
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/text"));

    WebKitURIResponse* response = webkit_download_get_response(download.get());
    g_assert_true(WEBKIT_IS_URI_RESPONSE(response));
    g_assert_cmpstr(webkit_uri_response_get_mime_type(response), ==, "text/plain");
    g_assert_nonnull(webkit_download_get_destination(download.get()));
    g_assert_cmpfloat(webkit_download_get_estimated_progress(download.get()), ==, 1);
    test->checkDestinationAndDeleteFile(download.get(), kServerSuggestedFilename);
}

static void testDownloadUserAgent(DownloadTest* test, gconstpointer)
{
    s_userAgentMap.clear();
    GRefPtr<WebKitDownload> download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/ua-test"));
    g_assert_null(webkit_download_get_web_view(download.get()));
    WebKitURIRequest* request = webkit_download_get_request(download.get());
    g_assert_true(WEBKIT_IS_URI_REQUEST(request));
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/ua-test"));

    const char* userAgent = soup_message_headers_get_one(webkit_uri_request_get_http_headers(request), "User-Agent");
    g_assert_nonnull(userAgent);
    g_assert_cmpuint(s_userAgentMap.size(), ==, 1);
    g_assert_true(s_userAgentMap.contains("/ua-test"));
    ASSERT_CMP_CSTRING(userAgent, ==, s_userAgentMap.get("/ua-test"));
    s_userAgentMap.clear();

    GUniquePtr<char> expectedFilename(g_strdup_printf("%s.pdf", kServerSuggestedFilename));
    test->checkDestinationAndDeleteFile(download.get(), expectedFilename.get());

    download = test->downloadURIAndWaitUntilFinished(kServer->getURIForPath("/ua-test-redirect"));
    g_assert_null(webkit_download_get_web_view(download.get()));
    request = webkit_download_get_request(download.get());
    g_assert_true(WEBKIT_IS_URI_REQUEST(request));
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/ua-test-redirect"));

    userAgent = soup_message_headers_get_one(webkit_uri_request_get_http_headers(request), "User-Agent");
    g_assert_nonnull(userAgent);
    g_assert_cmpuint(s_userAgentMap.size(), ==, 2);
    g_assert_true(s_userAgentMap.contains("/ua-test-redirect"));
    ASSERT_CMP_CSTRING(userAgent, ==, s_userAgentMap.get("/ua-test-redirect"));
    g_assert_true(s_userAgentMap.contains("/ua-test"));
    ASSERT_CMP_CSTRING(userAgent, ==, s_userAgentMap.get("/ua-test"));
    s_userAgentMap.clear();

    test->checkDestinationAndDeleteFile(download.get(), expectedFilename.get());
}

static void testDownloadEphemeralContext(Test* test, gconstpointer)
{
#if ENABLE(2022_GLIB_API)
    GRefPtr<WebKitNetworkSession> networkSession = adoptGRef(webkit_network_session_new_ephemeral());
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(networkSession.get()));
#else
    GRefPtr<WebKitWebsiteDataManager> manager = adoptGRef(webkit_website_data_manager_new_ephemeral());
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(manager.get()));
    GRefPtr<WebKitWebContext> context = adoptGRef(webkit_web_context_new_with_website_data_manager(manager.get()));
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(context.get()));
    g_assert_true(webkit_web_context_is_ephemeral(context.get()));
#endif

    GRefPtr<GMainLoop> mainLoop = adoptGRef(g_main_loop_new(nullptr, TRUE));
#if ENABLE(2022_GLIB_API)
    GRefPtr<WebKitDownload> download = adoptGRef(webkit_network_session_download_uri(networkSession.get(), kServer->getURIForPath("/test.pdf").data()));
#else
    GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_context_download_uri(context.get(), kServer->getURIForPath("/test.pdf").data()));
#endif
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));
    g_signal_connect(download.get(), "decide-destination", G_CALLBACK(+[](WebKitDownload* download, const gchar* suggestedFilename, gpointer) {
        GUniquePtr<char> destination(g_build_filename(Test::dataDirectory(), suggestedFilename, nullptr));
        webkit_download_set_destination(download, destination.get());
        return TRUE;
    }), nullptr);
    g_signal_connect(download.get(), "finished", G_CALLBACK(+[](WebKitDownload*, GMainLoop* loop) {
        g_main_loop_quit(loop);
    }), mainLoop.get());

    g_main_loop_run(mainLoop.get());

    GRefPtr<GFile> destFile = adoptGRef(g_file_new_for_path(webkit_download_get_destination(download.get())));
    g_file_delete(destFile.get(), nullptr, nullptr);
}

#if !ENABLE(2022_GLIB_API)
static void testDownloadDestinationURI(Test* test, gconstpointer)
{
    GRefPtr<GMainLoop> mainLoop = adoptGRef(g_main_loop_new(nullptr, TRUE));
    GRefPtr<WebKitDownload> download = adoptGRef(webkit_web_context_download_uri(test->m_webContext.get(), kServer->getURIForPath("/test.pdf").data()));
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));
    g_signal_connect(download.get(), "decide-destination", G_CALLBACK(+[](WebKitDownload* download, const gchar* suggestedFilename, gpointer) {
        GUniquePtr<char> destination(g_build_filename(Test::dataDirectory(), suggestedFilename, nullptr));
        GUniquePtr<char> destinationURI(g_filename_to_uri(destination.get(), nullptr, nullptr));
        webkit_download_set_destination(download, destinationURI.get());
        return TRUE;
    }), nullptr);
    g_signal_connect(download.get(), "finished", G_CALLBACK(+[](WebKitDownload*, GMainLoop* loop) {
        g_main_loop_quit(loop);
    }), mainLoop.get());

    g_main_loop_run(mainLoop.get());

    // If we set a URI, we get a URI.
    const char* destinationURI = webkit_download_get_destination(download.get());
    g_assert_true(g_str_has_prefix(destinationURI, "file://"));

    GRefPtr<GFile> destFile = adoptGRef(g_file_new_for_uri(destinationURI));
    g_assert_true(g_file_query_exists(destFile.get(), nullptr));
    g_file_delete(destFile.get(), nullptr, nullptr);

    download = adoptGRef(webkit_web_context_download_uri(test->m_webContext.get(), kServer->getURIForPath("/test.pdf").data()));
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(download.get()));
    g_signal_connect(download.get(), "notify::destination", G_CALLBACK(+[](WebKitDownload* download, GParamSpec*, gpointer) {
        webkit_download_cancel(download);
    }), nullptr);
    g_signal_connect(download.get(), "finished", G_CALLBACK(+[](WebKitDownload*, GMainLoop* loop) {
        g_main_loop_quit(loop);
    }), mainLoop.get());

    g_main_loop_run(mainLoop.get());

    // If we don't call set_destination, we still get a URI.
    destinationURI = webkit_download_get_destination(download.get());
    g_assert_true(g_str_has_prefix(destinationURI, "file://"));

    // Download was cancelled, destination was not created.
    destFile = adoptGRef(g_file_new_for_uri(destinationURI));
    g_assert_false(g_file_query_exists(destFile.get(), nullptr));
}
#endif

#if PLATFORM(GTK)
static void testContextMenuDownloadActions(WebViewDownloadTest* test, gconstpointer)
{
    test->showInWindow();

    static const char* linkHTMLFormat = "<html><body><a style='position:absolute; left:1; top:1' href='%s'>Download Me</a></body></html>";
    GUniquePtr<char> linkHTML(g_strdup_printf(linkHTMLFormat, kServer->getURIForPath("/test.pdf").data()));
    test->loadHtml(linkHTML.get(), kServer->getURIForPath("/").data());
    test->waitUntilLoadFinished();

    auto* item = test->showContextMenuAndGetDownloadItem(1, 1);
    g_assert(WEBKIT_IS_CONTEXT_MENU_ITEM(item));
    g_action_activate(webkit_context_menu_item_get_gaction(item), nullptr);
    test->waitUntilDownloadStarted();

    g_assert_true(test->webView() == webkit_download_get_web_view(test->m_download.get()));

    WebKitURIRequest* request = webkit_download_get_request(test->m_download.get());
    g_assert_true(WEBKIT_IS_URI_REQUEST(request));
    ASSERT_CMP_CSTRING(webkit_uri_request_get_uri(request), ==, kServer->getURIForPath("/test.pdf"));

    auto headers = webkit_uri_request_get_http_headers(request);
    g_assert_nonnull(soup_message_headers_get_one(headers, "User-Agent"));

    test->waitUntilDownloadFinished();

    GRefPtr<GFile> downloadFile = adoptGRef(g_file_new_for_path(webkit_download_get_destination(test->m_download.get())));
    GUniqueOutPtr<GError> error;
    GRefPtr<GFileInfo> downloadFileInfo = adoptGRef(g_file_query_info(downloadFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), nullptr, &error.outPtr()));
    g_assert_no_error(error.get());
    g_assert_cmpint(g_file_info_get_size(downloadFileInfo.get()), >, 0);
    g_file_delete(downloadFile.get(), nullptr, nullptr);
}
#endif // PLATFORM(GTK)

#if PLATFORM(GTK)
static void testBlobDownload(WebViewDownloadTest* test, gconstpointer)
{
    test->showInWindow();

    static const char* linkBlobHTML =
        "<html><body>"
        "<a id='downloadLink' style='position:absolute; left:1; top:1' download='foo.pdf'>Download Me</a>"
        "<script>"
        "  blob = new Blob(['Hello world'], {type: 'text/plain'});"
        "  document.getElementById('downloadLink').href = window.URL.createObjectURL(blob);"
        "</script>"
        "</body></html>";
    test->loadHtml(linkBlobHTML, kServer->getURIForPath("/").data());
    test->waitUntilLoadFinished();

    g_idle_add([](gpointer userData) -> gboolean {
        auto* test = static_cast<WebViewDownloadTest*>(userData);
        test->clickMouseButton(1, 1);
        return FALSE;
    }, test);
    test->waitUntilDownloadStarted();

    g_assert_true(test->webView() == webkit_download_get_web_view(test->m_download.get()));
    test->waitUntilDownloadFinished();

    GRefPtr<GFile> downloadFile = adoptGRef(g_file_new_for_path(webkit_download_get_destination(test->m_download.get())));
    GRefPtr<GFileInfo> downloadFileInfo = adoptGRef(g_file_query_info(downloadFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE, static_cast<GFileQueryInfoFlags>(0), nullptr, nullptr));
    GUniquePtr<char> downloadPath(g_file_get_path(downloadFile.get()));
    GUniqueOutPtr<char> downloadContents;
    gsize downloadContentsLength;
    g_assert_true(g_file_get_contents(downloadPath.get(), &downloadContents.outPtr(), &downloadContentsLength, nullptr));
    g_assert_cmpint(g_file_info_get_size(downloadFileInfo.get()), ==, downloadContentsLength);
    g_assert_cmpstr(downloadContents.get(), ==, "Hello world");
    g_file_delete(downloadFile.get(), nullptr, nullptr);
}
#endif // PLATFORM(GTK)

void beforeAll()
{
    kServer = new WebKitTestServer();
    kServer->run(serverCallback);

    DownloadTest::add("Downloads", "local-file", testDownloadLocalFile);
    DownloadTest::add("Downloads", "overwrite-destination-allowed", testDownloadOverwriteDestinationAllowed);
    DownloadErrorTest::add("Downloads", "overwrite-destination-disallowed", testDownloadOverwriteDestinationDisallowed);
    DownloadErrorTest::add("Downloads", "local-file-error", testDownloadLocalFileError);
    DownloadTest::add("Downloads", "remote-file", testDownloadRemoteFile);
    DownloadErrorTest::add("Downloads", "remote-file-error", testDownloadRemoteFileError);
    WebViewDownloadTest::add("WebKitWebView", "download-uri", testWebViewDownloadURI);
    WebViewDownloadTest::add("Downloads", "async-decide-destination", testDownloadAsyncDecideDestination);
    AsyncCancellationTest::add("Downloads", "async-decide-destination-cancel", testDownloadAsyncDecideDestinationCancel);
    PolicyResponseDownloadTest::add("Downloads", "policy-decision-download", testPolicyResponseDownload);
    PolicyResponseDownloadTest::add("Downloads", "policy-decision-download-cancel", testPolicyResponseDownloadCancel);
    DownloadTest::add("Downloads", "mime-type", testDownloadMIMEType);
    DownloadTest::add("Downloads", "text-plain-mime-type", testDownloadTextPlainMIMEType);
    DownloadTest::add("Downloads", "user-agent", testDownloadUserAgent);
    Test::add("Downloads", "ephemeral-context", testDownloadEphemeralContext);
#if !ENABLE(2022_GLIB_API)
    Test::add("Downloads", "destination-uri", testDownloadDestinationURI);
#endif
#if PLATFORM(GTK)
    // FIXME: Implement keyStroke in WPE.
    WebViewDownloadTest::add("Downloads", "contex-menu-download-actions", testContextMenuDownloadActions);
    // FIXME: Implement mouse click in WPE.
    WebViewDownloadTest::add("Downloads", "blob-download", testBlobDownload);
#endif
}

void afterAll()
{
    delete kServer;
}
