/*
 * Copyright (C) 2014-2017 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 PLATFORM(MAC)

#import "PlatformUtilities.h"
#import "TestProtocol.h"
#import <WebKit/WKNavigationActionPrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/_WKProcessPoolConfiguration.h>
#import <wtf/BlockPtr.h>
#import <wtf/RetainPtr.h>

static bool shouldCancelNavigation;
static bool shouldDelayDecision;
static bool createdWebView;
static bool decidedPolicy;
static bool finishedNavigation;
static RetainPtr<WKNavigationAction> action;
static RetainPtr<WKWebView> newWebView;
static BlockPtr<void(WKNavigationActionPolicy)> delayedDecision;

static NSString *firstURL = @"data:text/html,First";
static NSString *secondURL = @"data:text/html,Second";

@interface DecidePolicyForNavigationActionController : NSObject <WKNavigationDelegate, WKUIDelegate>
@end

@implementation DecidePolicyForNavigationActionController

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    if (shouldCancelNavigation) {
        int64_t deferredWaitTime = 100 * NSEC_PER_MSEC;
        dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, deferredWaitTime);
        dispatch_after(when, dispatch_get_main_queue(), ^{
            decisionHandler(WKNavigationActionPolicyCancel);
            decidedPolicy = true;
        });
        return;
    }

    if (shouldDelayDecision) {
        if (delayedDecision)
            delayedDecision(WKNavigationActionPolicyCancel);
        delayedDecision = makeBlockPtr(decisionHandler);
        decidedPolicy = true;
        return;
    }

    decisionHandler(webView == newWebView.get() ? WKNavigationActionPolicyCancel : WKNavigationActionPolicyAllow);

    action = navigationAction;
    decidedPolicy = true;
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    finishedNavigation = true;
}

- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    action = navigationAction;
    newWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration]);

    createdWebView = true;
    return newWebView.get();
}

@end

TEST(WebKit, DecidePolicyForNavigationActionReload)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    decidedPolicy = false;
    [webView reload];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeReload, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [action sourceFrame]);
    EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
    EXPECT_WK_STREQ(firstURL, [[[[action targetFrame] request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action targetFrame] webView]);

    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionReloadFromOrigin)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    decidedPolicy = false;
    [webView reloadFromOrigin];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeReload, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [action sourceFrame]);
    EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
    EXPECT_WK_STREQ(firstURL, [[[[action targetFrame] request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action targetFrame] webView]);

    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionGoBack)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    finishedNavigation = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:secondURL]]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    decidedPolicy = false;
    [webView goBack];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeBackForward, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [action sourceFrame]);
    EXPECT_WK_STREQ(firstURL, [[[action request] URL] absoluteString]);
    EXPECT_WK_STREQ(secondURL, [[[[action targetFrame] request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action targetFrame] webView]);

    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionGoForward)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:firstURL]]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    finishedNavigation = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:secondURL]]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    finishedNavigation = false;
    [webView goBack];
    TestWebKitAPI::Util::run(&finishedNavigation);

    decidedPolicy = false;
    [webView goForward];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeBackForward, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [action sourceFrame]);
    EXPECT_WK_STREQ(secondURL, [[[action request] URL] absoluteString]);
    EXPECT_WK_STREQ(firstURL, [[[[action targetFrame] request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action targetFrame] webView]);

    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionOpenNewWindowAndDeallocSourceWebView)
{
    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);

    @autoreleasepool {
        auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

        auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
        [[window contentView] addSubview:webView.get()];

        [webView setNavigationDelegate:controller.get()];
        [webView setUIDelegate:controller.get()];

        createdWebView = false;
        [webView loadHTMLString:@"<script>window.open('http://webkit.org/destination.html')</script>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
        TestWebKitAPI::Util::run(&createdWebView);
    }

    decidedPolicy = false;
    [newWebView setNavigationDelegate:controller.get()];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [[action sourceFrame] webView]);
    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);

    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionForTargetedHyperlink)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"https://webkit.org/destination2.html\" target=\"B\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    createdWebView = false;
    [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination1.html\", \"B\")" completionHandler:nil];
    TestWebKitAPI::Util::run(&createdWebView);

    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [action targetFrame]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);

    // Wait for newWebView to ask to load its initial document.
    decidedPolicy = false;
    [newWebView setNavigationDelegate:controller.get()];
    TestWebKitAPI::Util::run(&decidedPolicy);

    decidedPolicy = false;
    [newWebView setNavigationDelegate:controller.get()];
    NSPoint clickPoint = NSMakePoint(100, 100);
    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);

    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionForLoadHTMLStringAllow)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    decidedPolicy = false;
    [webView loadHTMLString:@"TEST" baseURL:[NSURL URLWithString:@"about:blank"]];
    TestWebKitAPI::Util::run(&finishedNavigation);
    EXPECT_TRUE(decidedPolicy);
}

TEST(WebKit, DecidePolicyForNavigationActionForLoadHTMLStringDeny)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    shouldCancelNavigation = true;
    finishedNavigation = false;
    decidedPolicy = false;
    [webView loadHTMLString:@"TEST" baseURL:[NSURL URLWithString:@"about:blank"]];
    TestWebKitAPI::Util::sleep(0.5);
    EXPECT_FALSE(finishedNavigation);
    shouldCancelNavigation = false;
}

TEST(WebKit, DecidePolicyForNavigationActionForTargetedWindowOpen)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"javascript:window.open('https://webkit.org/destination2.html', 'B')\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    createdWebView = false;
    [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination1.html\", \"B\")" completionHandler:nil];
    TestWebKitAPI::Util::run(&createdWebView);

    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [action targetFrame]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);

    // Wait for newWebView to ask to load its initial document.
    decidedPolicy = false;
    [newWebView setNavigationDelegate:controller.get()];
    TestWebKitAPI::Util::run(&decidedPolicy);

    decidedPolicy = false;
    [newWebView setNavigationDelegate:controller.get()];
    NSPoint clickPoint = NSMakePoint(100, 100);
    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);

    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionForTargetedFormSubmission)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadHTMLString:@"<form action=\"https://webkit.org/destination1.html\" target=\"B\"><input type=\"submit\" name=\"submit\" value=\"Submit\" style=\"-webkit-appearance: none; height: 100%; width: 100%\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    createdWebView = false;
    [webView evaluateJavaScript:@"window.open(\"https://webkit.org/destination2.html\", \"B\")" completionHandler:nil];
    TestWebKitAPI::Util::run(&createdWebView);

    EXPECT_EQ(WKNavigationTypeOther, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(nil, [action targetFrame]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);

    // Wait for newWebView to ask to load its initial document.
    decidedPolicy = false;
    [newWebView setNavigationDelegate:controller.get()];
    TestWebKitAPI::Util::run(&decidedPolicy);

    decidedPolicy = false;
    NSPoint clickPoint = NSMakePoint(100, 100);
    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] != [action targetFrame]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_EQ(newWebView.get(), [[action targetFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);

    newWebView = nullptr;
    action = nullptr;
}

enum class ShouldEnableProcessSwap { No, Yes };
static void runDecidePolicyForNavigationActionForHyperlinkThatRedirects(ShouldEnableProcessSwap shouldEnableProcessSwap)
{
    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
    processPoolConfiguration.get().processSwapsOnNavigation = shouldEnableProcessSwap == ShouldEnableProcessSwap::Yes ? YES : NO;
    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);

    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [webViewConfiguration setProcessPool:processPool.get()];

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    [TestProtocol registerWithScheme:@"http"];
    finishedNavigation = false;
    [webView loadHTMLString:@"<a style=\"display: block; height: 100%\" href=\"http://redirect/?result\">" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    decidedPolicy = false;
    [newWebView setNavigationDelegate:controller.get()];
    NSPoint clickPoint = NSMakePoint(100, 100);
    [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeLeftMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
    EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
    EXPECT_WK_STREQ("http://redirect/?result", [[[action request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
    EXPECT_FALSE([action _isRedirect]);

    // Wait to decide policy for redirect.
    decidedPolicy = false;
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeLinkActivated, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
    EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
    EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
    EXPECT_TRUE([action _isRedirect]);

    [TestProtocol unregister];
    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionForHyperlinkThatRedirectsWithoutPSON)
{
    runDecidePolicyForNavigationActionForHyperlinkThatRedirects(ShouldEnableProcessSwap::No);
}

TEST(WebKit, DecidePolicyForNavigationActionForHyperlinkThatRedirectsWithPSON)
{
    runDecidePolicyForNavigationActionForHyperlinkThatRedirects(ShouldEnableProcessSwap::Yes);
}

TEST(WebKit, DecidePolicyForNavigationActionForPOSTFormSubmissionThatRedirectsToGET)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadHTMLString:@"<form action=\"http://redirect/?result\" method=\"POST\"><input type=\"submit\" name=\"submitButton\" value=\"Submit\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    [TestProtocol registerWithScheme:@"http"];
    decidedPolicy = false;
    [webView evaluateJavaScript:@"document.forms[0].submit()" completionHandler:nil];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
    EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
    EXPECT_WK_STREQ("http://redirect/?result", [[[action request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
    EXPECT_FALSE([action _isRedirect]);

    // Wait to decide policy for redirect.
    decidedPolicy = false;
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
    EXPECT_WK_STREQ("GET", [[action request] HTTPMethod]);
    EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
    EXPECT_TRUE([action _isRedirect]);

    [TestProtocol unregister];
    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DecidePolicyForNavigationActionForPOSTFormSubmissionThatRedirectsToPOST)
{
    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);

    auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
    [[window contentView] addSubview:webView.get()];

    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];
    [webView setUIDelegate:controller.get()];

    finishedNavigation = false;
    [webView loadHTMLString:@"<form action=\"http://307-redirect/?result\" method=\"POST\"><input type=\"submit\" name=\"submitButton\" value=\"Submit\"></form>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
    TestWebKitAPI::Util::run(&finishedNavigation);

    [TestProtocol registerWithScheme:@"http"];
    decidedPolicy = false;
    [webView evaluateJavaScript:@"document.forms[0].submit()" completionHandler:nil];
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
    EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
    EXPECT_WK_STREQ("http://307-redirect/?result", [[[action request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
    EXPECT_FALSE([action _isRedirect]);

    // Wait to decide policy for redirect.
    decidedPolicy = false;
    TestWebKitAPI::Util::run(&decidedPolicy);

    EXPECT_EQ(WKNavigationTypeFormSubmitted, [action navigationType]);
    EXPECT_TRUE([action sourceFrame] == [action targetFrame]);
    EXPECT_WK_STREQ("POST", [[action request] HTTPMethod]);
    EXPECT_WK_STREQ("http://result/", [[[action request] URL] absoluteString]);
    EXPECT_EQ(webView.get(), [[action sourceFrame] webView]);
    EXPECT_WK_STREQ("http", [[[action sourceFrame] securityOrigin] protocol]);
    EXPECT_WK_STREQ("webkit.org", [[[action sourceFrame] securityOrigin] host]);
    EXPECT_TRUE([action _isRedirect]);

    [TestProtocol unregister];
    newWebView = nullptr;
    action = nullptr;
}

TEST(WebKit, DelayDecidePolicyForNavigationAction)
{
    shouldDelayDecision = true;

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    auto controller = adoptNS([[DecidePolicyForNavigationActionController alloc] init]);
    [webView setNavigationDelegate:controller.get()];

    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
    TestWebKitAPI::Util::run(&decidedPolicy);
    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
    TestWebKitAPI::Util::sleep(0.5); // Wait until the pending api request gets clear.
    EXPECT_TRUE([[webView URL] isEqual:testURL.get()]);

    shouldDelayDecision = false;
    delayedDecision(WKNavigationActionPolicyCancel);
}

static size_t calls;
static bool done;

@interface DecidePolicyForNavigationActionFragmentDelegate : NSObject <WKNavigationDelegate>
@end

@implementation DecidePolicyForNavigationActionFragmentDelegate

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    decisionHandler(WKNavigationActionPolicyAllow);
    const char* url = navigationAction.request.URL.absoluteString.UTF8String;
    switch (calls++) {
    case 0:
        EXPECT_STREQ(url, "http://webkit.org/");
        return;
    case 1:
        EXPECT_STREQ(url, "http://webkit.org/#fragment");
        done = true;
        return;
    }
    ASSERT_NOT_REACHED();
}

@end

TEST(WebKit, DecidePolicyForNavigationActionFragment)
{
    auto webView = adoptNS([[WKWebView alloc] init]);
    auto delegate = adoptNS([[DecidePolicyForNavigationActionFragmentDelegate alloc] init]);
    [webView setNavigationDelegate:delegate.get()];
    [webView loadHTMLString:@"<script>window.location.href='#fragment';</script>" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
    TestWebKitAPI::Util::run(&done);
}

#endif
