/*
 * 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/WKWebViewPrivateForTesting.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)
