/*
 * Copyright (C) 2015-2019 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(IOS_FAMILY)

#import "PlatformUtilities.h"
#import "Test.h"
#import "TestProtocol.h"
#import "TestWKWebView.h"
#import <CoreServices/CoreServices.h>
#import <WebCore/WebCoreThread.h>
#import <WebKit/WKNavigationDelegatePrivate.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WebDataSourcePrivate.h>
#import <WebKit/WebKit.h>
#import <WebKit/WebPreferencesPrivate.h>
#import <WebKit/WebUIKitSupport.h>
#import <WebKit/WebViewPrivate.h>
#import <WebKit/_WKDownload.h>
#import <WebKit/_WKDownloadDelegate.h>
#import <wtf/RetainPtr.h>

using namespace TestWebKitAPI;

static bool isDone;
static bool downloadIsDone;

static NSString * const pagesDocumentPreviewMIMEType = @"application/pdf";
static NSURL * const pagesDocumentURL = [[NSBundle.mainBundle URLForResource:@"pages" withExtension:@"pages" subdirectory:@"TestWebKitAPI.resources"] retain];

@interface QuickLookDelegate : NSObject <WKNavigationDelegatePrivate, _WKDownloadDelegate>
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithExpectedFileURL:(NSURL *)fileURL responsePolicy:(WKNavigationResponsePolicy)responsePolicy;
- (instancetype)initWithExpectedFileURL:(NSURL *)fileURL previewMIMEType:(NSString *)mimeType responsePolicy:(WKNavigationResponsePolicy)responsePolicy;
- (void)verifyDownload;

@property (nonatomic, readonly) BOOL didFailNavigation;
@property (nonatomic, readonly) BOOL didFinishNavigation;
@property (nonatomic, readonly) BOOL didFinishQuickLookLoad;
@property (nonatomic, readonly) BOOL didStartQuickLookLoad;
@property (nonatomic, readonly, nullable) NSError *navigationError;

@end

@implementation QuickLookDelegate {
@protected
    NSUInteger _downloadFileSize;
    NSUInteger _expectedFileSize;
    RetainPtr<NSData> _expectedFileData;
    RetainPtr<NSError> _navigationError;
    RetainPtr<NSString> _expectedFileName;
    RetainPtr<NSString> _expectedFileType;
    RetainPtr<NSString> _expectedMIMEType;
    RetainPtr<NSURL> _downloadDestinationURL;
    WKNavigationResponsePolicy _responsePolicy;
}

static void readFile(NSURL *fileURL, NSUInteger& fileSize, RetainPtr<NSString>& fileName, RetainPtr<NSString>& fileType, RetainPtr<NSString>& mimeType, RetainPtr<NSData>& fileData)
{
    if (NSDictionary *attributes = [NSFileManager.defaultManager attributesOfItemAtPath:fileURL.path error:nil])
        fileSize = [attributes[NSFileSize] unsignedIntegerValue];

    fileName = fileURL.lastPathComponent;

    NSString *typeIdentifier = nil;
    if ([fileURL getResourceValue:&typeIdentifier forKey:NSURLTypeIdentifierKey error:nil])
        fileType = typeIdentifier;

    mimeType = adoptCF(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)typeIdentifier, kUTTagClassMIMEType));
    fileData = [NSData dataWithContentsOfURL:fileURL];
}

- (instancetype)initWithExpectedFileURL:(NSURL *)fileURL responsePolicy:(WKNavigationResponsePolicy)responsePolicy
{
    if (!(self = [super init]))
        return nil;

    readFile(fileURL, _expectedFileSize, _expectedFileName, _expectedFileType, _expectedMIMEType, _expectedFileData);

    _responsePolicy = responsePolicy;
    return self;
}

- (instancetype)initWithExpectedFileURL:(NSURL *)fileURL previewMIMEType:(NSString *)mimeType responsePolicy:(WKNavigationResponsePolicy)responsePolicy
{
    if (!(self = [self initWithExpectedFileURL:fileURL responsePolicy:responsePolicy]))
        return nil;
    
    _expectedMIMEType = mimeType;
    return self;
}

- (nullable NSError *)navigationError
{
    return _navigationError.get();
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    _didFailNavigation = NO;
    _didFinishNavigation = NO;
    _didFinishQuickLookLoad = NO;
    _didStartQuickLookLoad = NO;
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    EXPECT_TRUE(navigationResponse.canShowMIMEType);
    EXPECT_WK_STREQ(_expectedFileName.get(), navigationResponse.response.URL.lastPathComponent);
    EXPECT_WK_STREQ(_expectedMIMEType.get(), navigationResponse.response.MIMEType);
    decisionHandler(_responsePolicy);
}

- (void)_webView:(WKWebView *)webView didStartLoadForQuickLookDocumentInMainFrameWithFileName:(NSString *)fileName uti:(NSString *)uti
{
    EXPECT_FALSE(_didFinishQuickLookLoad);
    EXPECT_FALSE(_didStartQuickLookLoad);
    EXPECT_WK_STREQ(_expectedFileName.get(), fileName);
    EXPECT_WK_STREQ(_expectedFileType.get(), uti);
    _didStartQuickLookLoad = YES;
}

- (void)_webView:(WKWebView *)webView didFinishLoadForQuickLookDocumentInMainFrame:(NSData *)documentData
{
    EXPECT_EQ(_expectedFileSize, documentData.length);
    EXPECT_TRUE([_expectedFileData isEqualToData:documentData]);
    EXPECT_FALSE(_didFinishQuickLookLoad);
    EXPECT_TRUE(_didStartQuickLookLoad);
    _didFinishQuickLookLoad = YES;
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    EXPECT_FALSE(_didFailNavigation);
    EXPECT_FALSE(_didFinishNavigation);
    _didFinishNavigation = YES;
    isDone = true;
}

- (void)_webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error userInfo:(id<NSSecureCoding>)userInfo
{
    EXPECT_FALSE(_didFailNavigation);
    EXPECT_FALSE(_didFinishNavigation);
    EXPECT_NULL(_navigationError);
    _didFailNavigation = YES;
    _navigationError = error;
    isDone = true;
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    EXPECT_FALSE(_didFailNavigation);
    EXPECT_FALSE(_didFinishNavigation);
    EXPECT_NULL(_navigationError);
    _didFailNavigation = YES;
    _navigationError = error;
    isDone = true;
}

- (void)_webViewWebProcessDidCrash:(WKWebView *)webView
{
    RELEASE_ASSERT_NOT_REACHED();
}

- (void)_downloadDidStart:(_WKDownload *)download
{
    EXPECT_WK_STREQ(_expectedFileName.get(), download.request.URL.lastPathComponent);
}

- (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
{
    EXPECT_WK_STREQ(_expectedFileName.get(), response.URL.lastPathComponent);
    EXPECT_WK_STREQ(_expectedMIMEType.get(), response.MIMEType);
}

- (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
{
    _downloadFileSize += length;
}

- (void)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename completionHandler:(void (^)(BOOL, NSString *))completionHandler
{
    EXPECT_WK_STREQ(_expectedFileName.get(), filename);
    
    NSURL *tempDirectoryURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
    _downloadDestinationURL = [NSURL fileURLWithPath:filename relativeToURL:tempDirectoryURL];
    completionHandler(YES, [_downloadDestinationURL path]);
}

- (void)_downloadDidFinish:(_WKDownload *)download
{
    EXPECT_EQ(_expectedFileSize, _downloadFileSize);
    downloadIsDone = true;
}

- (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
{
    RELEASE_ASSERT_NOT_REACHED();
}

- (void)_downloadDidCancel:(_WKDownload *)download
{
    RELEASE_ASSERT_NOT_REACHED();
}

- (void)verifyDownload
{
    EXPECT_TRUE([NSFileManager.defaultManager fileExistsAtPath:[_downloadDestinationURL path]]);

    NSUInteger downloadFileSize;
    RetainPtr<NSData> downloadFileData;
    RetainPtr<NSString> downloadFileName;
    RetainPtr<NSString> downloadFileType;
    RetainPtr<NSString> downloadMIMEType;
    readFile(_downloadDestinationURL.get(), downloadFileSize, downloadFileName, downloadFileType, downloadMIMEType, downloadFileData);

    EXPECT_EQ(_expectedFileSize, downloadFileSize);
    EXPECT_TRUE([_expectedFileData isEqualToData:downloadFileData.get()]);
    EXPECT_WK_STREQ(_expectedFileName.get(), downloadFileName.get());
    EXPECT_WK_STREQ(_expectedFileType.get(), downloadFileType.get());
    EXPECT_WK_STREQ(_expectedMIMEType.get(), downloadMIMEType.get());
}

@end

static RetainPtr<WKWebView> runTest(QuickLookDelegate *delegate, NSURLRequest *request, BOOL shouldDecidePolicyBeforeLoading)
{
    auto processPool = adoptNS([[WKProcessPool alloc] init]);
    [processPool _setDownloadDelegate:delegate];

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

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration.get()]);
    [webView setNavigationDelegate:delegate];
    [webView loadRequest:request];

    isDone = false;
    Util::run(&isDone);

    return webView;
}

static RetainPtr<WKWebView> runTestDecideBeforeLoading(QuickLookDelegate *delegate, NSURLRequest *request)
{
    return runTest(delegate, request, YES);
}

static RetainPtr<WKWebView> runTestDecideAfterLoading(QuickLookDelegate *delegate, NSURLRequest *request)
{
    return runTest(delegate, request, NO);
}

TEST(QuickLook, AllowResponseBeforeLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookDelegate alloc] initWithExpectedFileURL:pagesDocumentURL responsePolicy:WKNavigationResponsePolicyAllow]);
    runTestDecideBeforeLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

TEST(QuickLook, AllowResponseAfterLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookDelegate alloc] initWithExpectedFileURL:pagesDocumentURL previewMIMEType:pagesDocumentPreviewMIMEType responsePolicy:WKNavigationResponsePolicyAllow]);
    runTestDecideAfterLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

@interface QuickLookAsyncDelegate : QuickLookDelegate
@end

@implementation QuickLookAsyncDelegate

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    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(_responsePolicy);
    });
}

@end

TEST(QuickLook, AsyncAllowResponseBeforeLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookAsyncDelegate alloc] initWithExpectedFileURL:pagesDocumentURL responsePolicy:WKNavigationResponsePolicyAllow]);
    runTestDecideBeforeLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

TEST(QuickLook, AsyncAllowResponseAfterLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookAsyncDelegate alloc] initWithExpectedFileURL:pagesDocumentURL previewMIMEType:pagesDocumentPreviewMIMEType responsePolicy:WKNavigationResponsePolicyAllow]);
    runTestDecideAfterLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

TEST(QuickLook, CancelResponseBeforeLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookDelegate alloc] initWithExpectedFileURL:pagesDocumentURL responsePolicy:WKNavigationResponsePolicyCancel]);
    runTestDecideBeforeLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_EQ(WebKitErrorFrameLoadInterruptedByPolicyChange, [delegate navigationError].code);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_FALSE([delegate didFinishQuickLookLoad]);
    EXPECT_FALSE([delegate didStartQuickLookLoad]);
    EXPECT_TRUE([delegate didFailNavigation]);
}

TEST(QuickLook, CancelResponseAfterLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookDelegate alloc] initWithExpectedFileURL:pagesDocumentURL previewMIMEType:pagesDocumentPreviewMIMEType responsePolicy:WKNavigationResponsePolicyCancel]);
    runTestDecideAfterLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_EQ(WebKitErrorFrameLoadInterruptedByPolicyChange, [delegate navigationError].code);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

TEST(QuickLook, DownloadResponseBeforeLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookDelegate alloc] initWithExpectedFileURL:pagesDocumentURL responsePolicy:_WKNavigationResponsePolicyBecomeDownload]);
    runTestDecideBeforeLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_EQ(WebKitErrorFrameLoadInterruptedByPolicyChange, [delegate navigationError].code);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_FALSE([delegate didFinishQuickLookLoad]);
    EXPECT_FALSE([delegate didStartQuickLookLoad]);
    EXPECT_TRUE([delegate didFailNavigation]);

    Util::run(&downloadIsDone);
    [delegate verifyDownload];
}

TEST(QuickLook, DownloadResponseAfterLoadingPreview)
{
    auto delegate = adoptNS([[QuickLookDelegate alloc] initWithExpectedFileURL:pagesDocumentURL previewMIMEType:pagesDocumentPreviewMIMEType responsePolicy:_WKNavigationResponsePolicyBecomeDownload]);
    runTestDecideAfterLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_EQ(WebKitErrorFrameLoadInterruptedByPolicyChange, [delegate navigationError].code);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

@interface QuickLookPasswordDelegate : QuickLookDelegate
@property (nonatomic) BOOL didRequestPassword;
@end

@implementation QuickLookPasswordDelegate

- (void)_webViewDidRequestPasswordForQuickLookDocument:(WKWebView *)webView
{
    _didRequestPassword = YES;
    isDone = true;
}

@end

TEST(QuickLook, RequestPasswordBeforeLoadingPreview)
{
    NSURL *passwordProtectedDocumentURL = [NSBundle.mainBundle URLForResource:@"password-protected" withExtension:@"pages" subdirectory:@"TestWebKitAPI.resources"];
    auto delegate = adoptNS([[QuickLookPasswordDelegate alloc] initWithExpectedFileURL:passwordProtectedDocumentURL responsePolicy:WKNavigationResponsePolicyAllow]);
    runTestDecideBeforeLoading(delegate.get(), [NSURLRequest requestWithURL:passwordProtectedDocumentURL]);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didRequestPassword]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

TEST(QuickLook, RequestPasswordAfterLoadingPreview)
{
    NSURL *passwordProtectedDocumentURL = [NSBundle.mainBundle URLForResource:@"password-protected" withExtension:@"pages" subdirectory:@"TestWebKitAPI.resources"];
    auto delegate = adoptNS([[QuickLookPasswordDelegate alloc] initWithExpectedFileURL:passwordProtectedDocumentURL previewMIMEType:pagesDocumentPreviewMIMEType responsePolicy:WKNavigationResponsePolicyAllow]);
    runTestDecideAfterLoading(delegate.get(), [NSURLRequest requestWithURL:passwordProtectedDocumentURL]);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_FALSE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didRequestPassword]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);
}

TEST(QuickLook, ReloadAndSameDocumentNavigation)
{
    auto delegate = adoptNS([[QuickLookDelegate alloc] initWithExpectedFileURL:pagesDocumentURL responsePolicy:WKNavigationResponsePolicyAllow]);
    auto webView = runTestDecideBeforeLoading(delegate.get(), [NSURLRequest requestWithURL:pagesDocumentURL]);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);

    isDone = false;
    [webView evaluateJavaScript:@"window.location.reload()" completionHandler:nil];
    Util::run(&isDone);
    EXPECT_FALSE([delegate didFailNavigation]);
    EXPECT_TRUE([delegate didFinishNavigation]);
    EXPECT_TRUE([delegate didFinishQuickLookLoad]);
    EXPECT_TRUE([delegate didStartQuickLookLoad]);

    isDone = false;
    [webView evaluateJavaScript:@"window.location = '#test'; window.location.hash" completionHandler:^(id _Nullable value, NSError * _Nullable error) {
        EXPECT_NULL(error);
        EXPECT_WK_STREQ(@"#test", value);
        isDone = true;
    }];
    Util::run(&isDone);
}

@interface QuickLookLegacyDelegate : NSObject <WebFrameLoadDelegate, WebPolicyDelegate>
@end

@implementation QuickLookLegacyDelegate

- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
    isDone = true;
}

- (void)webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
{
    EXPECT_WK_STREQ(pagesDocumentPreviewMIMEType, type);
    [listener use];
}

@end

TEST(QuickLook, LegacyQuickLookContent)
{
    WebKitInitialize();
    WebThreadLock();

    auto webView = adoptNS([[WebView alloc] init]);

    auto delegate = adoptNS([[QuickLookLegacyDelegate alloc] init]);
    [webView setFrameLoadDelegate:delegate.get()];
    [webView setPolicyDelegate:delegate.get()];

    auto webPreferences = adoptNS([[WebPreferences alloc] initWithIdentifier:@"LegacyQuickLookContent"]);
    [webPreferences setQuickLookDocumentSavingEnabled:YES];
    [webView setPreferences:webPreferences.get()];

    WebFrame *mainFrame = [webView mainFrame];

    [mainFrame loadRequest:[NSURLRequest requestWithURL:pagesDocumentURL]];
    Util::run(&isDone);
    WebThreadLock();

    NSUInteger expectedFileSize;
    RetainPtr<NSData> expectedFileData;
    RetainPtr<NSString> expectedFileName;
    RetainPtr<NSString> expectedFileType;
    RetainPtr<NSString> expectedMIMEType;
    readFile(pagesDocumentURL, expectedFileSize, expectedFileName, expectedFileType, expectedMIMEType, expectedFileData);

    NSDictionary *quickLookContent = mainFrame.dataSource._quickLookContent;
    NSString *filePath = quickLookContent[WebQuickLookFileNameKey];
    EXPECT_TRUE([NSFileManager.defaultManager fileExistsAtPath:filePath]);
    EXPECT_WK_STREQ(expectedFileName.get(), filePath.lastPathComponent);
    EXPECT_WK_STREQ(expectedFileType.get(), quickLookContent[WebQuickLookUTIKey]);

    NSDictionary *fileAttributes = [NSFileManager.defaultManager attributesOfItemAtPath:filePath error:nil];
    EXPECT_EQ(expectedFileSize, [fileAttributes[NSFileSize] unsignedIntegerValue]);
    
    EXPECT_TRUE([expectedFileData isEqualToData:[NSData dataWithContentsOfFile:filePath]]);

    isDone = false;
    [mainFrame loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
    Util::run(&isDone);
    WebThreadLock();

    EXPECT_NULL(mainFrame.dataSource._quickLookContent);
}

TEST(QuickLook, LoadFromMemoryCache)
{
    [TestProtocol registerWithScheme:@"http"];
    TestProtocol.additionalResponseHeaders = @{ @"Cache-Control" : @"max-age=3600" };

    auto webView = adoptNS([[TestWKWebView alloc] init]);
    [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://bundle-file/simple.html"]]];

    NSString * const contentTypeJavaScript = @"document.contentType";
    NSString * const simpleMIMEType = @"text/html";
    EXPECT_WK_STREQ(simpleMIMEType, [webView stringByEvaluatingJavaScript:contentTypeJavaScript]);

    NSURL * const pagesDocumentHTTPURL = [NSURL URLWithString:@"http://bundle-file/pages.pages"];
    [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:pagesDocumentHTTPURL]];
    EXPECT_WK_STREQ(pagesDocumentPreviewMIMEType, [webView stringByEvaluatingJavaScript:contentTypeJavaScript]);

    [webView synchronouslyGoBack];
    EXPECT_WK_STREQ(simpleMIMEType, [webView stringByEvaluatingJavaScript:contentTypeJavaScript]);

    [webView synchronouslyLoadRequest:[NSURLRequest requestWithURL:pagesDocumentHTTPURL]];
    EXPECT_WK_STREQ(pagesDocumentPreviewMIMEType, [webView stringByEvaluatingJavaScript:contentTypeJavaScript]);

    TestProtocol.additionalResponseHeaders = nil;
    [TestProtocol unregister];
}

#endif // PLATFORM(IOS_FAMILY)
