/*
 * Copyright (C) 2018 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 HAVE(SAFE_BROWSING)

#import "ClassMethodSwizzler.h"
#import "HTTPServer.h"
#import "PlatformUtilities.h"
#import "Test.h"
#import "TestNavigationDelegate.h"
#import "TestResourceLoadDelegate.h"
#import "TestURLSchemeHandler.h"
#import "TestWKWebView.h"
#import "WKWebViewConfigurationExtras.h"
#import <Foundation/NSURLError.h>
#import <WebKit/WKNavigationDelegate.h>
#import <WebKit/WKPreferencesPrivate.h>
#import <WebKit/WKUIDelegatePrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/_WKFeature.h>
#import <WebKit/_WKResourceLoadDelegate.h>
#import <WebKit/_WKResourceLoadInfo.h>
#import <wtf/RetainPtr.h>
#import <wtf/RunLoop.h>
#import <wtf/SoftLinking.h>
#import <wtf/URL.h>
#import <wtf/Vector.h>

SOFT_LINK_PRIVATE_FRAMEWORK(SafariSafeBrowsing);
SOFT_LINK_CLASS(SafariSafeBrowsing, SSBLookupContext);
SOFT_LINK_CLASS(SafariSafeBrowsing, SSBLookupResult);
SOFT_LINK_CLASS(SafariSafeBrowsing, SSBServiceLookupResult);

static bool committedNavigation;
static bool warningShown;
static bool didCloseCalled;

@interface SafeBrowsingNavigationDelegate : NSObject <WKNavigationDelegate, WKUIDelegatePrivate>
@end

@implementation SafeBrowsingNavigationDelegate

- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
    committedNavigation = true;
}

- (void)_webViewDidShowSafeBrowsingWarning:(WKWebView *)webView
{
    warningShown = true;
}

- (void)webViewDidClose:(WKWebView *)webView
{
    didCloseCalled = true;
}

@end

@interface TestServiceLookupResult : NSObject {
    RetainPtr<NSString> _provider;
    BOOL _isPhishing;
    BOOL _isMalware;
    BOOL _isUnwantedSoftware;
}
@end

@implementation TestServiceLookupResult

+ (instancetype)resultWithProvider:(RetainPtr<NSString>&&)provider phishing:(BOOL)phishing malware:(BOOL)malware unwantedSoftware:(BOOL)unwantedSoftware
{
    auto result = adoptNS([[TestServiceLookupResult alloc] init]);
    if (!result)
        return nil;

    result->_provider = WTF::move(provider);
    result->_isPhishing = phishing;
    result->_isMalware = malware;
    result->_isUnwantedSoftware = unwantedSoftware;

    return result.autorelease();
}

- (NSString *)provider
{
    return _provider.get();
}

- (BOOL)isPhishing
{
    return _isPhishing;
}

- (BOOL)isMalware
{
    return _isMalware;
}

- (BOOL)isUnwantedSoftware
{
    return _isUnwantedSoftware;
}

- (NSString *)malwareDetailsBaseURLString
{
    return @"test://";
}

- (NSURL *)learnMoreURL
{
    return [NSURL URLWithString:@"test://"];
}

- (NSString *)reportAnErrorBaseURLString
{
    return @"test://";
}

- (NSString *)localizedProviderDisplayName
{
    return @"test display name";
}

@end

@interface TestLookupResult : NSObject {
    RetainPtr<NSArray> _results;
}
@end

@implementation TestLookupResult

+ (instancetype)resultWithResults:(RetainPtr<NSArray<TestServiceLookupResult *>>&&)results
{
    auto result = adoptNS([[TestLookupResult alloc] init]);
    if (!result)
        return nil;
    
    result->_results = WTF::move(results);
    
    return result.autorelease();
}

- (NSArray<TestServiceLookupResult *> *)serviceLookupResults
{
    return _results.get();
}

@end

@interface TestLookupContext : NSObject
@end

@implementation TestLookupContext

+ (TestLookupContext *)sharedLookupContext
{
    static TestLookupContext *context = [[TestLookupContext alloc] init];
    return context;
}

- (void)lookUpURL:(NSURL *)URL completionHandler:(void (^)(TestLookupResult *, NSError *))completionHandler
{
    completionHandler([TestLookupResult resultWithResults:@[[TestServiceLookupResult resultWithProvider:@"SSBProviderApple" phishing:YES malware:NO unwantedSoftware:NO]]], nil);
}

@end

static NSURL *resourceURL(NSString *resource)
{
    return [NSBundle.test_resourcesBundle URLForResource:resource withExtension:@"html"];
}

TEST(SafeBrowsing, Preference)
{
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [TestLookupContext methodForSelector:@selector(sharedLookupContext)]);

    __block bool done = false;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    delegate.get().didStartProvisionalNavigation = ^(WKWebView *, WKNavigation *) {
        done = true;
    };

    auto webView = adoptNS([WKWebView new]);
    EXPECT_TRUE([webView configuration].preferences.fraudulentWebsiteWarningEnabled);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    [webView setNavigationDelegate:delegate.get()];
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple")]];
    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = NO;
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple2")]];
    TestWebKitAPI::Util::run(&done);
    EXPECT_FALSE([webView configuration].preferences.fraudulentWebsiteWarningEnabled);
    EXPECT_FALSE([webView _safeBrowsingWarning]);
}

static RetainPtr<WKWebView> safeBrowsingView()
{
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [TestLookupContext methodForSelector:@selector(sharedLookupContext)]);

    static auto delegate = adoptNS([SafeBrowsingNavigationDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    [webView setNavigationDelegate:delegate.get()];
    [webView setUIDelegate:delegate.get()];
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple")]];
    EXPECT_FALSE(warningShown);
    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
    EXPECT_TRUE(warningShown);
#if !PLATFORM(MAC)
    [[webView _safeBrowsingWarning] didMoveToWindow];
#endif
    return webView;
}

#if PLATFORM(MAC)
static void checkTitleAndClick(NSButton *button, const char* expectedTitle)
{
    EXPECT_STREQ(button.title.UTF8String, expectedTitle);
    [button performClick:nil];
}
#else
static void checkTitleAndClick(UIButton *button, const char* expectedTitle)
{
    EXPECT_STREQ([button attributedTitleForState:UIControlStateNormal].string.UTF8String, expectedTitle);
    UIView *target = button.superview.superview;
    SEL selector = NSSelectorFromString(strcmp(expectedTitle, "Go Back") ? @"showDetailsClicked" : @"goBackClicked");
    [target performSelector:selector];
}
#endif

template<typename ViewType> void goBack(ViewType *view, bool mainFrame = true)
{
    WKWebView *webView = (WKWebView *)view.superview;
    auto box = view.subviews.firstObject;
    checkTitleAndClick(box.subviews[3], "Go Back");
    if (mainFrame)
        EXPECT_EQ([webView _safeBrowsingWarning], nil);
    else
        EXPECT_NE([webView _safeBrowsingWarning], nil);
}

TEST(SafeBrowsing, GoBack)
{
    auto webView = safeBrowsingView();
    EXPECT_FALSE(didCloseCalled);
    goBack([webView _safeBrowsingWarning]);
    EXPECT_TRUE(didCloseCalled);
}

TEST(SafeBrowsing, GoBackAfterRestoreFromSessionState)
{
    auto webView1 = adoptNS([WKWebView new]);
    [webView1 loadRequest:[NSURLRequest requestWithURL:[NSBundle.test_resourcesBundle URLForResource:@"simple" withExtension:@"html"]]];
    [webView1 _test_waitForDidFinishNavigation];
    _WKSessionState *state = [webView1 _sessionState];

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [TestLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto delegate = adoptNS([SafeBrowsingNavigationDelegate new]);
    auto webView2 = adoptNS([WKWebView new]);
    [webView2 configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    [webView2 setNavigationDelegate:delegate.get()];
    [webView2 setUIDelegate:delegate.get()];
    [webView2 _restoreSessionState:state andNavigate:YES];
    EXPECT_FALSE(warningShown);
    while (![webView2 _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
    EXPECT_TRUE(warningShown);
#if !PLATFORM(MAC)
    [[webView2 _safeBrowsingWarning] didMoveToWindow];
#endif
    EXPECT_FALSE(didCloseCalled);
    goBack([webView2 _safeBrowsingWarning]);
    EXPECT_TRUE(didCloseCalled);
    WKBackForwardList *list = [webView2 backForwardList];
    EXPECT_FALSE(!!list.backItem);
    EXPECT_FALSE(!!list.forwardItem);
    EXPECT_TRUE([list.currentItem.URL.path hasSuffix:@"/simple.html"]);
}

template<typename ViewType> void visitUnsafeSite(ViewType *view)
{
    [view performSelector:NSSelectorFromString(@"clickedOnLink:") withObject:[NSURL URLWithString:@"WKVisitUnsafeWebsiteSentinel"]];
}

TEST(SafeBrowsing, VisitUnsafeWebsite)
{
    auto webView = safeBrowsingView();
    auto warning = [webView _safeBrowsingWarning];
    EXPECT_EQ(warning.subviews.count, 1ull);
#if PLATFORM(MAC)
    EXPECT_GT(warning.subviews.firstObject.subviews[2].frame.size.height, 0);
#endif
    EXPECT_WK_STREQ([webView title], "Deceptive Website Warning");
    checkTitleAndClick(warning.subviews.firstObject.subviews[4], "Show Details");
    EXPECT_EQ(warning.subviews.count, 2ull);
    EXPECT_FALSE(committedNavigation);
    visitUnsafeSite(warning);
    EXPECT_WK_STREQ([webView title], "");
    TestWebKitAPI::Util::run(&committedNavigation);
}

TEST(SafeBrowsing, NavigationClearsWarning)
{
    auto webView = safeBrowsingView();
    EXPECT_NE([webView _safeBrowsingWarning], nil);
    [webView loadRequest:[NSURLRequest requestWithURL:[NSBundle.test_resourcesBundle URLForResource:@"simple2" withExtension:@"html"]]];
    while ([webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, ShowWarningSPI)
{
    __block bool completionHandlerCalled = false;
    __block BOOL shouldContinueValue = NO;
    auto webView = adoptNS([WKWebView new]);
    auto showWarning = ^{
        completionHandlerCalled = false;
        [webView _showSafeBrowsingWarningWithURL:nil title:@"test title" warning:@"test warning" details:adoptNS([[NSAttributedString alloc] initWithString:@"test details"]).get() completionHandler:^(BOOL shouldContinue) {
            shouldContinueValue = shouldContinue;
            completionHandlerCalled = true;
        }];
#if !PLATFORM(MAC)
        [[webView _safeBrowsingWarning] didMoveToWindow];
#endif
    };

    showWarning();
    checkTitleAndClick([webView _safeBrowsingWarning].subviews.firstObject.subviews[3], "Go Back");
    TestWebKitAPI::Util::run(&completionHandlerCalled);
    EXPECT_FALSE(shouldContinueValue);

    showWarning();
    [[webView _safeBrowsingWarning] performSelector:NSSelectorFromString(@"clickedOnLink:") withObject:[WKWebView _visitUnsafeWebsiteSentinel]];
    TestWebKitAPI::Util::run(&completionHandlerCalled);
    EXPECT_TRUE(shouldContinueValue);
}

static Vector<URL> urls;

@interface SafeBrowsingObserver : NSObject
@end

@implementation SafeBrowsingObserver

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context
{
    urls.append((NSURL *)[change objectForKey:NSKeyValueChangeNewKey]);
}

@end

TEST(SafeBrowsing, URLObservation)
{
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [TestLookupContext methodForSelector:@selector(sharedLookupContext)]);

    RetainPtr<NSURL> simpleURL = [NSBundle.test_resourcesBundle URLForResource:@"simple" withExtension:@"html"];
    RetainPtr<NSURL> simple2URL = [NSBundle.test_resourcesBundle URLForResource:@"simple2" withExtension:@"html"];
    auto observer = adoptNS([SafeBrowsingObserver new]);

    auto webViewWithWarning = [&] () -> RetainPtr<WKWebView> {
        auto webView = adoptNS([WKWebView new]);
        auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
        navigationDelegate.get().decidePolicyForNavigationAction = ^(WKNavigationAction *action, void (^decisionHandler)(WKNavigationActionPolicy)) {
            TestWebKitAPI::Util::runFor(0.01_s);
            decisionHandler(WKNavigationActionPolicyAllow);
        };
        [webView setNavigationDelegate:navigationDelegate.get()];
        [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
        [webView addObserver:observer.get() forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:nil];

        [webView loadHTMLString:@"meaningful content to be drawn" baseURL:simpleURL.get()];
        while (![webView _safeBrowsingWarning])
            TestWebKitAPI::Util::spinRunLoop();
#if !PLATFORM(MAC)
        [[webView _safeBrowsingWarning] didMoveToWindow];
#endif
        visitUnsafeSite([webView _safeBrowsingWarning]);
        EXPECT_TRUE(!![webView _safeBrowsingWarning]);
        while ([webView _safeBrowsingWarning])
            TestWebKitAPI::Util::spinRunLoop();
        EXPECT_FALSE(!![webView _safeBrowsingWarning]);

        [webView evaluateJavaScript:[NSString stringWithFormat:@"window.location='%@'", simple2URL.get()] completionHandler:nil];
        while (![webView _safeBrowsingWarning])
            TestWebKitAPI::Util::spinRunLoop();
#if !PLATFORM(MAC)
        [[webView _safeBrowsingWarning] didMoveToWindow];
#endif
        return webView;
    };
    
    auto checkURLs = [&] (Vector<RetainPtr<NSURL>>&& expected) {
        EXPECT_EQ(urls.size(), expected.size());
        if (urls.size() != expected.size())
            return;
        for (size_t i = 0; i < expected.size(); ++i)
            EXPECT_STREQ(urls[i].string().utf8().data(), [expected[i] absoluteString].UTF8String);
    };

    {
        auto webView = webViewWithWarning();
        checkURLs({ simpleURL, simple2URL });
        goBack([webView _safeBrowsingWarning]);
        checkURLs({ simpleURL, simple2URL, simpleURL });
        [webView removeObserver:observer.get() forKeyPath:@"URL"];
    }
    
    urls.clear();

    {
        auto webView = webViewWithWarning();
        checkURLs({ simpleURL, simple2URL });
        visitUnsafeSite([webView _safeBrowsingWarning]);
        TestWebKitAPI::Util::spinRunLoop(5);
        checkURLs({ simpleURL, simple2URL });
        [webView removeObserver:observer.get() forKeyPath:@"URL"];
    }
}

static RetainPtr<NSString> phishingResourceName;

@interface SimpleLookupContext : NSObject
@end

@implementation SimpleLookupContext

+ (SimpleLookupContext *)sharedLookupContext
{
    static SimpleLookupContext *context = [[SimpleLookupContext alloc] init];
    return context;
}

- (void)lookUpURL:(NSURL *)URL completionHandler:(void (^)(TestLookupResult *, NSError *))completionHandler
{
    BOOL phishing = NO;
    if ([URL isEqual:resourceURL(phishingResourceName.get())] || [[URL path] hasSuffix:phishingResourceName.get()])
        phishing = YES;
    completionHandler([TestLookupResult resultWithResults:@[[TestServiceLookupResult resultWithProvider:@"SSBProviderApple" phishing:phishing malware:NO unwantedSoftware:NO]]], nil);
}

@end

static bool navigationFinished;

@interface WKWebViewGoBackNavigationDelegate : NSObject <WKNavigationDelegate>
@end

@implementation WKWebViewGoBackNavigationDelegate

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

@end

TEST(SafeBrowsing, WKWebViewGoBack)
{
    phishingResourceName = @"simple3";
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [SimpleLookupContext methodForSelector:@selector(sharedLookupContext)]);
    
    auto delegate = adoptNS([WKWebViewGoBackNavigationDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    [webView setNavigationDelegate:delegate.get()];
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple")]];
    TestWebKitAPI::Util::run(&navigationFinished);

    navigationFinished = false;
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple2")]];
    TestWebKitAPI::Util::run(&navigationFinished);

    navigationFinished = false;
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple3")]];
    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
    [webView goBack];
    TestWebKitAPI::Util::run(&navigationFinished);
    EXPECT_TRUE([[webView URL] isEqual:resourceURL(@"simple2")]);
}

TEST(SafeBrowsing, WKWebViewGoBackIFrame)
{
    phishingResourceName = @"simple";
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [SimpleLookupContext methodForSelector:@selector(sharedLookupContext)]);
    
    auto delegate = adoptNS([TestNavigationDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView configuration].preferences._safeBrowsingEnabled = YES;

    __block bool navigationFailed = false;
    __block bool navigationFinished = false;
    delegate.get().didFailProvisionalLoadInSubframeWithError = ^(WKWebView *, WKFrameInfo *frame, NSError *error) {
        EXPECT_NOT_NULL(error);
        auto failingURL = (NSURL *)[error.userInfo valueForKey:NSURLErrorFailingURLErrorKey];
        EXPECT_TRUE([failingURL.lastPathComponent isEqualToString:@"simple.html"]);
#if USE(NSURL_ERROR_FAILING_URL_STRING_KEY)
        auto failingURLString = (NSString *)[error.userInfo valueForKey:NSURLErrorFailingURLStringErrorKey];
        EXPECT_TRUE([failingURLString hasSuffix:@"/simple.html"]);
#endif
        navigationFailed = true;
    };
    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *navigation) {
        navigationFinished = true;
    };

    [webView setNavigationDelegate:delegate.get()];
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple2")]];
    TestWebKitAPI::Util::run(&navigationFinished);
    EXPECT_FALSE(navigationFailed);
    navigationFinished = false;
    navigationFailed = false;

    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple-iframe")]];
    TestWebKitAPI::Util::run(&navigationFinished);
    TestWebKitAPI::Util::run(&navigationFailed);
}

@interface NullLookupContext : NSObject
@end
@implementation NullLookupContext
+ (NullLookupContext *)sharedLookupContext
{
    return nil;
}
@end

TEST(SafeBrowsing, MissingFramework)
{
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [NullLookupContext methodForSelector:@selector(sharedLookupContext)]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600)]);
    [webView synchronouslyLoadTestPageNamed:@"simple"];
}

static Seconds delayDuration;

@interface DelayedLookupContext : NSObject
@end

@implementation DelayedLookupContext

+ (DelayedLookupContext *)sharedLookupContext
{
    static DelayedLookupContext *context = [[DelayedLookupContext alloc] init];
    return context;
}

- (void)lookUpURL:(NSURL *)URL completionHandler:(void (^)(TestLookupResult *, NSError *))completionHandler
{
    BOOL phishing = ![URL isEqual:resourceURL(@"simple2")] && ![[URL path] isEqual:@"/safe"];
    RunLoop::mainSingleton().dispatchAfter(delayDuration, [completionHandler = makeBlockPtr(completionHandler), phishing] {
        completionHandler.get()([TestLookupResult resultWithResults:@[[TestServiceLookupResult resultWithProvider:@"SSBProviderApple" phishing:phishing malware:NO unwantedSoftware:NO]]], nil);
    });
}

@end

TEST(SafeBrowsing, HangTimeout)
{
    delayDuration = 1000_s;
    TestWebKitAPI::HTTPServer server({
        { "/test"_s, { "test"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::HttpsProxy);
    auto configuration = server.httpsProxyConfiguration();

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [DelayedLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    navigationFinished = false;
    [webView setNavigationDelegate:delegate.get()];
    [webView evaluateJavaScript:@"window.location = 'https://example2.com/test'" completionHandler:nil];

    [delegate waitForDidFinishNavigation];
}

TEST(SafeBrowsing, PostResponse)
{
    delayDuration = 25_ms;
    TestWebKitAPI::HTTPServer server({
        { "/test"_s, { "test"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::HttpsProxy);
    auto configuration = server.httpsProxyConfiguration();

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [DelayedLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    navigationFinished = false;
    [webView setNavigationDelegate:delegate.get()];
    [webView evaluateJavaScript:@"window.location = 'https://example2.com/test'" completionHandler:nil];

    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, PostResponseIframe)
{
    delayDuration = 25_ms;
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [DelayedLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto delegate = adoptNS([TestNavigationDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    [webView configuration].preferences._safeBrowsingEnabled = YES;

    __block bool navigationFailed = false;
    __block bool navigationFinished = false;
    delegate.get().didFailProvisionalLoadInSubframeWithError = ^(WKWebView *, WKFrameInfo *frame, NSError *error) {
        EXPECT_NOT_NULL(error);
        auto failingURL = (NSURL *)[error.userInfo valueForKey:NSURLErrorFailingURLErrorKey];
        EXPECT_TRUE([failingURL.lastPathComponent isEqualToString:@"simple.html"]);
#if USE(NSURL_ERROR_FAILING_URL_STRING_KEY)
        auto failingURLString = (NSString *)[error.userInfo valueForKey:NSURLErrorFailingURLStringErrorKey];
        EXPECT_TRUE([failingURLString hasSuffix:@"/simple.html"]);
#endif
        navigationFailed = true;
    };
    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *navigation) {
        navigationFinished = true;
    };

    [webView setNavigationDelegate:delegate.get()];
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple2")]];
    TestWebKitAPI::Util::run(&navigationFinished);
    EXPECT_FALSE(navigationFailed);
}

static const char* mainResource = "";
TEST(SafeBrowsing, PreresponseSafeBrowsingWarning)
{
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [TestLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    auto handler = adoptNS([[TestURLSchemeHandler alloc] init]);
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration setURLSchemeHandler:handler.get() forURLScheme:@"sb"];
    configuration.get().preferences.fraudulentWebsiteWarningEnabled = YES;
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
    [webView setNavigationDelegate:delegate.get()];

    [handler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
        RunLoop::mainSingleton().dispatchAfter(1000_s, [task = retainPtr(task)] {
            auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.get().request.URL MIMEType:@"text/html" expectedContentLength:0 textEncodingName:nil]);
            [task didReceiveResponse:response.get()];
            [task didReceiveData:[NSData dataWithBytes:mainResource length:strlen(mainResource)]];
            [task didFinish];
        });
    }];

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"sb://host1/main.html"]]];

    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, PostResponseServerSideRedirect)
{
    delayDuration = 2_ms;
    TestWebKitAPI::HTTPServer server({
        { "/safe"_s, { 301, { { "Location"_s, "/redirectTarget"_s } } } },
        { "/redirectTarget"_s, { "hi"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::HttpsProxy);
    auto configuration = server.httpsProxyConfiguration();

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [DelayedLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    navigationFinished = false;
    [webView setNavigationDelegate:delegate.get()];
    [webView evaluateJavaScript:@"window.location = 'https://example2.com/safe'" completionHandler:nil];

    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, MultipleRedirectsFirstPhishing)
{
    phishingResourceName = @"safe";
    TestWebKitAPI::HTTPServer server({
        { "/safe"_s, { 301, { { "Location"_s, "/redirectTarget1"_s } } } },
        { "/redirectTarget1"_s, { 301, { { "Location"_s, "/redirectTarget2"_s } } } },
        { "/redirectTarget2"_s, { "hi"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::HttpsProxy);
    auto configuration = server.httpsProxyConfiguration();

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [SimpleLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    navigationFinished = false;
    [webView setNavigationDelegate:delegate.get()];
    [webView evaluateJavaScript:@"window.location = 'https://example2.com/safe'" completionHandler:nil];

    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, MultipleRedirectsMiddlePhishing)
{
    phishingResourceName = @"redirectTarget1";
    TestWebKitAPI::HTTPServer server({
        { "/safe"_s, { 301, { { "Location"_s, "/redirectTarget1"_s } } } },
        { "/redirectTarget1"_s, { 301, { { "Location"_s, "/redirectTarget2"_s } } } },
        { "/redirectTarget2"_s, { "hi"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::HttpsProxy);
    auto configuration = server.httpsProxyConfiguration();

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [SimpleLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    navigationFinished = false;
    [webView setNavigationDelegate:delegate.get()];
    [webView evaluateJavaScript:@"window.location = 'https://example2.com/safe'" completionHandler:nil];

    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, MultipleRedirectsLastPhishing)
{
    phishingResourceName = @"redirectTarget2";
    TestWebKitAPI::HTTPServer server({
        { "/safe"_s, { 301, { { "Location"_s, "/redirectTarget1"_s } } } },
        { "/redirectTarget1"_s, { 301, { { "Location"_s, "/redirectTarget2"_s } } } },
        { "/redirectTarget2"_s, { "hi"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::HttpsProxy);
    auto configuration = server.httpsProxyConfiguration();

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [SimpleLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    navigationFinished = false;
    [webView setNavigationDelegate:delegate.get()];
    [webView evaluateJavaScript:@"window.location = 'https://example2.com/safe'" completionHandler:nil];

    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, PostResponseInjectedBundleSkipsDecidePolicyForResponse)
{
    delayDuration = 25_ms;
    TestWebKitAPI::HTTPServer server({
        { "/test"_s, { "test"_s } },
    });
    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"SkipDecidePolicyForResponsePlugIn"];

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [DelayedLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    navigationFinished = false;
    [webView setNavigationDelegate:delegate.get()];
    [webView evaluateJavaScript:@"window.location = 'https://example2.com/test'" completionHandler:nil];

    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, PostTimeout)
{
    delayDuration = 100_ms;
    TestWebKitAPI::HTTPServer server({
        { "/test"_s, { "test"_s } },
    }, TestWebKitAPI::HTTPServer::Protocol::HttpsProxy);
    auto configuration = server.httpsProxyConfiguration();

    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [DelayedLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
    [webView configuration].preferences.fraudulentWebsiteWarningEnabled = YES;
    auto delegate = adoptNS([TestNavigationDelegate new]);
    [delegate allowAnyTLSCertificate];
    [webView setNavigationDelegate:delegate.get()];

    [webView evaluateJavaScript:@"window.location = 'https://example2.com/test'" completionHandler:nil];

    EXPECT_WK_STREQ([webView title], "");
    while (![webView _safeBrowsingWarning])
        TestWebKitAPI::Util::spinRunLoop();
}

TEST(SafeBrowsing, PhishingInFrame)
{
    phishingResourceName = @"simple";
    ClassMethodSwizzler swizzler(getSSBLookupContextClassSingleton(), @selector(sharedLookupContext), [SimpleLookupContext methodForSelector:@selector(sharedLookupContext)]);

    auto delegate = adoptNS([TestNavigationDelegate new]);
    auto webView = adoptNS([WKWebView new]);
    auto configuration = webView.get().configuration;
    auto preferences = configuration.preferences;
    preferences._safeBrowsingEnabled = YES;

    for (_WKFeature *feature in [WKPreferences _features]) {
        if ([feature.key isEqualToString:@"SiteIsolationEnabled"]) {
            [preferences _setEnabled:YES forFeature:feature];
            break;
        }
    }

    __block bool navigationFailed = false;
    __block bool navigationFinished = false;
    delegate.get().didFailProvisionalLoadInSubframeWithError = ^(WKWebView *, WKFrameInfo *frame, NSError *error) {
        EXPECT_NOT_NULL(error);
        auto failingURL = (NSURL *)[error.userInfo valueForKey:NSURLErrorFailingURLErrorKey];
        EXPECT_TRUE([failingURL.lastPathComponent isEqualToString:@"simple.html"]);
#if USE(NSURL_ERROR_FAILING_URL_STRING_KEY)
        auto failingURLString = (NSString *)[error.userInfo valueForKey:NSURLErrorFailingURLStringErrorKey];
        EXPECT_TRUE([failingURLString hasSuffix:@"/simple.html"]);
#endif
        navigationFailed = true;
    };
    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *navigation) {
        navigationFinished = true;
    };

    [webView setNavigationDelegate:delegate.get()];
    [webView loadRequest:[NSURLRequest requestWithURL:resourceURL(@"simple-iframe")]];
    TestWebKitAPI::Util::run(&navigationFinished);
    TestWebKitAPI::Util::run(&navigationFailed);
    EXPECT_TRUE(navigationFailed);
    EXPECT_TRUE(navigationFinished);
}


#endif // HAVE(SAFE_BROWSING)
