/*
 * Copyright (C) 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) || PLATFORM(IOS)

#import "DragAndDropSimulator.h"
#import "NSItemProviderAdditions.h"
#import "PencilKitTestSPI.h"
#import "PlatformUtilities.h"
#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import "WKWebViewConfigurationExtras.h"
#import <Contacts/Contacts.h>
#import <MapKit/MapKit.h>
#import <WebKit/WKPreferencesRefPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
#import <WebKit/WebArchive.h>
#import <WebKit/WebKitPrivate.h>
#import <wtf/RetainPtr.h>
#import <wtf/SoftLinking.h>

#if PLATFORM(IOS_FAMILY)
#import <MobileCoreServices/MobileCoreServices.h>
#endif

SOFT_LINK_FRAMEWORK(Contacts)
SOFT_LINK_CLASS(Contacts, CNMutableContact)

SOFT_LINK_FRAMEWORK(MapKit)
SOFT_LINK_CLASS(MapKit, MKMapItem)
SOFT_LINK_CLASS(MapKit, MKPlacemark)

@interface NSArray (AttachmentTestingHelpers)
- (_WKAttachment *)_attachmentWithName:(NSString *)name;
@end

@implementation NSArray (AttachmentTestingHelpers)
- (_WKAttachment *)_attachmentWithName:(NSString *)name
{
    for (_WKAttachment *attachment in self) {
        if ([attachment.info.name isEqualToString:name])
            return attachment;
    }
    return nil;
}
@end

#define USES_MODERN_ATTRIBUTED_STRING_CONVERSION ((PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000) || PLATFORM(MAC))

@interface AttachmentUpdateObserver : NSObject <WKUIDelegatePrivate>
@property (nonatomic, readonly) NSArray *inserted;
@property (nonatomic, readonly) NSArray *removed;
@property (nonatomic, readonly) NSArray *dataInvalidated;
@end

@implementation AttachmentUpdateObserver {
    RetainPtr<NSMutableArray<_WKAttachment *>> _inserted;
    RetainPtr<NSMutableArray<_WKAttachment *>> _removed;
    RetainPtr<NSMutableArray<_WKAttachment *>> _dataInvalidated;
    RetainPtr<NSMutableDictionary<NSString *, NSString *>> _identifierToSourceMap;
}

- (instancetype)init
{
    if (self = [super init]) {
        _inserted = adoptNS([[NSMutableArray alloc] init]);
        _removed = adoptNS([[NSMutableArray alloc] init]);
        _dataInvalidated = adoptNS([[NSMutableArray alloc] init]);
        _identifierToSourceMap = adoptNS([[NSMutableDictionary alloc] init]);
    }
    return self;
}

- (NSArray<_WKAttachment *> *)inserted
{
    return _inserted.get();
}

- (NSArray<_WKAttachment *> *)removed
{
    return _removed.get();
}

- (NSArray<_WKAttachment *> *)dataInvalidated
{
    return _dataInvalidated.get();
}

- (NSString *)sourceForIdentifier:(NSString *)identifier
{
    return [_identifierToSourceMap objectForKey:identifier];
}

- (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment withSource:(NSString *)source
{
    [_inserted addObject:attachment];
    if (source)
        [_identifierToSourceMap setObject:source forKey:attachment.uniqueIdentifier];
}

- (void)_webView:(WKWebView *)webView didRemoveAttachment:(_WKAttachment *)attachment
{
    [_removed addObject:attachment];
}

- (void)_webView:(WKWebView *)webView didInvalidateDataForAttachment:(_WKAttachment *)attachment
{
    [_dataInvalidated addObject:attachment];
}

@end

namespace TestWebKitAPI {

class ObserveAttachmentUpdatesForScope {
public:
    ObserveAttachmentUpdatesForScope(TestWKWebView *webView)
        : m_webView(webView)
    {
        m_previousDelegate = webView.UIDelegate;
        m_observer = adoptNS([[AttachmentUpdateObserver alloc] init]);
        webView.UIDelegate = m_observer.get();
    }

    ~ObserveAttachmentUpdatesForScope()
    {
        [m_webView setUIDelegate:m_previousDelegate.get()];
    }

    AttachmentUpdateObserver *observer() const { return m_observer.get(); }

    void expectAttachmentUpdates(NSArray<_WKAttachment *> *removed, NSArray<_WKAttachment *> *inserted)
    {
        BOOL removedAttachmentsMatch = [[NSSet setWithArray:observer().removed] isEqual:[NSSet setWithArray:removed]];
        if (!removedAttachmentsMatch)
            NSLog(@"Expected removed attachments: %@ to match %@.", observer().removed, removed);
        EXPECT_TRUE(removedAttachmentsMatch);

        BOOL insertedAttachmentsMatch = [[NSSet setWithArray:observer().inserted] isEqual:[NSSet setWithArray:inserted]];
        if (!insertedAttachmentsMatch)
            NSLog(@"Expected inserted attachments: %@ to match %@.", observer().inserted, inserted);
        EXPECT_TRUE(insertedAttachmentsMatch);
    }

    void expectAttachmentInvalidation(NSArray<_WKAttachment *> *dataInvalidated)
    {
        BOOL invalidatedAttachmentsMatch = [[NSSet setWithArray:observer().dataInvalidated] isEqual:[NSSet setWithArray:dataInvalidated]];
        if (!invalidatedAttachmentsMatch)
            NSLog(@"Expected attachments with invalidated data: %@ to match %@.", observer().dataInvalidated, dataInvalidated);
        EXPECT_TRUE(invalidatedAttachmentsMatch);
    }

    void expectSourceForIdentifier(NSString *expectedSource, NSString *identifier)
    {
        NSString *observedSource = [observer() sourceForIdentifier:identifier];
        BOOL success = observedSource == expectedSource || [observedSource isEqualToString:expectedSource];
        EXPECT_TRUE(success);
        if (!success)
            NSLog(@"Expected source: %@ but observed: %@", expectedSource, observedSource);
    }

private:
    RetainPtr<AttachmentUpdateObserver> m_observer;
    RetainPtr<TestWKWebView> m_webView;
    RetainPtr<id> m_previousDelegate;
};

}

@interface TestWKWebView (AttachmentTesting)
@end

static NSString *attachmentEditingTestMarkup = @"<meta name='viewport' content='width=device-width, initial-scale=1'>"
    "<script>focus = () => document.body.focus()</script>"
    "<body onload=focus() contenteditable></body>";

static RetainPtr<TestWKWebView> webViewForTestingAttachments(CGSize webViewSize, WKWebViewConfiguration *configuration)
{
    configuration._attachmentElementEnabled = YES;
    configuration._editableImagesEnabled = YES;
    WKPreferencesSetCustomPasteboardDataEnabled((__bridge WKPreferencesRef)[configuration preferences], YES);

    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, webViewSize.width, webViewSize.height) configuration:configuration]);
    [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup];

    return webView;
}

static RetainPtr<TestWKWebView> webViewForTestingAttachments(CGSize webViewSize)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    return webViewForTestingAttachments(webViewSize, configuration.get());
}

static RetainPtr<TestWKWebView> webViewForTestingAttachments()
{
    return webViewForTestingAttachments(CGSizeMake(500, 500));
}

static NSData *testZIPData()
{
    NSURL *zipFileURL = [[NSBundle mainBundle] URLForResource:@"compressed-files" withExtension:@"zip" subdirectory:@"TestWebKitAPI.resources"];
    return [NSData dataWithContentsOfURL:zipFileURL];
}

static NSData *testHTMLData()
{
    return [@"<a href='#'>This is some HTML data</a>" dataUsingEncoding:NSUTF8StringEncoding];
}

static NSURL *testImageFileURL()
{
    return [[NSBundle mainBundle] URLForResource:@"icon" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"];
}

static NSData *testImageData()
{
    return [NSData dataWithContentsOfURL:testImageFileURL()];
}

static NSURL *testGIFFileURL()
{
    return [[NSBundle mainBundle] URLForResource:@"apple" withExtension:@"gif" subdirectory:@"TestWebKitAPI.resources"];
}

static NSData *testGIFData()
{
    return [NSData dataWithContentsOfURL:testGIFFileURL()];
}

static NSURL *testPDFFileURL()
{
    return [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"pdf" subdirectory:@"TestWebKitAPI.resources"];
}

static NSData *testPDFData()
{
    return [NSData dataWithContentsOfURL:testPDFFileURL()];
}

@implementation TestWKWebView (AttachmentTesting)

- (_WKAttachment *)synchronouslyInsertAttachmentWithFileWrapper:(NSFileWrapper *)fileWrapper contentType:(NSString *)contentType
{
    __block bool done = false;
    RetainPtr<_WKAttachment> attachment = [self _insertAttachmentWithFileWrapper:fileWrapper contentType:contentType completion:^(BOOL) {
        done = true;
    }];
    TestWebKitAPI::Util::run(&done);
    return attachment.autorelease();
}

- (_WKAttachment *)synchronouslyInsertAttachmentWithFilename:(NSString *)filename contentType:(NSString *)contentType data:(NSData *)data
{
    __block bool done = false;
    auto fileWrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data]);
    if (filename)
        [fileWrapper setPreferredFilename:filename];
    RetainPtr<_WKAttachment> attachment = [self _insertAttachmentWithFileWrapper:fileWrapper.get() contentType:contentType completion:^(BOOL) {
        done = true;
    }];
    TestWebKitAPI::Util::run(&done);
    return attachment.autorelease();
}

- (NSArray<NSValue *> *)allBoundingClientRects:(NSString *)querySelector
{
    auto rects = adoptNS([[NSMutableArray alloc] init]);
    bool doneEvaluatingScript = false;
    NSString *script = [NSString stringWithFormat:@"Array.from(document.querySelectorAll('%@')).map(e => { const r = e.getBoundingClientRect(); return [r.left, r.top, r.width, r.height]; })", querySelector];
    [self evaluateJavaScript:script completionHandler:[rects, &doneEvaluatingScript] (NSArray<NSArray<NSNumber *> *> *result, NSError *) {
        for (NSArray<NSNumber *> *rectInfo in result) {
#if PLATFORM(IOS_FAMILY)
            [rects addObject:[NSValue valueWithCGRect:CGRectMake(rectInfo[0].floatValue, rectInfo[1].floatValue, rectInfo[2].floatValue, rectInfo[3].floatValue)]];
#else
            [rects addObject:[NSValue valueWithRect:NSMakeRect(rectInfo[0].floatValue, rectInfo[1].floatValue, rectInfo[2].floatValue, rectInfo[3].floatValue)]];
#endif
        }
        doneEvaluatingScript = true;
    }];
    TestWebKitAPI::Util::run(&doneEvaluatingScript);
    return rects.autorelease();
}

- (CGPoint)attachmentElementMidPoint
{
    __block CGPoint midPoint;
    __block bool doneEvaluatingScript = false;
    [self evaluateJavaScript:@"r = document.querySelector('attachment').getBoundingClientRect(); [r.left + r.width / 2, r.top + r.height / 2]" completionHandler:^(NSArray<NSNumber *> *result, NSError *) {
        midPoint = CGPointMake(result.firstObject.floatValue, result.lastObject.floatValue);
        doneEvaluatingScript = true;
    }];
    TestWebKitAPI::Util::run(&doneEvaluatingScript);
    return midPoint;
}

- (CGSize)attachmentElementSize
{
    __block CGSize size;
    __block bool doneEvaluatingScript = false;
    [self evaluateJavaScript:@"r = document.querySelector('attachment').getBoundingClientRect(); [r.width, r.height]" completionHandler:^(NSArray<NSNumber *> *sizeResult, NSError *) {
        size = CGSizeMake(sizeResult.firstObject.floatValue, sizeResult.lastObject.floatValue);
        doneEvaluatingScript = true;
    }];
    TestWebKitAPI::Util::run(&doneEvaluatingScript);
    return size;
}

- (CGSize)imageElementSize
{
    __block CGSize size;
    __block bool doneEvaluatingScript = false;
    [self evaluateJavaScript:@"r = document.querySelector('img').getBoundingClientRect(); [r.width, r.height]" completionHandler:^(NSArray<NSNumber *> *sizeResult, NSError *) {
        size = CGSizeMake(sizeResult.firstObject.floatValue, sizeResult.lastObject.floatValue);
        doneEvaluatingScript = true;
    }];
    TestWebKitAPI::Util::run(&doneEvaluatingScript);
    return size;
}

- (void)waitForImageElementSizeToBecome:(CGSize)expectedSize
{
    while ([[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]]) {
        if (CGSizeEqualToSize(self.imageElementSize, expectedSize))
            break;
    }
}

- (BOOL)hasAttribute:(NSString *)attributeName forQuerySelector:(NSString *)querySelector
{
    return [self stringByEvaluatingJavaScript:[NSString stringWithFormat:@"document.querySelector('%@').hasAttribute('%@')", querySelector, attributeName]].boolValue;
}

- (NSString *)valueOfAttribute:(NSString *)attributeName forQuerySelector:(NSString *)querySelector
{
    return [self stringByEvaluatingJavaScript:[NSString stringWithFormat:@"document.querySelector('%@').getAttribute('%@')", querySelector, attributeName]];
}

- (void)expectUpdatesAfterCommand:(NSString *)command withArgument:(NSString *)argument expectedRemovals:(NSArray<_WKAttachment *> *)removed expectedInsertions:(NSArray<_WKAttachment *> *)inserted
{
    TestWebKitAPI::ObserveAttachmentUpdatesForScope observer(self);
    EXPECT_TRUE([self _synchronouslyExecuteEditCommand:command argument:argument]);
    observer.expectAttachmentUpdates(removed, inserted);
}

@end

@implementation NSData (AttachmentTesting)

- (NSString *)shortDescription
{
    return [NSString stringWithFormat:@"<%tu bytes>", self.length];
}

@end

@implementation _WKAttachment (AttachmentTesting)

- (void)synchronouslySetFileWrapper:(NSFileWrapper *)fileWrapper newContentType:(NSString *)newContentType error:(NSError **)error
{
    __block RetainPtr<NSError> resultError;
    __block bool done = false;

    [self setFileWrapper:fileWrapper contentType:newContentType completion:^(NSError *error) {
        resultError = error;
        done = true;
    }];

    TestWebKitAPI::Util::run(&done);

    if (error)
        *error = resultError.autorelease();
}

- (void)synchronouslySetData:(NSData *)data newContentType:(NSString *)newContentType newFilename:(NSString *)newFilename error:(NSError **)error
{
    __block RetainPtr<NSError> resultError;
    __block bool done = false;
    auto fileWrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data]);
    if (newFilename)
        [fileWrapper setPreferredFilename:newFilename];

    [self setFileWrapper:fileWrapper.get() contentType:newContentType completion:^(NSError *error) {
        resultError = error;
        done = true;
    }];

    TestWebKitAPI::Util::run(&done);

    if (error)
        *error = resultError.autorelease();
}

- (void)expectRequestedDataToBe:(NSData *)expectedData
{
    NSError *requestError = nil;
    _WKAttachmentInfo *info = self.info;

    BOOL observedDataIsEqualToExpectedData = info.data == expectedData || [info.data isEqualToData:expectedData];
    EXPECT_TRUE(observedDataIsEqualToExpectedData);
    if (!observedDataIsEqualToExpectedData) {
        NSLog(@"Expected data: %@ but observed: %@ for %@", [expectedData shortDescription], [info.data shortDescription], self);
        NSLog(@"Observed error: %@ while reading data for %@", requestError, self);
    }
}

@end

static void runTestWithTemporaryFolder(void(^runTest)(NSURL *folderURL))
{
    NSFileManager *defaultManager = [NSFileManager defaultManager];
    auto temporaryFolder = retainPtr([NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"folder-%@", NSUUID.UUID]] isDirectory:YES]);
    [defaultManager removeItemAtURL:temporaryFolder.get() error:nil];
    [defaultManager createDirectoryAtURL:temporaryFolder.get() withIntermediateDirectories:NO attributes:nil error:nil];
    [testImageData() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"image.png" isDirectory:NO] atomically:YES];
    [testZIPData() writeToURL:[temporaryFolder.get() URLByAppendingPathComponent:@"archive.zip" isDirectory:NO] atomically:YES];
    @try {
        runTest(temporaryFolder.get());
    } @finally {
        [[NSFileManager defaultManager] removeItemAtURL:temporaryFolder.get() error:nil];
    }
}

#if PLATFORM(IOS_FAMILY)

static void runTestWithTemporaryImageFile(NSString *fileName, void(^runTest)(NSURL *fileURL))
{
    NSFileManager *defaultManager = [NSFileManager defaultManager];
    auto temporaryFilePath = retainPtr([NSTemporaryDirectory() stringByAppendingPathComponent:fileName]);
    auto temporaryFileURL = retainPtr([NSURL fileURLWithPath:temporaryFilePath.get()]);
    [defaultManager removeItemAtURL:temporaryFileURL.get() error:nil];
    [testImageData() writeToFile:temporaryFilePath.get() atomically:YES];
    @try {
        runTest(temporaryFileURL.get());
    } @finally {
        [defaultManager removeItemAtURL:temporaryFileURL.get() error:nil];
    }
}

#endif // PLATFORM(IOS_FAMILY)

static void simulateFolderDragWithURL(DragAndDropSimulator *simulator, NSURL *folderURL)
{
#if PLATFORM(MAC)
    [simulator writePromisedFiles:@[ folderURL ]];
#else
    auto folderProvider = adoptNS([[NSItemProvider alloc] init]);
    [folderProvider setSuggestedName:folderURL.lastPathComponent];
    [folderProvider setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
    [folderProvider registerFileRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeFolder fileOptions:0 visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[protectedFolderURL = retainPtr(folderURL)] (void(^completion)(NSURL *, BOOL, NSError *)) -> NSProgress * {
        completion(protectedFolderURL.get(), NO, nil);
        return nil;
    }];
    simulator.externalItemProviders = @[ folderProvider.get() ];
#endif
}

#pragma mark - Platform testing helper functions

#if PLATFORM(MAC)

BOOL isCompletelyTransparent(NSImage *image)
{
    auto representation = adoptNS([[NSBitmapImageRep alloc] initWithData:image.TIFFRepresentation]);
    for (int row = 0; row < image.size.height; ++row) {
        for (int column = 0; column < image.size.width; ++column) {
            if ([representation colorAtX:column y:row].alphaComponent)
                return false;
        }
    }
    return true;
}

#endif

#if PLATFORM(IOS_FAMILY)

typedef void(^ItemProviderDataLoadHandler)(NSData *, NSError *);

@implementation NSItemProvider (AttachmentTesting)

- (void)registerData:(NSData *)data type:(NSString *)type
{
    [self registerDataRepresentationForTypeIdentifier:type visibility:NSItemProviderRepresentationVisibilityAll loadHandler:[protectedData = retainPtr(data)] (ItemProviderDataLoadHandler completionHandler) -> NSProgress * {
        completionHandler(protectedData.get(), nil);
        return nil;
    }];
}

- (void)expectType:(NSString *)type withData:(NSData *)expectedData
{
    BOOL containsType = [self.registeredTypeIdentifiers containsObject:type];
    EXPECT_TRUE(containsType);
    if (!containsType) {
        NSLog(@"Expected: %@ to contain %@", self, type);
        return;
    }

    __block bool done = false;
    [self loadDataRepresentationForTypeIdentifier:type completionHandler:^(NSData *observedData, NSError *error) {
        EXPECT_TRUE([observedData isEqualToData:expectedData]);
        if (![observedData isEqualToData:expectedData])
            NSLog(@"Expected data: <%tu bytes> to be equal to data: <%tu bytes>", observedData.length, expectedData.length);
        EXPECT_TRUE(!error);
        if (error)
            NSLog(@"Encountered error when loading data: %@", error);
        done = true;
    }];
    TestWebKitAPI::Util::run(&done);
}

@end

#endif // PLATFORM(IOS_FAMILY)

void platformCopyRichTextWithMultipleAttachments()
{
    auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(__bridge NSString *)kUTTypePNG]);
    auto pdf = adoptNS([[NSTextAttachment alloc] initWithData:testPDFData() ofType:(__bridge NSString *)kUTTypePDF]);
    auto zip = adoptNS([[NSTextAttachment alloc] initWithData:testZIPData() ofType:(__bridge NSString *)kUTTypeZipArchive]);

    auto richText = adoptNS([[NSMutableAttributedString alloc] init]);
    [richText appendAttributedString:[NSAttributedString attributedStringWithAttachment:image.get()]];
    [richText appendAttributedString:[NSAttributedString attributedStringWithAttachment:pdf.get()]];
    [richText appendAttributedString:[NSAttributedString attributedStringWithAttachment:zip.get()]];

#if PLATFORM(MAC)
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    [pasteboard writeObjects:@[ richText.get() ]];
#elif PLATFORM(IOS_FAMILY)
    auto item = adoptNS([[NSItemProvider alloc] init]);
    [item registerObject:richText.get() visibility:NSItemProviderRepresentationVisibilityAll];
    [UIPasteboard generalPasteboard].itemProviders = @[ item.get() ];
#endif
}

void platformCopyRichTextWithImage()
{
    auto richText = adoptNS([[NSMutableAttributedString alloc] init]);
    auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(__bridge NSString *)kUTTypePNG]);

    [richText appendAttributedString:[[[NSAttributedString alloc] initWithString:@"Lorem ipsum "] autorelease]];
    [richText appendAttributedString:[NSAttributedString attributedStringWithAttachment:image.get()]];
    [richText appendAttributedString:[[[NSAttributedString alloc] initWithString:@" dolor sit amet."] autorelease]];

#if PLATFORM(MAC)
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    [pasteboard writeObjects:@[ richText.get() ]];
#elif PLATFORM(IOS_FAMILY)
    auto item = adoptNS([[NSItemProvider alloc] init]);
    [item registerObject:richText.get() visibility:NSItemProviderRepresentationVisibilityAll];
    [UIPasteboard generalPasteboard].itemProviders = @[ item.get() ];
#endif
}

void platformCopyPNG()
{
#if PLATFORM(MAC)
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard declareTypes:@[NSPasteboardTypePNG] owner:nil];
    [pasteboard setData:testImageData() forType:NSPasteboardTypePNG];
#elif PLATFORM(IOS_FAMILY)
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    auto item = adoptNS([[NSItemProvider alloc] init]);
    [item setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
    [item registerData:testImageData() type:(__bridge NSString *)kUTTypePNG];
    pasteboard.itemProviders = @[ item.get() ];
#endif
}

#if PLATFORM(MAC)
typedef NSImage PlatformImage;
#else
typedef UIImage PlatformImage;
#endif

PlatformImage *platformImageWithData(NSData *data)
{
#if PLATFORM(MAC)
    return [[[NSImage alloc] initWithData:data] autorelease];
#else
    return [UIImage imageWithData:data];
#endif
}

@interface FileWrapper : NSFileWrapper
@end

@implementation FileWrapper
@end

namespace TestWebKitAPI {

#pragma mark - Platform-agnostic tests

TEST(WKAttachmentTests, AttachmentElementInsertion)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> firstAttachment;
    RetainPtr<_WKAttachment> secondAttachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        // Use the given content type for the attachment element's type.
        firstAttachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo" contentType:@"text/html" data:testHTMLData()];
        EXPECT_WK_STREQ(@"foo", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"text/html", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"38 bytes", [webView valueOfAttribute:@"subtitle" forQuerySelector:@"attachment"]);
        observer.expectAttachmentUpdates(@[ ], @[ firstAttachment.get() ]);
    }

    _WKAttachmentInfo *info = [firstAttachment info];
    EXPECT_TRUE([info.data isEqualToData:testHTMLData()]);
    EXPECT_TRUE([info.contentType isEqualToString:@"text/html"]);
    EXPECT_TRUE([info.name isEqualToString:@"foo"]);
    EXPECT_EQ(info.filePath.length, 0U);

    {
        ObserveAttachmentUpdatesForScope scope(webView.get());
        // Since no content type is explicitly specified, compute it from the file extension.
        [webView _executeEditCommand:@"DeleteBackward" argument:nil completion:nil];
        secondAttachment = [webView synchronouslyInsertAttachmentWithFilename:@"bar.png" contentType:nil data:testImageData()];
        EXPECT_WK_STREQ(@"bar.png", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"image/png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"37 KB", [webView valueOfAttribute:@"subtitle" forQuerySelector:@"attachment"]);
        scope.expectAttachmentUpdates(@[ firstAttachment.get() ], @[ secondAttachment.get() ]);
    }

    [firstAttachment expectRequestedDataToBe:testHTMLData()];
    [secondAttachment expectRequestedDataToBe:testImageData()];
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentbloburl" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentpath" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentid" forQuerySelector:@"attachment"]);
}

TEST(WKAttachmentTests, AttachmentUpdatesWhenInsertingAndDeletingNewline)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
        observer.expectAttachmentUpdates(@[ ], @[attachment.get()]);
    }
    [webView expectUpdatesAfterCommand:@"InsertParagraph" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [webView expectUpdatesAfterCommand:@"DeleteBackward" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [webView stringByEvaluatingJavaScript:@"getSelection().collapse(document.body)"];
    [webView expectUpdatesAfterCommand:@"InsertParagraph" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];

    [webView expectUpdatesAfterCommand:@"DeleteBackward" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];

    _WKAttachmentInfo *info = [attachment info];
    EXPECT_TRUE([info.data isEqualToData:testHTMLData()]);
    EXPECT_TRUE([info.contentType isEqualToString:@"text/plain"]);
    EXPECT_TRUE([info.name isEqualToString:@"foo.txt"]);
    EXPECT_EQ(info.filePath.length, 0U);

    [webView expectUpdatesAfterCommand:@"DeleteForward" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[]];
    [attachment expectRequestedDataToBe:testHTMLData()];
}

TEST(WKAttachmentTests, AttachmentUpdatesWhenUndoingAndRedoing)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<NSData> htmlData = testHTMLData();
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
        observer.expectAttachmentUpdates(@[ ], @[attachment.get()]);
    }
    [webView expectUpdatesAfterCommand:@"Undo" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[]];
    [attachment expectRequestedDataToBe:htmlData.get()];

    [webView expectUpdatesAfterCommand:@"Redo" withArgument:nil expectedRemovals:@[] expectedInsertions:@[attachment.get()]];
    [attachment expectRequestedDataToBe:htmlData.get()];

    [webView expectUpdatesAfterCommand:@"DeleteBackward" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[]];
    [attachment expectRequestedDataToBe:htmlData.get()];

    [webView expectUpdatesAfterCommand:@"Undo" withArgument:nil expectedRemovals:@[] expectedInsertions:@[attachment.get()]];
    [attachment expectRequestedDataToBe:htmlData.get()];

    [webView expectUpdatesAfterCommand:@"Redo" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[]];
    [attachment expectRequestedDataToBe:htmlData.get()];
}

TEST(WKAttachmentTests, AttachmentUpdatesWhenChangingFontStyles)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> attachment;
    [webView _synchronouslyExecuteEditCommand:@"InsertText" argument:@"Hello"];
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }
    [webView expectUpdatesAfterCommand:@"InsertText" withArgument:@"World" expectedRemovals:@[] expectedInsertions:@[]];
    [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
    [webView expectUpdatesAfterCommand:@"ToggleBold" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [webView expectUpdatesAfterCommand:@"ToggleItalic" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [webView expectUpdatesAfterCommand:@"ToggleUnderline" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [attachment expectRequestedDataToBe:testHTMLData()];
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentbloburl" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentpath" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentid" forQuerySelector:@"attachment"]);

    // Inserting text should delete the current selection, removing the attachment in the process.
    [webView expectUpdatesAfterCommand:@"InsertText" withArgument:@"foo" expectedRemovals:@[attachment.get()] expectedInsertions:@[]];
    [attachment expectRequestedDataToBe:testHTMLData()];
}

TEST(WKAttachmentTests, AttachmentUpdatesWhenInsertingLists)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }
    [webView expectUpdatesAfterCommand:@"InsertOrderedList" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    // This edit command behaves more like a "toggle", and will actually break us out of the list we just inserted.
    [webView expectUpdatesAfterCommand:@"InsertOrderedList" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [webView expectUpdatesAfterCommand:@"InsertUnorderedList" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [webView expectUpdatesAfterCommand:@"InsertUnorderedList" withArgument:nil expectedRemovals:@[] expectedInsertions:@[]];
    [attachment expectRequestedDataToBe:testHTMLData()];
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentbloburl" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentpath" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentid" forQuerySelector:@"attachment"]);
}

TEST(WKAttachmentTests, AttachmentUpdatesWhenInsertingRichMarkup)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"InsertHTML" argument:@"<div><strong><attachment src='cid:123-4567' title='a'></attachment></strong></div>"];
        attachment = observer.observer().inserted[0];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
        observer.expectSourceForIdentifier(@"cid:123-4567", [attachment uniqueIdentifier]);
    }
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentbloburl" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentpath" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentid" forQuerySelector:@"attachment"]);
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').remove()"];
        [webView waitForNextPresentationUpdate];
        observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
    }
    [attachment expectRequestedDataToBe:nil];
}

TEST(WKAttachmentTests, AttachmentUpdatesWhenCuttingAndPasting)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"foo.txt" contentType:@"text/plain" data:testHTMLData()];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }
    [attachment expectRequestedDataToBe:testHTMLData()];
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
    [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Cut" argument:nil];
        observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
    }
    [attachment expectRequestedDataToBe:testHTMLData()];
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }
    [attachment expectRequestedDataToBe:testHTMLData()];
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentbloburl" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentpath" forQuerySelector:@"attachment"]);
    EXPECT_FALSE([webView hasAttribute:@"webkitattachmentid" forQuerySelector:@"attachment"]);
}

TEST(WKAttachmentTests, AttachmentDataForEmptyFile)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"empty.txt" contentType:@"text/plain" data:[NSData data]];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }
    [attachment expectRequestedDataToBe:[NSData data]];
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
    {
        ObserveAttachmentUpdatesForScope scope(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        scope.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
    }
    [attachment expectRequestedDataToBe:[NSData data]];
}

TEST(WKAttachmentTests, DropFolderAsAttachmentAndMoveByDragging)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAttachmentElementEnabled:YES];

    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
    [[simulator webView] synchronouslyLoadHTMLString:attachmentEditingTestMarkup];

    runTestWithTemporaryFolder([simulator] (NSURL *folderURL) {
        simulateFolderDragWithURL(simulator.get(), folderURL);
        [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)];

        TestWKWebView *webView = [simulator webView];
        auto attachment = retainPtr([simulator insertedAttachments].firstObject);
#if PLATFORM(IOS_FAMILY)
        NSString *expectedType = (__bridge NSString *)kUTTypeFolder;
#else
        NSString *expectedType = (__bridge NSString *)kUTTypeDirectory;
#endif
        EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').uniqueIdentifier"]);
        EXPECT_WK_STREQ(expectedType, [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(folderURL.lastPathComponent, [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);

        NSFileWrapper *image = [attachment info].fileWrapper.fileWrappers[@"image.png"];
        NSFileWrapper *archive = [attachment info].fileWrapper.fileWrappers[@"archive.zip"];
        EXPECT_TRUE([image.regularFileContents isEqualToData:testImageData()]);
        EXPECT_TRUE([archive.regularFileContents isEqualToData:testZIPData()]);

        [webView evaluateJavaScript:@"getSelection().collapseToEnd()" completionHandler:nil];
        [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];
        [webView _executeEditCommand:@"InsertHTML" argument:@"<em>foo</em>" completion:nil];
        [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];

        [webView expectElementTag:@"ATTACHMENT" toComeBefore:@"EM"];
        [simulator clearExternalDragInformation];
        [simulator runFrom:webView.attachmentElementMidPoint to:CGPointMake(300, 300)];
        [webView expectElementTag:@"EM" toComeBefore:@"ATTACHMENT"];
    });
}

TEST(WKAttachmentTests, InsertFolderAndFileWithUnknownExtension)
{
    auto webView = webViewForTestingAttachments();
    auto file = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testHTMLData()]);
    [file setPreferredFilename:@"test.foobar"];
    auto image = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testImageData()]);
    auto document = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testPDFData()]);
    auto folder = adoptNS([[NSFileWrapper alloc] initDirectoryWithFileWrappers:@{ @"image.png": image.get(), @"document.pdf": document.get() }]);
    [folder setPreferredFilename:@"folder"];

    RetainPtr<_WKAttachment> firstAttachment;
    RetainPtr<_WKAttachment> secondAttachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        firstAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:file.get() contentType:nil];
        observer.expectAttachmentUpdates(@[ ], @[ firstAttachment.get() ]);
    }
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        secondAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:folder.get() contentType:nil];
        observer.expectAttachmentUpdates(@[ ], @[ secondAttachment.get() ]);
    }

    auto checkAttachmentConsistency = [webView, file, folder] (_WKAttachment *expectedFileAttachment, _WKAttachment *expectedFolderAttachment) {
        [webView expectElementCount:2 querySelector:@"ATTACHMENT"];
        EXPECT_TRUE(UTTypeConformsTo((__bridge CFStringRef)[webView valueOfAttribute:@"type" forQuerySelector:@"attachment[title=folder]"], kUTTypeDirectory));
        EXPECT_TRUE(UTTypeConformsTo((__bridge CFStringRef)[webView valueOfAttribute:@"type" forQuerySelector:@"attachment[title^=test]"], kUTTypeData));
        EXPECT_WK_STREQ(expectedFileAttachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment[title^=test]').uniqueIdentifier"]);
        EXPECT_WK_STREQ(expectedFolderAttachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment[title=folder]').uniqueIdentifier"]);
        EXPECT_TRUE([expectedFileAttachment.info.fileWrapper isEqual:file.get()]);
        EXPECT_TRUE([expectedFolderAttachment.info.fileWrapper isEqual:folder.get()]);
    };

    checkAttachmentConsistency(firstAttachment.get(), secondAttachment.get());

    {
        // Swap the two attachments' file wrappers without creating or destroying attachment elements.
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [firstAttachment synchronouslySetFileWrapper:folder.get() newContentType:nil error:nil];
        [secondAttachment synchronouslySetFileWrapper:file.get() newContentType:nil error:nil];
        observer.expectAttachmentUpdates(@[ ], @[ ]);
    }

    checkAttachmentConsistency(secondAttachment.get(), firstAttachment.get());
}

TEST(WKAttachmentTests, ChangeAttachmentDataAndFileInformation)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> attachment;
    {
        RetainPtr<NSData> pdfData = testPDFData();
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"test.pdf" contentType:@"application/pdf" data:pdfData.get()];
        [attachment expectRequestedDataToBe:pdfData.get()];
        EXPECT_WK_STREQ(@"test.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
        observer.expectAttachmentUpdates(@[ ], @[attachment.get()]);
    }
    {
        RetainPtr<NSData> imageData = testImageData();
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [attachment synchronouslySetData:imageData.get() newContentType:@"image/png" newFilename:@"icon.png" error:nil];
        [attachment expectRequestedDataToBe:imageData.get()];
        EXPECT_WK_STREQ(@"icon.png", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"image/png", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
        observer.expectAttachmentUpdates(@[ ], @[ ]);
    }
    {
        RetainPtr<NSData> textData = [@"Hello world" dataUsingEncoding:NSUTF8StringEncoding];
        ObserveAttachmentUpdatesForScope observer(webView.get());
        // The new content type should be inferred from the file name.
        [attachment synchronouslySetData:textData.get() newContentType:nil newFilename:@"foo.txt" error:nil];
        [attachment expectRequestedDataToBe:textData.get()];
        EXPECT_WK_STREQ(@"foo.txt", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"text/plain", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
        observer.expectAttachmentUpdates(@[ ], @[ ]);
    }
    {
        RetainPtr<NSData> htmlData = testHTMLData();
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [attachment synchronouslySetData:htmlData.get() newContentType:@"text/html" newFilename:@"bar" error:nil];
        [attachment expectRequestedDataToBe:htmlData.get()];
        EXPECT_WK_STREQ(@"bar", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
        EXPECT_WK_STREQ(@"text/html", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
        observer.expectAttachmentUpdates(@[ ], @[ ]);
    }
    [webView expectUpdatesAfterCommand:@"DeleteBackward" withArgument:nil expectedRemovals:@[attachment.get()] expectedInsertions:@[ ]];
}

TEST(WKAttachmentTests, RemoveNewlinesBeforePastedImage)
{
    platformCopyPNG();

    RetainPtr<_WKAttachment> attachment;
    auto webView = webViewForTestingAttachments();
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(1U, observer.observer().inserted.count);
        attachment = observer.observer().inserted[0];
    }

    auto size = platformImageWithData([attachment info].data).size;
    EXPECT_EQ(215., size.width);
    EXPECT_EQ(174., size.height);
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);

    [webView stringByEvaluatingJavaScript:@"getSelection().collapse(document.body, 0)"];
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];
        observer.expectAttachmentUpdates(@[ ], @[ ]);
        [webView expectElementTagsInOrder:@[ @"BR", @"BR", @"IMG" ]];
    }
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        observer.expectAttachmentUpdates(@[ ], @[ ]);
        [webView expectElementCount:0 querySelector:@"BR"];
    }
}

TEST(WKAttachmentTests, CutAndPastePastedImage)
{
    platformCopyPNG();

    RetainPtr<_WKAttachment> attachment;
    auto webView = webViewForTestingAttachments();
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(1U, observer.observer().inserted.count);
        attachment = observer.observer().inserted[0];
    }
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"Cut" argument:nil];
        observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
    }
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }
}

TEST(WKAttachmentTests, MovePastedImageByDragging)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAttachmentElementEnabled:YES];
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
    TestWKWebView *webView = [simulator webView];
    [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup];

    platformCopyPNG();
    [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
    [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];
    [webView _executeEditCommand:@"InsertHTML" argument:@"<strong>text</strong>" completion:nil];
    [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];
    [webView expectElementTag:@"IMG" toComeBefore:@"STRONG"];
    [webView expectElementCount:1 querySelector:@"IMG"];

    // Drag the attachment element to somewhere below the strong text.
    [simulator runFrom:CGPointMake(50, 50) to:CGPointMake(50, 350)];

    [webView expectElementTag:@"STRONG" toComeBefore:@"IMG"];
    [webView expectElementCount:1 querySelector:@"IMG"];
    EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count);

    [simulator endDataTransfer];
}

TEST(WKAttachmentTests, InsertPastedAttributedStringContainingImage)
{
    auto webView = webViewForTestingAttachments();
    platformCopyRichTextWithImage();

    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(0U, observer.observer().removed.count);
        EXPECT_EQ(1U, observer.observer().inserted.count);
        attachment = observer.observer().inserted[0];
    }

    [attachment expectRequestedDataToBe:testImageData()];
    EXPECT_WK_STREQ("Lorem ipsum  dolor sit amet.", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]);
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);

    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
    }
}

TEST(WKAttachmentTests, InsertPastedAttributedStringContainingMultipleAttachments)
{
    auto webView = webViewForTestingAttachments();
    platformCopyRichTextWithMultipleAttachments();

    RetainPtr<_WKAttachment> imageAttachment;
    RetainPtr<_WKAttachment> zipAttachment;
    RetainPtr<_WKAttachment> pdfAttachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(0U, observer.observer().removed.count);
        EXPECT_EQ(3U, observer.observer().inserted.count);
        for (_WKAttachment *attachment in observer.observer().inserted) {
            NSData *data = attachment.info.data;
            if ([data isEqualToData:testZIPData()])
                zipAttachment = attachment;
            else if ([data isEqualToData:testPDFData()])
                pdfAttachment = attachment;
            else if ([data isEqualToData:testImageData()])
                imageAttachment = attachment;
        }
    }

    EXPECT_TRUE(zipAttachment && imageAttachment && pdfAttachment);
    [webView expectElementCount:2 querySelector:@"ATTACHMENT"];
    [webView expectElementCount:1 querySelector:@"IMG"];
    EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);

    NSString *zipAttachmentType = [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"];
#if USES_MODERN_ATTRIBUTED_STRING_CONVERSION
    EXPECT_WK_STREQ("application/zip", zipAttachmentType);
#else
    EXPECT_WK_STREQ("application/octet-stream", zipAttachmentType);
#endif

    EXPECT_WK_STREQ([imageAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
    EXPECT_WK_STREQ([pdfAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].uniqueIdentifier"]);
    EXPECT_WK_STREQ([zipAttachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].uniqueIdentifier"]);

    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        NSArray<_WKAttachment *> *removedAttachments = [observer.observer() removed];
        EXPECT_EQ(3U, removedAttachments.count);
        EXPECT_TRUE([removedAttachments containsObject:zipAttachment.get()]);
        EXPECT_TRUE([removedAttachments containsObject:imageAttachment.get()]);
        EXPECT_TRUE([removedAttachments containsObject:pdfAttachment.get()]);
    }
}

TEST(WKAttachmentTests, DoNotInsertDataURLImagesAsAttachments)
{
    auto webContentSourceView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]);
    [webContentSourceView synchronouslyLoadTestPageNamed:@"apple-data-url"];
    [webContentSourceView selectAll:nil];
    [webContentSourceView _synchronouslyExecuteEditCommand:@"Copy" argument:nil];

    auto webView = webViewForTestingAttachments();
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(0U, observer.observer().inserted.count);
    }

    EXPECT_FALSE([webView stringByEvaluatingJavaScript:@"Boolean(document.querySelector('attachment'))"].boolValue);
    EXPECT_EQ(1990, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').src.length"].integerValue);
    EXPECT_WK_STREQ("This is an apple", [webView stringByEvaluatingJavaScript:@"document.body.textContent"]);
}

TEST(WKAttachmentTests, InsertAndRemoveDuplicateAttachment)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<NSData> data = testHTMLData();
    auto fileWrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data.get()]);
    RetainPtr<_WKAttachment> originalAttachment;
    RetainPtr<_WKAttachment> pastedAttachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        originalAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:fileWrapper.get() contentType:@"text/plain"];
        EXPECT_EQ(0U, observer.observer().removed.count);
        observer.expectAttachmentUpdates(@[ ], @[ originalAttachment.get() ]);
    }
    [webView selectAll:nil];
    [webView _executeEditCommand:@"Copy" argument:nil completion:nil];
    [webView evaluateJavaScript:@"getSelection().collapseToEnd()" completionHandler:nil];
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(0U, observer.observer().removed.count);
        EXPECT_EQ(1U, observer.observer().inserted.count);
        pastedAttachment = observer.observer().inserted.firstObject;
        EXPECT_FALSE([pastedAttachment isEqual:originalAttachment.get()]);
    }
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        observer.expectAttachmentUpdates(@[ pastedAttachment.get() ], @[ ]);
        [originalAttachment expectRequestedDataToBe:data.get()];
    }
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView evaluateJavaScript:@"getSelection().setPosition(document.body)" completionHandler:nil];
        [webView _synchronouslyExecuteEditCommand:@"DeleteForward" argument:nil];
        observer.expectAttachmentUpdates(@[ originalAttachment.get() ], @[ ]);
    }

    EXPECT_FALSE([originalAttachment isEqual:pastedAttachment.get()]);
    EXPECT_TRUE([[originalAttachment info].fileWrapper isEqual:[pastedAttachment info].fileWrapper]);
    EXPECT_TRUE([[originalAttachment info].fileWrapper isEqual:fileWrapper.get()]);
}

TEST(WKAttachmentTests, InsertDuplicateAttachmentAndUpdateData)
{
    auto webView = webViewForTestingAttachments();
    auto originalData = retainPtr(testHTMLData());
    auto fileWrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:originalData.get()]);
    RetainPtr<_WKAttachment> originalAttachment;
    RetainPtr<_WKAttachment> pastedAttachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        originalAttachment = [webView synchronouslyInsertAttachmentWithFileWrapper:fileWrapper.get() contentType:@"text/plain"];
        EXPECT_EQ(0U, observer.observer().removed.count);
        observer.expectAttachmentUpdates(@[ ], @[ originalAttachment.get() ]);
    }
    [webView selectAll:nil];
    [webView _executeEditCommand:@"Copy" argument:nil completion:nil];
    [webView evaluateJavaScript:@"getSelection().collapseToEnd()" completionHandler:nil];
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(0U, observer.observer().removed.count);
        EXPECT_EQ(1U, observer.observer().inserted.count);
        pastedAttachment = observer.observer().inserted.firstObject;
        EXPECT_FALSE([pastedAttachment isEqual:originalAttachment.get()]);
    }
    auto updatedData = retainPtr([@"HELLO WORLD" dataUsingEncoding:NSUTF8StringEncoding]);
    [originalAttachment synchronouslySetData:updatedData.get() newContentType:nil newFilename:nil error:nil];
    [originalAttachment expectRequestedDataToBe:updatedData.get()];
    [pastedAttachment expectRequestedDataToBe:originalData.get()];

    EXPECT_FALSE([originalAttachment isEqual:pastedAttachment.get()]);
    EXPECT_FALSE([[originalAttachment info].fileWrapper isEqual:[pastedAttachment info].fileWrapper]);
    EXPECT_FALSE([[originalAttachment info].fileWrapper isEqual:fileWrapper.get()]);
}

TEST(WKAttachmentTests, InsertAttachmentUsingFileWrapperWithFilePath)
{
    auto webView = webViewForTestingAttachments();
    auto originalFileWrapper = adoptNS([[NSFileWrapper alloc] initWithURL:testImageFileURL() options:0 error:nil]);
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFileWrapper:originalFileWrapper.get() contentType:nil];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }

    _WKAttachmentInfo *infoBeforeUpdate = [attachment info];
    EXPECT_WK_STREQ("image/png", infoBeforeUpdate.contentType);
    EXPECT_WK_STREQ("icon.png", infoBeforeUpdate.name);
    EXPECT_TRUE([originalFileWrapper isEqual:infoBeforeUpdate.fileWrapper]);
    [attachment expectRequestedDataToBe:testImageData()];

    auto newFileWrapper = adoptNS([[NSFileWrapper alloc] initWithURL:testPDFFileURL() options:0 error:nil]);
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [attachment synchronouslySetFileWrapper:newFileWrapper.get() newContentType:nil error:nil];
        observer.expectAttachmentUpdates(@[ ], @[ ]);
    }

    _WKAttachmentInfo *infoAfterUpdate = [attachment info];
    EXPECT_WK_STREQ("application/pdf", infoAfterUpdate.contentType);
    EXPECT_WK_STREQ("test.pdf", infoAfterUpdate.name);
    EXPECT_TRUE([newFileWrapper isEqual:infoAfterUpdate.fileWrapper]);
    [attachment expectRequestedDataToBe:testPDFData()];
}

TEST(WKAttachmentTests, InvalidateAttachmentsAfterMainFrameNavigation)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> pdfAttachment;
    RetainPtr<_WKAttachment> htmlAttachment;
    {
        ObserveAttachmentUpdatesForScope insertionObserver(webView.get());
        pdfAttachment = [webView synchronouslyInsertAttachmentWithFilename:@"attachment.pdf" contentType:@"application/pdf" data:testPDFData()];
        htmlAttachment = [webView synchronouslyInsertAttachmentWithFilename:@"index.html" contentType:@"text/html" data:testHTMLData()];
        insertionObserver.expectAttachmentUpdates(@[ ], @[ pdfAttachment.get(), htmlAttachment.get() ]);
        EXPECT_TRUE([pdfAttachment isConnected]);
        EXPECT_TRUE([htmlAttachment isConnected]);
    }

    ObserveAttachmentUpdatesForScope removalObserver(webView.get());
    [webView synchronouslyLoadTestPageNamed:@"simple"];
    removalObserver.expectAttachmentUpdates(@[ pdfAttachment.get(), htmlAttachment.get() ], @[ ]);
    EXPECT_FALSE([pdfAttachment isConnected]);
    EXPECT_FALSE([htmlAttachment isConnected]);
    [pdfAttachment expectRequestedDataToBe:nil];
    [htmlAttachment expectRequestedDataToBe:nil];
}

TEST(WKAttachmentTests, InvalidateAttachmentsAfterWebProcessTermination)
{
    auto webView = webViewForTestingAttachments();
    RetainPtr<_WKAttachment> pdfAttachment;
    RetainPtr<_WKAttachment> htmlAttachment;
    {
        ObserveAttachmentUpdatesForScope insertionObserver(webView.get());
        pdfAttachment = [webView synchronouslyInsertAttachmentWithFilename:@"attachment.pdf" contentType:@"application/pdf" data:testPDFData()];
        htmlAttachment = [webView synchronouslyInsertAttachmentWithFilename:@"index.html" contentType:@"text/html" data:testHTMLData()];
        insertionObserver.expectAttachmentUpdates(@[ ], @[ pdfAttachment.get(), htmlAttachment.get() ]);
        EXPECT_TRUE([pdfAttachment isConnected]);
        EXPECT_TRUE([htmlAttachment isConnected]);
    }
    {
        ObserveAttachmentUpdatesForScope removalObserver(webView.get());
        [webView stringByEvaluatingJavaScript:@"getSelection().collapseToEnd()"];
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        removalObserver.expectAttachmentUpdates(@[ htmlAttachment.get() ], @[ ]);
        EXPECT_TRUE([pdfAttachment isConnected]);
        EXPECT_FALSE([htmlAttachment isConnected]);
        [htmlAttachment expectRequestedDataToBe:testHTMLData()];
    }

    __block bool webProcessTerminated = false;
    auto navigationDelegate = adoptNS([[TestNavigationDelegate alloc] init]);
    [webView setNavigationDelegate:navigationDelegate.get()];
    [navigationDelegate setWebContentProcessDidTerminate:^(WKWebView *) {
        webProcessTerminated = true;
    }];

    ObserveAttachmentUpdatesForScope observer(webView.get());
    [webView _killWebContentProcess];
    TestWebKitAPI::Util::run(&webProcessTerminated);

    observer.expectAttachmentUpdates(@[ pdfAttachment.get() ], @[ ]);
    EXPECT_FALSE([pdfAttachment isConnected]);
    EXPECT_FALSE([htmlAttachment isConnected]);
    [pdfAttachment expectRequestedDataToBe:nil];
    [htmlAttachment expectRequestedDataToBe:nil];
}

TEST(WKAttachmentTests, MoveAttachmentElementAsIconByDragging)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAttachmentElementEnabled:YES];
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
    TestWKWebView *webView = [simulator webView];
    [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup];

    auto data = retainPtr(testPDFData());
    auto attachment = retainPtr([webView synchronouslyInsertAttachmentWithFilename:@"document.pdf" contentType:@"application/pdf" data:data.get()]);

    [webView _executeEditCommand:@"InsertParagraph" argument:nil completion:nil];
    [webView _executeEditCommand:@"InsertHTML" argument:@"<strong>text</strong>" completion:nil];
    [webView _synchronouslyExecuteEditCommand:@"InsertParagraph" argument:nil];
    [webView expectElementTag:@"ATTACHMENT" toComeBefore:@"STRONG"];

    // Drag the attachment element to somewhere below the strong text.
    [simulator runFrom:[webView attachmentElementMidPoint] to:CGPointMake(50, 300)];

    EXPECT_WK_STREQ("document.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
    EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
    [attachment expectRequestedDataToBe:data.get()];
    EXPECT_EQ([simulator insertedAttachments].count, [simulator removedAttachments].count);
#if PLATFORM(MAC)
    EXPECT_FALSE(isCompletelyTransparent([simulator draggingInfo].draggedImage));
#endif

    [webView expectElementTag:@"STRONG" toComeBefore:@"ATTACHMENT"];
    [simulator endDataTransfer];
}

TEST(WKAttachmentTests, PasteWebArchiveContainingImages)
{
    NSData *markupData = [@"<img src='1.png' alt='foo'><div><br></div><img src='2.gif' alt='bar'>" dataUsingEncoding:NSUTF8StringEncoding];

    auto mainResource = adoptNS([[WebResource alloc] initWithData:markupData URL:[NSURL URLWithString:@"foo.html"] MIMEType:@"text/html" textEncodingName:@"utf-8" frameName:nil]);
    auto pngResource = adoptNS([[WebResource alloc] initWithData:testImageData() URL:[NSURL URLWithString:@"1.png"] MIMEType:@"image/png" textEncodingName:nil frameName:nil]);
    auto gifResource = adoptNS([[WebResource alloc] initWithData:testGIFData() URL:[NSURL URLWithString:@"2.gif"] MIMEType:@"image/gif" textEncodingName:nil frameName:nil]);
    auto archive = adoptNS([[WebArchive alloc] initWithMainResource:mainResource.get() subresources:@[ pngResource.get(), gifResource.get() ] subframeArchives:@[ ]]);

#if PLATFORM(MAC)
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard declareTypes:@[WebArchivePboardType] owner:nil];
    [pasteboard setData:[archive data] forType:WebArchivePboardType];
#else
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setData:[archive data] forPasteboardType:WebArchivePboardType];
#endif

    RetainPtr<_WKAttachment> gifAttachment;
    RetainPtr<_WKAttachment> pngAttachment;
    auto webView = webViewForTestingAttachments();

    ObserveAttachmentUpdatesForScope observer(webView.get());
    [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
    [webView expectElementCount:2 querySelector:@"IMG"];

    for (_WKAttachment *attachment in observer.observer().inserted) {
        if ([attachment.info.contentType isEqualToString:@"image/png"])
            pngAttachment = attachment;
        else if ([attachment.info.contentType isEqualToString:@"image/gif"])
            gifAttachment = attachment;
    }

    EXPECT_WK_STREQ("foo", [pngAttachment info].name);
    EXPECT_WK_STREQ("bar", [gifAttachment info].name);
    [pngAttachment expectRequestedDataToBe:testImageData()];
    [gifAttachment expectRequestedDataToBe:testGIFData()];
    observer.expectAttachmentUpdates(@[ ], @[ pngAttachment.get(), gifAttachment.get() ]);
}

TEST(WKAttachmentTests, ChangeFileWrapperForPastedImage)
{
    platformCopyPNG();
    auto webView = webViewForTestingAttachments();

    ObserveAttachmentUpdatesForScope observer(webView.get());
    [webView paste:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];

    auto attachment = retainPtr(observer.observer().inserted.firstObject);
    auto originalImageData = retainPtr([attachment info].fileWrapper);
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"HTMLAttachmentElement.getAttachmentIdentifier(document.querySelector('img'))"]);

    auto newImage = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testGIFData()]);
    [newImage setPreferredFilename:@"foo.gif"];
    [attachment synchronouslySetFileWrapper:newImage.get() newContentType:nil error:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(52, 64)];

    [attachment synchronouslySetFileWrapper:originalImageData.get() newContentType:@"image/png" error:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
}

TEST(WKAttachmentTests, AddAttachmentToConnectedImageElement)
{
    auto webView = webViewForTestingAttachments();
    [webView _synchronouslyExecuteEditCommand:@"InsertHTML" argument:@"<img></img>"];

    __block bool doneWaitingForAttachmentInsertion = false;
    [webView performAfterReceivingMessage:@"inserted" action:^{
        doneWaitingForAttachmentInsertion = true;
    }];

    const char *scriptForEnsuringAttachmentIdentifier = \
        "const identifier = HTMLAttachmentElement.getAttachmentIdentifier(document.querySelector('img'));"
        "setTimeout(() => webkit.messageHandlers.testHandler.postMessage('inserted'), 0);"
        "identifier";

    ObserveAttachmentUpdatesForScope observer(webView.get());
    NSString *attachmentIdentifier = [webView stringByEvaluatingJavaScript:@(scriptForEnsuringAttachmentIdentifier)];
    auto attachment = retainPtr([webView _attachmentForIdentifier:attachmentIdentifier]);
    EXPECT_WK_STREQ(attachmentIdentifier, [attachment uniqueIdentifier]);
    EXPECT_WK_STREQ(attachmentIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
    Util::run(&doneWaitingForAttachmentInsertion);
    observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);

    auto firstImage = adoptNS([[NSFileWrapper alloc] initWithURL:testImageFileURL() options:0 error:nil]);
    auto secondImage = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testGIFData()]);
    [secondImage setPreferredFilename:@"foo.gif"];

    [attachment synchronouslySetFileWrapper:firstImage.get() newContentType:@"image/png" error:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];

    [attachment synchronouslySetFileWrapper:secondImage.get() newContentType:(__bridge NSString *)kUTTypeGIF error:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(52, 64)];

    [attachment synchronouslySetFileWrapper:firstImage.get() newContentType:nil error:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
}

TEST(WKAttachmentTests, ConnectImageWithAttachmentToDocument)
{
    auto webView = webViewForTestingAttachments();
    ObserveAttachmentUpdatesForScope observer(webView.get());

    NSString *identifier = [webView stringByEvaluatingJavaScript:@"image = document.createElement('img'); HTMLAttachmentElement.getAttachmentIdentifier(image)"];
    auto image = adoptNS([[NSFileWrapper alloc] initWithURL:testImageFileURL() options:0 error:nil]);
    auto attachment = retainPtr([webView _attachmentForIdentifier:identifier]);
    [attachment synchronouslySetFileWrapper:image.get() newContentType:nil error:nil];
    EXPECT_FALSE([attachment isConnected]);
    observer.expectAttachmentUpdates(@[ ], @[ ]);

    [webView evaluateJavaScript:@"document.body.appendChild(image)" completionHandler:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(215, 174)];
    EXPECT_TRUE([attachment isConnected]);
    observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);

    auto newImage = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testGIFData()]);
    [newImage setPreferredFilename:@"test.gif"];
    [attachment synchronouslySetFileWrapper:newImage.get() newContentType:nil error:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(52, 64)];
}

TEST(WKAttachmentTests, CustomFileWrapperSubclass)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAttachmentElementEnabled:YES];
    RetainPtr<NSException> exception;
    @try {
        [configuration _setAttachmentFileWrapperClass:[NSArray self]];
    } @catch(NSException *caught) {
        exception = caught;
    }
    EXPECT_TRUE(exception);

    [configuration _setAttachmentFileWrapperClass:[FileWrapper self]];

    auto webView = webViewForTestingAttachments(CGSizeZero, configuration.get());

    ObserveAttachmentUpdatesForScope observer(webView.get());
    platformCopyPNG();
    [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
    NSArray<_WKAttachment *> * insertedAttachments = observer.observer().inserted;

    EXPECT_EQ(1U, insertedAttachments.count);
    EXPECT_EQ([FileWrapper self], [insertedAttachments.firstObject.info.fileWrapper class]);
}

// FIXME: Remove this version guard once rdar://51752593 is resolved.
#if PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED < 130000
TEST(WKAttachmentTests, CopyAndPasteBetweenWebViews)
{
    auto file = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testHTMLData()]);
    [file setPreferredFilename:@"test.foobar"];
    auto image = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testImageData()]);
    auto document = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testPDFData()]);
    auto folder = adoptNS([[NSFileWrapper alloc] initDirectoryWithFileWrappers:@{ @"image.png": image.get(), @"document.pdf": document.get() }]);
    [folder setPreferredFilename:@"folder"];
    auto archive = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testZIPData()]);
    [archive setPreferredFilename:@"archive"];

    @autoreleasepool {
        auto firstWebView = webViewForTestingAttachments();
        [firstWebView synchronouslyInsertAttachmentWithFileWrapper:file.get() contentType:@"application/octet-stream"];
        [firstWebView synchronouslyInsertAttachmentWithFileWrapper:folder.get() contentType:(__bridge NSString *)kUTTypeFolder];
        [firstWebView synchronouslyInsertAttachmentWithFileWrapper:archive.get() contentType:@"application/zip"];
        [firstWebView selectAll:nil];
        [firstWebView _executeEditCommand:@"Copy" argument:nil completion:nil];
    }

    auto secondWebView = webViewForTestingAttachments();
    ObserveAttachmentUpdatesForScope observer(secondWebView.get());
    [secondWebView paste:nil];
    [secondWebView expectElementCount:3 querySelector:@"attachment"];
    EXPECT_EQ(3U, observer.observer().inserted.count);

    NSString *plainFileIdentifier = [secondWebView stringByEvaluatingJavaScript:@"document.querySelector('attachment[title^=test]').uniqueIdentifier"];
    NSString *folderIdentifier = [secondWebView stringByEvaluatingJavaScript:@"document.querySelector('attachment[title=folder]').uniqueIdentifier"];
    NSString *archiveIdentifier = [secondWebView stringByEvaluatingJavaScript:@"document.querySelector('attachment[title=archive]').uniqueIdentifier"];

    _WKAttachmentInfo *pastedFileInfo = [secondWebView _attachmentForIdentifier:plainFileIdentifier].info;
    _WKAttachmentInfo *pastedFolderInfo = [secondWebView _attachmentForIdentifier:folderIdentifier].info;
    _WKAttachmentInfo *pastedArchiveInfo = [secondWebView _attachmentForIdentifier:archiveIdentifier].info;

    NSDictionary<NSString *, NSFileWrapper *> *pastedFolderContents = pastedFolderInfo.fileWrapper.fileWrappers;
    NSFileWrapper *documentFromFolder = [pastedFolderContents objectForKey:@"document.pdf"];
    NSFileWrapper *imageFromFolder = [pastedFolderContents objectForKey:@"image.png"];
    EXPECT_TRUE([[document regularFileContents] isEqualToData:documentFromFolder.regularFileContents]);
    EXPECT_TRUE([[image regularFileContents] isEqualToData:imageFromFolder.regularFileContents]);
    EXPECT_TRUE([[file regularFileContents] isEqualToData:pastedFileInfo.fileWrapper.regularFileContents]);
    EXPECT_TRUE([[archive regularFileContents] isEqualToData:pastedArchiveInfo.fileWrapper.regularFileContents]);
    EXPECT_WK_STREQ("application/octet-stream", pastedFileInfo.contentType);
    EXPECT_WK_STREQ("public.directory", pastedFolderInfo.contentType);
    EXPECT_WK_STREQ("application/zip", pastedArchiveInfo.contentType);
}
#endif // PLATFORM(IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED < 130000

TEST(WKAttachmentTests, AttachmentIdentifierOfClonedAttachment)
{
    auto webView = webViewForTestingAttachments();
    auto attachment = retainPtr([webView synchronouslyInsertAttachmentWithFilename:@"attachment.pdf" contentType:@"application/pdf" data:testPDFData()]);
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.body.cloneNode(true).querySelector('attachment').uniqueIdentifier"]);
}

TEST(WKAttachmentTests, SetFileWrapperForPDFImageAttachment)
{
    auto webView = webViewForTestingAttachments();
    [webView evaluateJavaScript:@"document.body.appendChild()" completionHandler:nil];
    NSString *identifier = [webView stringByEvaluatingJavaScript:@"const i = document.createElement('img'); document.body.appendChild(i); HTMLAttachmentElement.getAttachmentIdentifier(i)"];
    auto attachment = retainPtr([webView _attachmentForIdentifier:identifier]);

    auto pdfFile = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testPDFData()]);
    [attachment setFileWrapper:pdfFile.get() contentType:(__bridge NSString *)kUTTypePDF completion:nil];
    [webView waitForImageElementSizeToBecome:CGSizeMake(130, 29)];

    [webView synchronouslyLoadTestPageNamed:@"simple"];

    auto zipFile = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:testZIPData()]);
    [attachment setFileWrapper:zipFile.get() contentType:(__bridge NSString *)kUTTypeZipArchive completion:nil];
    EXPECT_FALSE([attachment isConnected]);
}

#pragma mark - Platform-specific tests

#if PLATFORM(MAC)

TEST(WKAttachmentTestsMac, InsertPastedFileURLsAsAttachments)
{
    NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
    [pasteboard clearContents];
    [pasteboard declareTypes:@[NSFilenamesPboardType] owner:nil];
    [pasteboard setPropertyList:@[testPDFFileURL().path, testImageFileURL().path] forType:NSFilenamesPboardType];

    RetainPtr<NSArray<_WKAttachment *>> insertedAttachments;
    auto webView = webViewForTestingAttachments();
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        insertedAttachments = [observer.observer() inserted];
        EXPECT_EQ(2U, [insertedAttachments count]);
    }

    [webView expectElementCount:1 querySelector:@"ATTACHMENT"];
    [webView expectElementCount:1 querySelector:@"IMG"];
    EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('type')"]);
    EXPECT_WK_STREQ("test.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').getAttribute('title')"]);

    NSString *imageAttachmentIdentifier = [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"];
    if ([testImageData() isEqualToData:[insertedAttachments firstObject].info.data])
        EXPECT_WK_STREQ([insertedAttachments firstObject].uniqueIdentifier, imageAttachmentIdentifier);
    else
        EXPECT_WK_STREQ([insertedAttachments lastObject].uniqueIdentifier, imageAttachmentIdentifier);

    for (_WKAttachment *attachment in insertedAttachments.get())
        EXPECT_GT(attachment.info.filePath.length, 0U);

    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        NSArray<_WKAttachment *> *removedAttachments = [observer.observer() removed];
        EXPECT_EQ(2U, removedAttachments.count);
        EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments firstObject]]);
        EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments lastObject]]);
    }
}

TEST(WKAttachmentTestsMac, DISABLED_InsertDroppedFilePromisesAsAttachments)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAttachmentElementEnabled:YES];
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
    TestWKWebView *webView = [simulator webView];
    [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup];
    [simulator writePromisedFiles:@[ testPDFFileURL(), testImageFileURL() ]];

    [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(50, 50)];

    [webView expectElementCount:1 querySelector:@"ATTACHMENT"];
    [webView expectElementCount:1 querySelector:@"IMG"];
    EXPECT_EQ(2U, [simulator insertedAttachments].count);

    auto insertedAttachments = retainPtr([simulator insertedAttachments]);
    NSArray<NSData *> *expectedData = @[ testPDFData(), testImageData() ];
    for (_WKAttachment *attachment in insertedAttachments.get()) {
        EXPECT_GT(attachment.info.filePath.length, 0U);
        EXPECT_TRUE([expectedData containsObject:attachment.info.data]);
        if ([testPDFData() isEqualToData:attachment.info.data])
            EXPECT_WK_STREQ("application/pdf", attachment.info.contentType);
        else if ([testImageData() isEqualToData:attachment.info.data]) {
            EXPECT_WK_STREQ("image/png", attachment.info.contentType);
            EXPECT_WK_STREQ(attachment.uniqueIdentifier, [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);
        }
    }

    [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
    [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
    auto removedAttachments = retainPtr([simulator removedAttachments]);
    EXPECT_EQ(2U, [removedAttachments count]);
    [webView expectElementCount:0 querySelector:@"ATTACHMENT"];
    [webView expectElementCount:0 querySelector:@"IMG"];
    EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments firstObject]]);
    EXPECT_TRUE([removedAttachments containsObject:[insertedAttachments lastObject]]);
}

TEST(WKAttachmentTestsMac, DragAttachmentAsFilePromise)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAttachmentElementEnabled:YES];
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
    TestWKWebView *webView = [simulator webView];
    [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup];

    auto fileWrapper = adoptNS([[NSFileWrapper alloc] initWithURL:testPDFFileURL() options:0 error:nil]);
    auto attachment = retainPtr([webView synchronouslyInsertAttachmentWithFileWrapper:fileWrapper.get() contentType:nil]);
    [simulator runFrom:[webView attachmentElementMidPoint] to:CGPointMake(300, 300)];

    NSArray<NSURL *> *urls = [simulator receivePromisedFiles];
    EXPECT_EQ(1U, urls.count);
    EXPECT_WK_STREQ("test.pdf", urls.lastObject.lastPathComponent);
    EXPECT_TRUE([[NSData dataWithContentsOfURL:urls.firstObject] isEqualToData:testPDFData()]);
    EXPECT_FALSE(isCompletelyTransparent([simulator draggingInfo].draggedImage));
}

TEST(WKAttachmentTestsMac, DragAttachmentWithNoTypeShouldNotCrash)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAttachmentElementEnabled:YES];
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebViewFrame:NSMakeRect(0, 0, 400, 400) configuration:configuration.get()]);
    TestWKWebView *webView = [simulator webView];
    [webView synchronouslyLoadHTMLString:attachmentEditingTestMarkup];

    [webView stringByEvaluatingJavaScript:@"document.body.appendChild(document.createElement('attachment')); 0"];

    [simulator runFrom:[webView attachmentElementMidPoint] to:CGPointMake(300, 300)];

    NSArray<NSURL *> *urls = [simulator receivePromisedFiles];
    EXPECT_EQ(0U, urls.count);
}

#endif // PLATFORM(MAC)

#if PLATFORM(IOS_FAMILY)

static RetainPtr<UITargetedDragPreview> targetedImageDragPreview(WKWebView *webView, NSData *imageData, CGSize size)
{
    auto imageView = adoptNS([[UIImageView alloc] initWithImage:[UIImage imageWithData:imageData]]);
    [imageView setBounds:CGRectMake(0, 0, size.width, size.height)];
    auto defaultDropTarget = adoptNS([[UIDragPreviewTarget alloc] initWithContainer:webView center:CGPointMake(450, 450)]);
    auto parameters = adoptNS([[UIDragPreviewParameters alloc] init]);
    return adoptNS([[UITargetedDragPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:defaultDropTarget.get()]);
}

TEST(WKAttachmentTestsIOS, TargetedPreviewsWhenDroppingImages)
{
    auto webView = webViewForTestingAttachments();
    [webView _setEditable:YES];

    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);

    // The first item preview should be scaled down by a factor of 2.
    auto firstPreview = targetedImageDragPreview(webView.get(), testImageData(), CGSizeMake(430, 348));
    auto firstItem = adoptNS([[NSItemProvider alloc] init]);
    [firstItem registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypePNG withData:testImageData() loadingDelay:0.5];
    [firstItem setPreferredPresentationSize:CGSizeMake(215, 174)];
    [firstItem setSuggestedName:@"icon"];

    // The second item preview should be scaled up by a factor of 2.
    auto secondPreview = targetedImageDragPreview(webView.get(), testGIFData(), CGSizeMake(26, 32));
    auto secondItem = adoptNS([[NSItemProvider alloc] init]);
    [secondItem registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypeGIF withData:testGIFData() loadingDelay:0.5];
    [secondItem setPreferredPresentationSize:CGSizeMake(52, 64)];
    [secondItem setSuggestedName:@"apple"];

    [simulator setDropAnimationTiming:DropAnimationShouldFinishBeforeHandlingDrop];
    [simulator setExternalItemProviders:[NSArray arrayWithObjects:firstItem.get(), secondItem.get(), nil] defaultDropPreviews:[NSArray arrayWithObjects:firstPreview.get(), secondPreview.get(), nil]];
    [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(450, 450)];

    EXPECT_EQ([simulator delayedDropPreviews].count, 2U);
    UITargetedDragPreview *firstDelayedPreview = [simulator delayedDropPreviews].firstObject;
    UITargetedDragPreview *secondDelayedPreview = [simulator delayedDropPreviews].lastObject;
    auto imageElementBounds = retainPtr([webView allBoundingClientRects:@"IMG"]);

    EXPECT_TRUE(CGAffineTransformEqualToTransform(CGAffineTransformMakeScale(0.5, 0.5), firstDelayedPreview.target.transform));
    EXPECT_TRUE(CGRectEqualToRect(CGRectMake(0, 0, 430, 348), firstDelayedPreview.parameters.visiblePath.bounds));
    EXPECT_TRUE(CGRectContainsPoint([imageElementBounds firstObject].CGRectValue, firstDelayedPreview.target.center));

    EXPECT_TRUE(CGAffineTransformEqualToTransform(CGAffineTransformMakeScale(2, 2), secondDelayedPreview.target.transform));
    EXPECT_TRUE(CGRectEqualToRect(CGRectMake(0, 0, 26, 32), secondDelayedPreview.parameters.visiblePath.bounds));
    EXPECT_TRUE(CGRectContainsPoint([imageElementBounds lastObject].CGRectValue, secondDelayedPreview.target.center));

    [webView expectElementCount:2 querySelector:@"IMG"];
    _WKAttachment *pngAttachment = [[simulator insertedAttachments] _attachmentWithName:@"icon.png"];
    _WKAttachment *gifAttachment = [[simulator insertedAttachments] _attachmentWithName:@"apple.gif"];
    EXPECT_WK_STREQ(pngAttachment.info.contentType, @"image/png");
    EXPECT_WK_STREQ(gifAttachment.info.contentType, @"image/gif");
}

TEST(WKAttachmentTestsIOS, TargetedPreviewIsClippedWhenDroppingTallImage)
{
    auto webView = webViewForTestingAttachments(CGSizeMake(800, 200));
    [webView stringByEvaluatingJavaScript:@"document.body.style.margin = '0'"];
    [webView _setEditable:YES];

    auto imageData = retainPtr([NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"400x400-green" withExtension:@"png" subdirectory:@"TestWebKitAPI.resources"]]);
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);

    auto preview = targetedImageDragPreview(webView.get(), imageData.get(), CGSizeMake(100, 100));
    auto item = adoptNS([[NSItemProvider alloc] init]);
    [item registerDataRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypePNG withData:imageData.get() loadingDelay:0.5];
    [item setPreferredPresentationSize:CGSizeMake(400, 400)];
    [item setSuggestedName:@"green"];

    [simulator setDropAnimationTiming:DropAnimationShouldFinishBeforeHandlingDrop];
    [simulator setExternalItemProviders:[NSArray arrayWithObject:item.get()] defaultDropPreviews:[NSArray arrayWithObject:preview.get()]];
    [simulator runFrom:CGPointMake(0, 0) to:CGPointMake(350, 350)];

    EXPECT_EQ([simulator delayedDropPreviews].count, 1U);
    UITargetedDragPreview *delayedPreview = [simulator delayedDropPreviews].firstObject;
    EXPECT_TRUE(CGAffineTransformEqualToTransform(CGAffineTransformMakeScale(4, 4), delayedPreview.target.transform));
    EXPECT_TRUE(CGRectEqualToRect(CGRectMake(0, 0, 100, 50), delayedPreview.parameters.visiblePath.bounds));
    EXPECT_TRUE(CGPointEqualToPoint(CGPointMake(200, 100), delayedPreview.target.center));

    [webView expectElementCount:1 querySelector:@"IMG"];
    _WKAttachment *attachment = [[simulator insertedAttachments] _attachmentWithName:@"green.png"];
    EXPECT_WK_STREQ(attachment.info.contentType, @"image/png");
}

TEST(WKAttachmentTestsIOS, InsertDroppedImageAsAttachment)
{
    auto webView = webViewForTestingAttachments();
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    auto item = adoptNS([[NSItemProvider alloc] init]);
    [item registerData:testImageData() type:(__bridge NSString *)kUTTypePNG];
    [dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
    [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

    EXPECT_EQ(1U, [dragAndDropSimulator insertedAttachments].count);
    EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);
    auto attachment = retainPtr([dragAndDropSimulator insertedAttachments].firstObject);
    [attachment expectRequestedDataToBe:testImageData()];
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);

    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
    }
}

TEST(WKAttachmentTestsIOS, InsertDroppedImageWithPreferredPresentationSize)
{
    auto webView = webViewForTestingAttachments();
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    auto item = adoptNS([[NSItemProvider alloc] init]);
    [item registerData:testImageData() type:(__bridge NSString *)kUTTypePNG];
    [item setPreferredPresentationSize:CGSizeMake(200, 100)];
    [dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
    [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

    CGSize imageElementSize = [webView imageElementSize];
    EXPECT_EQ(200, imageElementSize.width);
    EXPECT_EQ(100, imageElementSize.height);
}

TEST(WKAttachmentTestsIOS, InsertDroppedAttributedStringContainingAttachment)
{
    auto webView = webViewForTestingAttachments();
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    auto image = adoptNS([[NSTextAttachment alloc] initWithData:testImageData() ofType:(__bridge NSString *)kUTTypePNG]);
    auto item = adoptNS([[NSItemProvider alloc] init]);
    [item registerObject:[NSAttributedString attributedStringWithAttachment:image.get()] visibility:NSItemProviderRepresentationVisibilityAll];

    [dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
    [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

    EXPECT_EQ(1U, [dragAndDropSimulator insertedAttachments].count);
    EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);
    auto attachment = retainPtr([dragAndDropSimulator insertedAttachments].firstObject);

    auto size = platformImageWithData([attachment info].data).size;
    EXPECT_EQ(215., size.width);
    EXPECT_EQ(174., size.height);
    EXPECT_WK_STREQ([attachment uniqueIdentifier], [webView stringByEvaluatingJavaScript:@"document.querySelector('img').attachmentIdentifier"]);

    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"SelectAll" argument:nil];
        [webView _synchronouslyExecuteEditCommand:@"DeleteBackward" argument:nil];
        observer.expectAttachmentUpdates(@[ attachment.get() ], @[ ]);
    }
}

TEST(WKAttachmentTestsIOS, InsertDroppedRichAndPlainTextFilesAsAttachments)
{
    // Here, both rich text and plain text are content types that WebKit already understands how to insert in editable
    // areas in the absence of attachment elements. However, due to the explicitly set attachment presentation style
    // on the item providers, we should instead treat them as dropped files and insert attachment elements.
    // This exercises the scenario of dragging rich and plain text files from Files to Mail.
    auto richTextItem = adoptNS([[NSItemProvider alloc] init]);
    auto richText = adoptNS([[NSAttributedString alloc] initWithString:@"Hello world" attributes:@{ NSFontAttributeName: [UIFont boldSystemFontOfSize:12] }]);
    [richTextItem setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
    [richTextItem registerObject:richText.get() visibility:NSItemProviderRepresentationVisibilityAll];
    [richTextItem setSuggestedName:@"hello.rtf"];

    auto plainTextItem = adoptNS([[NSItemProvider alloc] init]);
    [plainTextItem setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
    [plainTextItem registerObject:@"Hello world" visibility:NSItemProviderRepresentationVisibilityAll];
    [plainTextItem setSuggestedName:@"world.txt"];

    auto webView = webViewForTestingAttachments();
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    [dragAndDropSimulator setExternalItemProviders:@[ richTextItem.get(), plainTextItem.get() ]];
    [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

    EXPECT_EQ(2U, [dragAndDropSimulator insertedAttachments].count);
    EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);

    for (_WKAttachment *attachment in [dragAndDropSimulator insertedAttachments])
        EXPECT_GT([attachment info].data.length, 0U);

    [webView expectElementCount:2 querySelector:@"ATTACHMENT"];
    EXPECT_WK_STREQ("hello.rtf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]);
    EXPECT_WK_STREQ((__bridge NSString *)kUTTypeFlatRTFD, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
    EXPECT_WK_STREQ("world.txt", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('title')"]);
    EXPECT_WK_STREQ((__bridge NSString *)kUTTypeUTF8PlainText, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]);
}

TEST(WKAttachmentTestsIOS, InsertDroppedZipArchiveAsAttachment)
{
    // Since WebKit doesn't have any default DOM representation for ZIP archives, we should fall back to inserting
    // attachment elements. This exercises the flow of dragging a ZIP file from an app that doesn't specify a preferred
    // presentation style (e.g. Notes) into Mail.
    auto item = adoptNS([[NSItemProvider alloc] init]);
    NSData *data = testZIPData();
    [item registerData:data type:(__bridge NSString *)kUTTypeZipArchive];
    [item setSuggestedName:@"archive.zip"];

    auto webView = webViewForTestingAttachments();
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    [dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
    [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

    EXPECT_EQ(1U, [dragAndDropSimulator insertedAttachments].count);
    EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);
    [[dragAndDropSimulator insertedAttachments].firstObject expectRequestedDataToBe:data];
    [webView expectElementCount:1 querySelector:@"ATTACHMENT"];
    EXPECT_WK_STREQ("archive.zip", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
    EXPECT_WK_STREQ("application/zip", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
}

TEST(WKAttachmentTestsIOS, InsertDroppedItemProvidersInOrder)
{
    // Tests that item providers are inserted in the order they are specified. In this case, the two inserted attachments
    // should be separated by a link.
    auto firstAttachmentItem = adoptNS([[NSItemProvider alloc] init]);
    [firstAttachmentItem setPreferredPresentationStyle:UIPreferredPresentationStyleAttachment];
    [firstAttachmentItem registerObject:@"FIRST" visibility:NSItemProviderRepresentationVisibilityAll];
    [firstAttachmentItem setSuggestedName:@"first.txt"];

    auto inlineTextItem = adoptNS([[NSItemProvider alloc] init]);
    auto appleURL = retainPtr([NSURL URLWithString:@"https://www.apple.com/"]);
    [inlineTextItem registerObject:appleURL.get() visibility:NSItemProviderRepresentationVisibilityAll];

    auto secondAttachmentItem = adoptNS([[NSItemProvider alloc] init]);
    [secondAttachmentItem registerData:testPDFData() type:(__bridge NSString *)kUTTypePDF];
    [secondAttachmentItem setSuggestedName:@"second.pdf"];

    auto webView = webViewForTestingAttachments();
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    [dragAndDropSimulator setExternalItemProviders:@[ firstAttachmentItem.get(), inlineTextItem.get(), secondAttachmentItem.get() ]];
    [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

    EXPECT_EQ(2U, [dragAndDropSimulator insertedAttachments].count);
    EXPECT_EQ(0U, [dragAndDropSimulator removedAttachments].count);

    for (_WKAttachment *attachment in [dragAndDropSimulator insertedAttachments])
        EXPECT_GT([attachment info].data.length, 0U);

    [webView expectElementTagsInOrder:@[ @"ATTACHMENT", @"A", @"ATTACHMENT" ]];

    EXPECT_WK_STREQ("first.txt", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('title')"]);
    EXPECT_WK_STREQ((__bridge NSString *)kUTTypeUTF8PlainText, [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[0].getAttribute('type')"]);
    EXPECT_WK_STREQ([appleURL absoluteString], [webView valueOfAttribute:@"href" forQuerySelector:@"a"]);
    EXPECT_WK_STREQ("second.pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('title')"]);
    EXPECT_WK_STREQ("application/pdf", [webView stringByEvaluatingJavaScript:@"document.querySelectorAll('attachment')[1].getAttribute('type')"]);
}

TEST(WKAttachmentTestsIOS, DragAttachmentInsertedAsFile)
{
    auto item = adoptNS([[NSItemProvider alloc] init]);
    auto data = retainPtr(testPDFData());
    [item registerData:data.get() type:(__bridge NSString *)kUTTypePDF];
    [item setSuggestedName:@"document.pdf"];

    auto webView = webViewForTestingAttachments();
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    [dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
    [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

    // First, verify that the attachment was successfully dropped.
    EXPECT_EQ(1U, [dragAndDropSimulator insertedAttachments].count);
    _WKAttachment *attachment = [dragAndDropSimulator insertedAttachments].firstObject;
    [attachment expectRequestedDataToBe:data.get()];
    EXPECT_WK_STREQ("document.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
    EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);

    [webView evaluateJavaScript:@"getSelection().removeAllRanges()" completionHandler:nil];
    [dragAndDropSimulator setExternalItemProviders:@[ ]];
    [dragAndDropSimulator runFrom:CGPointMake(25, 25) to:CGPointMake(-100, -100)];

    // Next, verify that dragging the attachment produces an item provider with a PDF attachment.
    EXPECT_EQ(1U, [dragAndDropSimulator sourceItemProviders].count);
    NSItemProvider *itemProvider = [dragAndDropSimulator sourceItemProviders].firstObject;
    EXPECT_EQ(UIPreferredPresentationStyleAttachment, itemProvider.preferredPresentationStyle);
    [itemProvider expectType:(__bridge NSString *)kUTTypePDF withData:data.get()];
    EXPECT_WK_STREQ("document.pdf", [itemProvider suggestedName]);
    [dragAndDropSimulator endDataTransfer];
}

TEST(WKAttachmentTestsIOS, DragAttachmentInsertedAsData)
{
    auto webView = webViewForTestingAttachments();
    auto data = retainPtr(testPDFData());
    RetainPtr<_WKAttachment> attachment;
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        attachment = [webView synchronouslyInsertAttachmentWithFilename:@"document.pdf" contentType:@"application/pdf" data:data.get()];
        observer.expectAttachmentUpdates(@[ ], @[ attachment.get() ]);
    }

    // First, verify that the attachment was successfully inserted from raw data.
    [attachment expectRequestedDataToBe:data.get()];
    EXPECT_WK_STREQ("document.pdf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
    EXPECT_WK_STREQ("application/pdf", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);

    [webView evaluateJavaScript:@"getSelection().removeAllRanges()" completionHandler:nil];
    auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    [dragAndDropSimulator runFrom:CGPointMake(25, 25) to:CGPointMake(-100, -100)];

    // Next, verify that dragging the attachment produces an item provider with a PDF attachment.
    EXPECT_EQ(1U, [dragAndDropSimulator sourceItemProviders].count);
    NSItemProvider *itemProvider = [dragAndDropSimulator sourceItemProviders].firstObject;
    EXPECT_EQ(UIPreferredPresentationStyleAttachment, itemProvider.preferredPresentationStyle);
    [itemProvider expectType:(__bridge NSString *)kUTTypePDF withData:data.get()];
    EXPECT_WK_STREQ("document.pdf", [itemProvider suggestedName]);
    [dragAndDropSimulator endDataTransfer];
}

static RetainPtr<NSItemProvider> mapItemForTesting()
{
    auto placemark = adoptNS([allocMKPlacemarkInstance() initWithCoordinate:CLLocationCoordinate2DMake(37.3327, -122.0053)]);
    auto mapItem = adoptNS([allocMKMapItemInstance() initWithPlacemark:placemark.get()]);
    [mapItem setName:@"Apple Park.vcf"];

    auto itemProvider = adoptNS([[NSItemProvider alloc] init]);
    [itemProvider registerObject:mapItem.get() visibility:NSItemProviderRepresentationVisibilityAll];
    [itemProvider setSuggestedName:[mapItem name]];
    return itemProvider;
}

static RetainPtr<NSItemProvider> contactItemForTesting()
{
    auto contact = adoptNS([allocCNMutableContactInstance() init]);
    [contact setGivenName:@"Foo"];
    [contact setFamilyName:@"Bar"];

    auto itemProvider = adoptNS([[NSItemProvider alloc] init]);
    [itemProvider registerObject:contact.get() visibility:NSItemProviderRepresentationVisibilityAll];
    [itemProvider setSuggestedName:@"Foo Bar.vcf"];
    return itemProvider;
}

TEST(WKAttachmentTestsIOS, InsertDroppedMapItemAsAttachment)
{
    auto itemProvider = mapItemForTesting();
    auto webView = webViewForTestingAttachments();
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    [simulator setExternalItemProviders:@[ itemProvider.get() ]];
    [simulator runFrom:CGPointMake(25, 25) to:CGPointMake(100, 100)];

    NSURL *droppedLinkURL = [NSURL URLWithString:[webView valueOfAttribute:@"href" forQuerySelector:@"a"]];
    [webView expectElementTag:@"A" toComeBefore:@"ATTACHMENT"];
    EXPECT_WK_STREQ("maps.apple.com", droppedLinkURL.host);
    EXPECT_WK_STREQ("Apple Park.vcf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
    EXPECT_WK_STREQ("text/vcard", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
    EXPECT_EQ(1U, [simulator insertedAttachments].count);
    _WKAttachmentInfo *info = [simulator insertedAttachments].firstObject.info;
    EXPECT_WK_STREQ("Apple Park.vcf", info.name);
    EXPECT_WK_STREQ("text/vcard", info.contentType);
}

TEST(WKAttachmentTestsIOS, InsertDroppedContactAsAttachment)
{
    auto itemProvider = contactItemForTesting();
    auto webView = webViewForTestingAttachments();
    auto simulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
    [simulator setExternalItemProviders:@[ itemProvider.get() ]];
    [simulator runFrom:CGPointMake(25, 25) to:CGPointMake(100, 100)];

    [webView expectElementCount:0 querySelector:@"a"];
    EXPECT_WK_STREQ("Foo Bar.vcf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').title"]);
    EXPECT_WK_STREQ("text/vcard", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
    EXPECT_EQ(1U, [simulator insertedAttachments].count);
    _WKAttachmentInfo *info = [simulator insertedAttachments].firstObject.info;
    EXPECT_WK_STREQ("Foo Bar.vcf", info.name);
    EXPECT_WK_STREQ("text/vcard", info.contentType);
}

TEST(WKAttachmentTestsIOS, InsertPastedContactAsAttachment)
{
    UIPasteboard.generalPasteboard.itemProviders = @[ contactItemForTesting().autorelease() ];
    auto webView = webViewForTestingAttachments();
    ObserveAttachmentUpdatesForScope observer(webView.get());
    [webView paste:nil];

    [webView expectElementCount:0 querySelector:@"a"];
    EXPECT_WK_STREQ("Foo Bar.vcf", [webView stringByEvaluatingJavaScript:@"document.querySelector('attachment').title"]);
    EXPECT_WK_STREQ("text/vcard", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
    EXPECT_EQ(1U, observer.observer().inserted.count);
    _WKAttachment *attachment = observer.observer().inserted.firstObject;
    EXPECT_WK_STREQ("Foo Bar.vcf", attachment.info.name);
    EXPECT_WK_STREQ("text/vcard", attachment.info.contentType);
}

TEST(WKAttachmentTestsIOS, InsertPastedMapItemAsAttachment)
{
    UIApplicationInitialize();
    UIPasteboard.generalPasteboard.itemProviders = @[ mapItemForTesting().autorelease() ];
    auto webView = webViewForTestingAttachments();
    ObserveAttachmentUpdatesForScope observer(webView.get());
    [webView paste:nil];

    NSURL *pastedLinkURL = [NSURL URLWithString:[webView valueOfAttribute:@"href" forQuerySelector:@"a"]];
    [webView expectElementTag:@"A" toComeBefore:@"ATTACHMENT"];
    EXPECT_WK_STREQ("maps.apple.com", pastedLinkURL.host);
    EXPECT_WK_STREQ("Apple Park.vcf", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment"]);
    EXPECT_WK_STREQ("text/vcard", [webView valueOfAttribute:@"type" forQuerySelector:@"attachment"]);
    EXPECT_EQ(1U, observer.observer().inserted.count);
    _WKAttachment *attachment = observer.observer().inserted.firstObject;
    EXPECT_WK_STREQ("Apple Park.vcf", attachment.info.name);
    EXPECT_WK_STREQ("text/vcard", attachment.info.contentType);
}

TEST(WKAttachmentTestsIOS, InsertPastedFilesAsAttachments)
{
    auto pdfItem = adoptNS([[NSItemProvider alloc] init]);
    [pdfItem setSuggestedName:@"doc"];
    [pdfItem registerData:testPDFData() type:(__bridge NSString *)kUTTypePDF];

    auto textItem = adoptNS([[NSItemProvider alloc] init]);
    [textItem setSuggestedName:@"hello"];
    [textItem registerData:[@"helloworld" dataUsingEncoding:NSUTF8StringEncoding] type:(__bridge NSString *)kUTTypePlainText];

    UIPasteboard.generalPasteboard.itemProviders = @[ pdfItem.get(), textItem.get() ];

    RetainPtr<_WKAttachment> textAttachment;
    RetainPtr<_WKAttachment> pdfAttachment;
    auto webView = webViewForTestingAttachments();
    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        [webView _synchronouslyExecuteEditCommand:@"Paste" argument:nil];
        EXPECT_EQ(2U, observer.observer().inserted.count);
        _WKAttachment *firstAttachment = observer.observer().inserted.firstObject;
        if ([firstAttachment.info.contentType isEqualToString:@"text/plain"]) {
            textAttachment = firstAttachment;
            pdfAttachment = observer.observer().inserted.lastObject;
        } else {
            EXPECT_WK_STREQ(firstAttachment.info.contentType, @"application/pdf");
            textAttachment = observer.observer().inserted.lastObject;
            pdfAttachment = firstAttachment;
        }
        observer.expectAttachmentUpdates(@[ ], @[ pdfAttachment.get(), textAttachment.get() ]);
    }

    [webView expectElementCount:2 querySelector:@"attachment"];
    EXPECT_WK_STREQ("doc", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment[type^=application]"]);
    EXPECT_WK_STREQ("doc", [pdfAttachment info].name);
    EXPECT_WK_STREQ("hello", [webView valueOfAttribute:@"title" forQuerySelector:@"attachment[type^=text]"]);
    EXPECT_WK_STREQ("hello", [textAttachment info].name);
    [pdfAttachment expectRequestedDataToBe:testPDFData()];
    [textAttachment expectRequestedDataToBe:[@"helloworld" dataUsingEncoding:NSUTF8StringEncoding]];
    EXPECT_TRUE([webView canPerformAction:@selector(paste:) withSender:nil]);
}

TEST(WKAttachmentTestsIOS, InsertDroppedImageWithNonImageFileExtension)
{
    runTestWithTemporaryImageFile(@"image.hello", ^(NSURL *fileURL) {
        auto item = adoptNS([[NSItemProvider alloc] init]);
        [item setSuggestedName:@"image.hello"];
        [item registerFileRepresentationForTypeIdentifier:(__bridge NSString *)kUTTypePNG fileOptions:NSItemProviderFileOptionOpenInPlace visibility:NSItemProviderRepresentationVisibilityAll loadHandler:^NSProgress *(void (^callback)(NSURL *, BOOL, NSError *))
        {
            callback(fileURL, YES, nil);
            return nil;
        }];

        auto webView = webViewForTestingAttachments();
        auto dragAndDropSimulator = adoptNS([[DragAndDropSimulator alloc] initWithWebView:webView.get()]);
        [dragAndDropSimulator setExternalItemProviders:@[ item.get() ]];
        [dragAndDropSimulator runFrom:CGPointZero to:CGPointMake(50, 50)];

        EXPECT_EQ(1U, [dragAndDropSimulator insertedAttachments].count);
        _WKAttachment *attachment = [dragAndDropSimulator insertedAttachments].firstObject;
        _WKAttachmentInfo *info = attachment.info;
        EXPECT_WK_STREQ("image/png", info.contentType);
        EXPECT_WK_STREQ("image.hello", info.filePath.lastPathComponent);
        EXPECT_WK_STREQ("image.hello", info.name);
        [webView expectElementCount:1 querySelector:@"IMG"];
    });
}

#if HAVE(PENCILKIT)
static BOOL forEachViewInHierarchy(UIView *view, void(^mapFunction)(UIView *subview, BOOL *stop))
{
    BOOL stop = NO;
    mapFunction(view, &stop);
    if (stop)
        return YES;

    for (UIView *subview in view.subviews) {
        stop = forEachViewInHierarchy(subview, mapFunction);
        if (stop)
            break;
    }
    return stop;
}

static PKCanvasView *findEditableImageCanvas(WKWebView *webView)
{
    Class pkCanvasViewClass = NSClassFromString(@"PKCanvasView");
    __block PKCanvasView *canvasView = nil;
    forEachViewInHierarchy(webView.window, ^(UIView *subview, BOOL *stop) {
        if (![subview isKindOfClass:pkCanvasViewClass])
            return;

        canvasView = (PKCanvasView *)subview;
        *stop = YES;
    });
    return canvasView;
}

static void drawSquareInEditableImage(WKWebView *webView)
{
    Class pkDrawingClass = NSClassFromString(@"PKDrawing");
    Class pkInkClass = NSClassFromString(@"PKInk");
    Class pkStrokeClass = NSClassFromString(@"PKStroke");

    PKCanvasView *canvasView = findEditableImageCanvas(webView);
    RetainPtr<PKDrawing> drawing = canvasView.drawing ?: adoptNS([[pkDrawingClass alloc] init]);
    RetainPtr<CGPathRef> path = adoptCF(CGPathCreateWithRect(CGRectMake(0, 0, 50, 50), NULL));
    RetainPtr<PKInk> ink = [pkInkClass inkWithIdentifier:@"com.apple.ink.pen" color:UIColor.greenColor weight:100.0];
    RetainPtr<PKStroke> stroke = adoptNS([[pkStrokeClass alloc] _initWithPath:path.get() ink:ink.get() inputScale:1]);
    [drawing _addStroke:stroke.get()];

    [canvasView setDrawing:drawing.get()];
}

TEST(WKAttachmentTestsIOS, EditableImageAttachmentDataInvalidation)
{
    auto webView = webViewForTestingAttachments();

    RetainPtr<_WKAttachment> attachment;

    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        EXPECT_TRUE([webView _synchronouslyExecuteEditCommand:@"InsertEditableImage" argument:nil]);
        EXPECT_EQ(observer.observer().inserted.count, 1LU);
        attachment = observer.observer().inserted.firstObject;
    }

    [webView waitForNextPresentationUpdate];

    {
        ObserveAttachmentUpdatesForScope observer(webView.get());
        drawSquareInEditableImage(webView.get());
        observer.expectAttachmentInvalidation(@[ attachment.get() ]);
    }
}

#endif // HAVE(PENCILKIT)

#endif // PLATFORM(IOS_FAMILY)

} // namespace TestWebKitAPI

#endif // PLATFORM(MAC) || PLATFORM(IOS)
