/*
 * Copyright (C) 2022-2024 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "config.h"

#if ENABLE(WK_WEB_EXTENSIONS)

#import "HTTPServer.h"
#import "WebExtensionUtilities.h"

#import <WebKit/_WKWebExtensionWebNavigationURLFilter.h>
#import <wtf/text/MakeString.h>

namespace TestWebKitAPI {

static auto *webNavigationManifest = @{ @"manifest_version": @3, @"permissions": @[ @"webNavigation" ], @"background": @{ @"scripts": @[ @"background.js" ], @"type": @"module", @"persistent": @NO } };

TEST(WKWebExtensionAPIWebNavigation, EventListenerRegistration)
{
    auto *backgroundScript = Util::constructScript(@[
        @"function listener() { browser.test.notifyFail('This listener should not have been called') }",
        @"browser.test.assertFalse(browser.webNavigation.onBeforeNavigate.hasListener(listener), 'Should not have listener')",

        @"browser.webNavigation.onBeforeNavigate.addListener(listener)",
        @"browser.test.assertTrue(browser.webNavigation.onBeforeNavigate.hasListener(listener), 'Should have listener')",

        @"browser.webNavigation.onBeforeNavigate.removeListener(listener)",
        @"browser.test.assertFalse(browser.webNavigation.onBeforeNavigate.hasListener(listener), 'Should not have listener')",

        @"browser.test.notifyPass()"
    ]);

    Util::loadAndRunExtension(webNavigationManifest, @{ @"background.js": backgroundScript });
}

TEST(WKWebExtensionAPIWebNavigation, BeforeNavigateEvent)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"browser.webNavigation.onBeforeNavigate.addListener((details) => {",
        @"    browser.test.assertEq(details?.frameId, 0, 'details.frameId should be')",
        @"    browser.test.assertEq(details?.parentFrameId, -1, 'details.parentFrameId should be')",

        @"    browser.test.assertEq(typeof details?.url, 'string', 'details.url should be')",
        @"    browser.test.assertTrue(details?.url?.includes('localhost'), 'details.url should include localhost')",

        @"    browser.test.assertEq(typeof details?.tabId, 'number', 'details.tabId should be')",
        @"    browser.test.assertEq(typeof details?.timeStamp, 'number', 'details.timeStamp should be')",

        @"    browser.test.assertEq(details?.documentId, undefined, 'details.documentId should be')",

        @"    browser.test.notifyPass()",
        @"})",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, CommittedEvent)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"browser.webNavigation.onCommitted.addListener((details) => {",
        @"    browser.test.assertEq(details?.frameId, 0, 'details.frameId should be')",
        @"    browser.test.assertEq(details?.parentFrameId, -1, 'details.parentFrameId should be')",

        @"    browser.test.assertEq(typeof details?.url, 'string', 'details.url should be')",
        @"    browser.test.assertTrue(details?.url?.includes('localhost'), 'details.url should include localhost')",

        @"    browser.test.assertEq(typeof details?.tabId, 'number', 'details.tabId should be')",
        @"    browser.test.assertEq(typeof details?.timeStamp, 'number', 'details.timeStamp should be')",

        @"    browser.test.assertEq(typeof details?.documentId, 'string', 'details.documentId should be')",
        @"    browser.test.assertEq(details?.documentId?.length, 36, 'details.documentId.length should be')",

        @"    browser.test.notifyPass()",
        @"})",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, DOMContentLoadedEvent)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"browser.webNavigation.onDOMContentLoaded.addListener((details) => {",
        @"    browser.test.assertEq(details?.frameId, 0, 'details.frameId should be')",
        @"    browser.test.assertEq(details?.parentFrameId, -1, 'details.parentFrameId should be')",

        @"    browser.test.assertEq(typeof details?.url, 'string', 'details.url should be')",
        @"    browser.test.assertTrue(details?.url?.includes('localhost'), 'details.url should include localhost')",

        @"    browser.test.assertEq(typeof details?.tabId, 'number', 'details.tabId should be')",
        @"    browser.test.assertEq(typeof details?.timeStamp, 'number', 'details.timeStamp should be')",

        @"    browser.test.assertEq(typeof details?.documentId, 'string', 'details.documentId should be')",
        @"    browser.test.assertEq(details?.documentId?.length, 36, 'details.documentId.length should be')",

        @"    browser.test.notifyPass()",
        @"})",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, CompletedEvent)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"browser.webNavigation.onCompleted.addListener((details) => {",
        @"    browser.test.assertEq(details?.frameId, 0, 'details.frameId should be')",
        @"    browser.test.assertEq(details?.parentFrameId, -1, 'details.parentFrameId should be')",

        @"    browser.test.assertEq(typeof details?.url, 'string', 'details.url should be')",
        @"    browser.test.assertTrue(details?.url?.includes('localhost'), 'details.url should include localhost')",

        @"    browser.test.assertEq(typeof details?.tabId, 'number', 'details.tabId should be')",
        @"    browser.test.assertEq(typeof details?.timeStamp, 'number', 'details.timeStamp should be')",

        @"    browser.test.assertEq(typeof details?.documentId, 'string', 'details.documentId should be')",
        @"    browser.test.assertEq(details?.documentId?.length, 36, 'details.documentId.length should be')",

        @"    browser.test.notifyPass()",
        @"})",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, AllowedFilter)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function passListener() { browser.test.notifyPass() }",

        @"browser.webNavigation.onCommitted.addListener(passListener, { 'url': [ {'hostContains': 'localhost'} ] })",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, DeniedFilter)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function passListener() { browser.test.notifyPass() }",
        @"function failListener() { browser.test.notifyFail('This listener should not have been called') }",

        @"browser.webNavigation.onCommitted.addListener(failListener, { 'url': [ {'hostContains': 'example'} ] })",
        @"browser.webNavigation.onCommitted.addListener(passListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, AllEventsFired)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"let beforeNavigateEventFired = false",
        @"let onCommittedEventFired = false",
        @"let onDOMContentLoadedEventFired = false",

        @"function beforeNavigateHandler() { beforeNavigateEventFired = true }",
        @"function onCommittedHandler() { onCommittedEventFired = true }",
        @"function onDOMContentLoadedHandler() { onDOMContentLoadedEventFired = true }",

        @"function onCompletedHandler() {",
        @"  browser.test.assertTrue(beforeNavigateEventFired)",
        @"  browser.test.assertTrue(onCommittedEventFired)",
        @"  browser.test.assertTrue(onDOMContentLoadedEventFired)",

        @"  browser.test.notifyPass()",
        @"}",

        @"browser.webNavigation.onBeforeNavigate.addListener(beforeNavigateHandler)",
        @"browser.webNavigation.onCommitted.addListener(onCommittedHandler)",
        @"browser.webNavigation.onDOMContentLoaded.addListener(onDOMContentLoadedHandler)",
        @"browser.webNavigation.onCompleted.addListener(onCompletedHandler)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, DocumentIdAcrossEvents)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"let documentId = null",

        @"browser.webNavigation.onBeforeNavigate.addListener((details) => {",
        @"  browser.test.assertEq(details?.documentId, undefined, 'details.documentId should be')",
        @"})",

        @"browser.webNavigation.onCommitted.addListener((details) => {",
        @"  browser.test.assertEq(documentId, null, 'documentId should be')",

        @"  browser.test.assertEq(typeof details?.documentId, 'string', 'details.documentId should be')",
        @"  browser.test.assertEq(details?.documentId?.length, 36, 'details.documentId.length should be')",

        @"  documentId = details?.documentId",
        @"})",

        @"browser.webNavigation.onDOMContentLoaded.addListener((details) => {",
        @"  browser.test.assertEq(documentId, details?.documentId, 'details.documentId should stay consistent in onDOMContentLoaded')",
        @"})",

        @"browser.webNavigation.onCompleted.addListener((details) => {",
        @"  browser.test.assertEq(documentId, details?.documentId, 'details.documentId should stay consistent in onCompleted')",

        @"  browser.test.notifyPass()",
        @"})",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, RemoveListenerDuringEvent)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, ""_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function navigationListener() {",
        @"  browser.webNavigation.onCommitted.removeListener(navigationListener)",
        @"  browser.test.assertFalse(browser.webNavigation.onCommitted.hasListener(navigationListener), 'Listener should be removed')",
        @"}",

        @"browser.webNavigation.onCommitted.addListener(navigationListener)",
        @"browser.webNavigation.onCommitted.addListener(() => browser.test.notifyPass())",

        @"browser.test.assertTrue(browser.webNavigation.onCommitted.hasListener(navigationListener), 'Listener should be registered')",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:urlRequest.URL];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, ErrorOccurredEventDuringProvisionalLoad)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, "<iframe src='/frame.html'></iframe>"_s } },
        { "/frame.html"_s, { HTTPResponse::Behavior::TerminateConnectionAfterReceivingRequest } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function errorListener(details) {",
        @"  browser.test.assertTrue(details?.frameId != 0)",

        @"  browser.test.assertTrue(details?.url.includes('localhost'))",
        @"  browser.test.assertTrue(details?.url.includes('frame'))",

        @"  browser.test.notifyPass()",
        @"}",

        @"browser.webNavigation.onErrorOccurred.addListener(errorListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    NSURL *requestURL = urlRequest.URL;
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:requestURL];
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:[requestURL URLByAppendingPathComponent:@"frame.html"]];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

template<size_t length>
String longString(Latin1Character c)
{
    Vector<Latin1Character> vector(length, c);
    return vector.span();
}

TEST(WKWebExtensionAPIWebNavigation, ErrorOccurredEventDuringLoad)
{
    TestWebKitAPI::HTTPServer server(TestWebKitAPI::HTTPServer::UseCoroutines::Yes, [&](auto connection) -> TestWebKitAPI::ConnectionTask {
        while (1) {
            auto request = co_await connection.awaitableReceiveHTTPRequest();
            auto path = TestWebKitAPI::HTTPServer::parsePath(request);
            if (path == "/"_s) {
                constexpr auto body = "<iframe src='/frame.html'></iframe>"_s;
                auto reply = makeString(
                    "HTTP/1.1 200 OK\r\n"
                    "Content-Type: text/html\r\n"
                    "Content-Length: "_s, body.length(), "\r\n"
                    "Connection: close\r\n"
                    "\r\n"_s, body
                );
                co_await connection.awaitableSend(WTF::move(reply));
                continue;
            }
            if (path == "/frame.html"_s) {
                auto response = makeString(
                    "HTTP/1.1 200 OK\r\n"_s,
                    "Content-Length: 1000000\r\n"
                    "\r\n"_s, longString<500000>(' ')
                );

                co_await connection.awaitableSend(WTF::move(response));
                connection.terminate();
                continue;
            }
            EXPECT_FALSE(true);
        }
    });

    auto *backgroundScript = Util::constructScript(@[
        @"async function errorListener(details) {",
        // This should be a subframe
        @"  browser.test.assertTrue(details.frameId != 0)",

        // The URL of the frame that failed loading should include localhost and frame.
        @"  browser.test.assertTrue(details.url.includes('localhost'))",
        @"  browser.test.assertTrue(details.url.includes('frame'))",

        @"  const frame = await browser.webNavigation.getFrame({ tabId: details.tabId, frameId: details.frameId })",
        @"  browser.test.assertEq(frame.parentFrameId, 0)",
        @"  browser.test.assertTrue(frame.errorOccurred)",

        // And since the failure happened after the load had been committed, the frame object has the URL set as well.
        @"  browser.test.assertTrue(frame.url.includes('localhost'))",
        @"  browser.test.assertTrue(frame.url.includes('frame'))",

        @"  browser.test.notifyPass()",
        @"}",

        // The passListener firing will consider the test passed.
        @"browser.webNavigation.onErrorOccurred.addListener(errorListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    NSURL *requestURL = urlRequest.URL;
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:requestURL];
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:[requestURL URLByAppendingPathComponent:@"frame.html"]];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, GetFrameWithMainFrame)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, "<iframe src='/frame.html'></iframe>"_s } },
        { "/frame.html"_s, { { { "Content-Type"_s, "text/html"_s } }, "<body style='background-color: blue'></body>"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function completedListener(details) {",
        @"  if (details?.frameId !== 0)",
        @"    return",

        @"  browser.webNavigation.getFrame({ tabId: details?.tabId, frameId: 0 }, (frame) => {",
        @"    browser.test.assertEq(frame?.parentFrameId, -1)",
        @"    browser.test.assertTrue(frame?.url?.includes('localhost'))",
        @"    browser.test.assertFalse(frame?.url?.includes('frame'))",
        @"    browser.test.assertEq(typeof frame?.documentId, 'string', 'frame.documentId should be')",
        @"    browser.test.assertEq(frame?.documentId?.length, 36, 'frame.documentId.length should be')",

        @"    browser.test.notifyPass()",
        @"  })",
        @"}",

        @"browser.webNavigation.onCompleted.addListener(completedListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    NSURL *requestURL = urlRequest.URL;
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:requestURL];
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:[requestURL URLByAppendingPathComponent:@"frame.html"]];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, GetFrameWithSubframe)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, "<iframe src='/frame.html'></iframe>"_s } },
        { "/frame.html"_s, { { { "Content-Type"_s, "text/html"_s } }, "<body style='background-color: blue'></body>"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function completedListener(details) {",
        @"  if (details?.frameId === 0)",
        @"    return",

        @"  browser.webNavigation.getFrame({ tabId: details?.tabId, frameId: details?.frameId }, (frame) => {",
        @"    browser.test.assertEq(frame.parentFrameId, 0)",
        @"    browser.test.assertTrue(frame.url.includes('localhost'))",
        @"    browser.test.assertTrue(frame.url.includes('frame'))",
        @"    browser.test.assertEq(typeof frame?.documentId, 'string', 'frame.documentId should be')",
        @"    browser.test.assertEq(frame?.documentId?.length, 36, 'frame.documentId.length should be')",

        @"    browser.test.notifyPass()",
        @"  })",
        @"}",

        @"browser.webNavigation.onCompleted.addListener(completedListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    NSURL *requestURL = urlRequest.URL;
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:requestURL];
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:[requestURL URLByAppendingPathComponent:@"frame.html"]];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, GetAllFrames)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, "<iframe src='/frame.html'></iframe>"_s } },
        { "/frame.html"_s, { { { "Content-Type"_s, "text/html"_s } }, "<body style='background-color: blue'></body>"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function completedListener(details) {",
        @"  if (details.frameId !== 0)",
        @"    return",

        @"  browser.webNavigation.getAllFrames({ tabId: details?.tabId }, (frames) => {",
        @"    browser.test.assertEq(frames?.length, 2)",

        @"    for (let frame of frames) {",
        @"      if (frame?.frameId === 0) {",
        @"        browser.test.assertEq(frame?.parentFrameId, -1)",
        @"        browser.test.assertTrue(frame?.url.includes('localhost'))",
        @"        browser.test.assertFalse(frame?.url.includes('frame'))",
        @"      } else {",
        @"        browser.test.assertEq(frame?.parentFrameId, 0)",
        @"        browser.test.assertTrue(frame?.url.includes('localhost'))",
        @"        browser.test.assertTrue(frame?.url.includes('frame'))",
        @"      }",

        @"      browser.test.assertEq(typeof frame?.documentId, 'string', 'frame.documentId should be')",
        @"      browser.test.assertEq(frame?.documentId?.length, 36, 'frame.documentId.length should be')",
        @"    }",

        @"    browser.test.notifyPass()",
        @"  })",
        @"}",

        @"browser.webNavigation.onCompleted.addListener(completedListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    NSURL *requestURL = urlRequest.URL;
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:requestURL];
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:[requestURL URLByAppendingPathComponent:@"frame.html"]];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, ErrorOccurred)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, "<iframe src='/frame.html'></iframe>"_s } },
        { "/frame.html"_s, { HTTPResponse::Behavior::TerminateConnectionAfterReceivingRequest } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"function errorListener(details) {",
        // A subframe should have been the one to have the error.
        @"  browser.test.assertFalse(details.frameId == 0)",
        @"  browser.test.assertEq(details.parentFrameId, 0)",

        // Get more information about the frame to verify the errorOccurred bit was set.
        @"  browser.webNavigation.getFrame({ tabId: details.tabId, frameId: details.frameId }, function(frame) {",
        @"    browser.test.assertEq(frame.parentFrameId, 0)",
        @"    browser.test.assertTrue(frame.errorOccurred)",

        // One thing to note here is that if the provisional load fails, there won't be a URL in the details.
        @"    browser.test.assertEq(frame.url, '')",

        @"    browser.test.notifyPass()",
        @"  })",
        @"}",

        // The passListener firing will consider the test passed.
        @"browser.webNavigation.onErrorOccurred.addListener(errorListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    NSURL *requestURL = urlRequest.URL;
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:requestURL];
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:[requestURL URLByAppendingPathComponent:@"frame.html"]];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, Errors)
{
    TestWebKitAPI::HTTPServer server({
        { "/"_s, { { { "Content-Type"_s, "text/html"_s } }, "<iframe src='/frame.html'></iframe>"_s } },
        { "/frame.html"_s, { { { "Content-Type"_s, "text/html"_s } }, "<body style='background-color: blue'></body>"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::Http);

    auto *backgroundScript = Util::constructScript(@[
        @"async function completedListener(details) {",
        // Only listen for when the main frame loads so we don't call this method more than once.
        @"  if (details.frameId !== 0)",
        @"    return",
        @"  const activeTab = await browser.tabs.query({ active: true })",
        // Make sure invalid tab/frame IDs vend an error message - use arbitrary frame and tabIds.
        @"  await browser.test.assertRejects(browser.webNavigation.getFrame({tabId: (details.tabId + 1), frameId: 0}), /tab not found/i)",
        @"  await browser.test.assertRejects(browser.webNavigation.getFrame({tabId: details.tabId, frameId: 42}), /frame not found/i)",
        @"  browser.test.notifyPass()",
        @"}",

        // The passListener firing will consider the test passed.
        @"browser.webNavigation.onCompleted.addListener(completedListener)",

        @"browser.test.sendMessage('Load Tab')"
    ]);

    auto manager = Util::loadExtension(webNavigationManifest, @{ @"background.js": backgroundScript });

    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forPermission:WKWebExtensionPermissionWebNavigation];

    auto *urlRequest = server.requestWithLocalhost();
    NSURL *requestURL = urlRequest.URL;
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:requestURL];
    [manager.get().context setPermissionStatus:WKWebExtensionContextPermissionStatusGrantedExplicitly forURL:[requestURL URLByAppendingPathComponent:@"frame.html"]];

    [manager runUntilTestMessage:@"Load Tab"];

    [manager.get().defaultTab.webView loadRequest:urlRequest];

    [manager run];
}

TEST(WKWebExtensionAPIWebNavigation, URLFilterTestMatchAllPredicates)
{
    NSString *errorString = nil;
    NSDictionary *filterDictionary = @{
        @"url": @[
            @{
                @"schemes": @[ @"https" ],
                @"hostEquals": @"apple.com",
            }
        ]
    };

    _WKWebExtensionWebNavigationURLFilter *filter = [[_WKWebExtensionWebNavigationURLFilter alloc] initWithDictionary:filterDictionary outErrorMessage:&errorString];
    EXPECT_NULL(errorString);

    EXPECT_TRUE([filter matchesURL:[NSURL URLWithString:@"https://apple.com"]]);
    EXPECT_FALSE([filter matchesURL:[NSURL URLWithString:@"http://apple.com"]]);
    EXPECT_FALSE([filter matchesURL:[NSURL URLWithString:@"https://example.com"]]);

    [filter release];
}


TEST(WKWebExtensionAPIWebNavigation, URLFilterMatchesOnePredicate)
{
    NSString *errorString = nil;
    NSDictionary *filterDictionary = @{
        @"url": @[
            @{ @"hostEquals": @"apple.com" },
            @{ @"hostEquals": @"example.com" },
        ]
    };

    _WKWebExtensionWebNavigationURLFilter *filter = [[_WKWebExtensionWebNavigationURLFilter alloc] initWithDictionary:filterDictionary outErrorMessage:&errorString];
    EXPECT_NULL(errorString);

    EXPECT_TRUE([filter matchesURL:[NSURL URLWithString:@"http://apple.com"]]);
    EXPECT_TRUE([filter matchesURL:[NSURL URLWithString:@"http://example.com"]]);
    EXPECT_FALSE([filter matchesURL:[NSURL URLWithString:@"about:blank"]]);
    EXPECT_FALSE([filter matchesURL:[NSURL URLWithString:@"file:///dev/null"]]);

    [filter release];
}

TEST(WKWebExtensionAPIWebNavigation, EmptyFilterMatchesEverything)
{
    NSString *errorString = nil;
    NSDictionary *filterDictionary = @{
        @"url": @[ ]
    };

    _WKWebExtensionWebNavigationURLFilter *filter = [[_WKWebExtensionWebNavigationURLFilter alloc] initWithDictionary:filterDictionary outErrorMessage:&errorString];
    EXPECT_NULL(errorString);

    EXPECT_TRUE([filter matchesURL:[NSURL URLWithString:@"about:blank"]]);
    EXPECT_TRUE([filter matchesURL:[NSURL URLWithString:@"http://example.com"]]);
    EXPECT_TRUE([filter matchesURL:[NSURL URLWithString:@"file:///dev/null"]]);

    [filter release];
}

TEST(WKWebExtensionAPIWebNavigation, URLKeyTypeChecking)
{
    __auto_type test = ^(NSDictionary *inputDictionary, NSString *expectedError) {
        _WKWebExtensionWebNavigationURLFilter *filter;
        NSString *error = nil;
        filter = [[_WKWebExtensionWebNavigationURLFilter alloc] initWithDictionary:inputDictionary outErrorMessage:&error];
        if (expectedError) {
            EXPECT_NS_EQUAL(error, expectedError);
            EXPECT_NULL(filter);
        } else {
            EXPECT_NULL(error);
            EXPECT_NOT_NULL(filter);
        }

        [filter release];
    };

    test(@{ }, @"The 'filters' value is invalid, because it is missing required keys: 'url'.");
    test(@{ @"a": @"b" }, @"The 'filters' value is invalid, because it is missing required keys: 'url'.");
    test(@{ @"a": @"b", @"url": @[ ] }, nil);
    test(@{ @"url": [NSNull null] }, @"The 'filters' value is invalid, because 'url' is expected to be an array of objects, but null was provided.");
    test(@{ @"url": @[ ] }, nil);
    test(@{ @"url": @[ @"A" ] }, @"The 'filters' value is invalid, because 'url' is expected to be an array of objects, but a string was provided in the array.");
    test(@{ @"url": @[ @[ ] ] }, @"The 'filters' value is invalid, because 'url' is expected to be an array of objects, but an array was provided in the array.");
    test(@{ @"url": @[ @{ } ] }, nil);
}

} // namespace TestWebKitAPI

#endif // ENABLE(WK_WEB_EXTENSIONS)
