[WK2] Add API to query if a download was user-initiated
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / Download.mm
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import <WebKit/WKFoundation.h>
28
29 #if WK_API_ENABLED
30 #if PLATFORM(MAC) // No downloading on iOS
31
32 #import "PlatformUtilities.h"
33 #import "Test.h"
34 #import "TestProtocol.h"
35 #import "TestWKWebView.h"
36 #import <WebCore/FileSystem.h>
37 #import <WebKit/_WKDownload.h>
38 #import <WebKit/_WKDownloadDelegate.h>
39 #import <WebKit/WKNavigationDelegatePrivate.h>
40 #import <WebKit/WKProcessPoolPrivate.h>
41 #import <WebKit/WKUIDelegatePrivate.h>
42 #import <WebKit/WKWebView.h>
43 #import <WebKit/WKWebViewConfiguration.h>
44 #import <wtf/RetainPtr.h>
45 #import <wtf/mac/AppKitCompatibilityDeclarations.h>
46 #import <wtf/text/WTFString.h>
47
48 static bool isDone;
49 static unsigned redirectCount = 0;
50 static bool hasReceivedResponse;
51 static NSURL *sourceURL = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
52 static WKWebView* expectedOriginatingWebView;
53 static bool expectedUserInitiatedState = false;
54
55 @interface DownloadDelegate : NSObject <_WKDownloadDelegate>
56 @end
57
58 @implementation DownloadDelegate {
59     RetainPtr<_WKDownload> _download;
60     String _destinationPath;
61     long long _expectedContentLength;
62     uint64_t _receivedContentLength;
63 }
64
65 - (void)_downloadDidStart:(_WKDownload *)download
66 {
67     EXPECT_NULL(_download);
68     EXPECT_NOT_NULL(download);
69     EXPECT_TRUE([[[[download request] URL] path] isEqualToString:[sourceURL path]]);
70     EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
71     _download = download;
72 }
73
74 - (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
75 {
76     hasReceivedResponse = true;
77     EXPECT_EQ(_download, download);
78     EXPECT_TRUE(_expectedContentLength == 0);
79     EXPECT_TRUE(_receivedContentLength == 0);
80     EXPECT_TRUE([[[response URL] path] isEqualToString:[sourceURL path]]);
81     _expectedContentLength = [response expectedContentLength];
82 }
83
84 - (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
85 {
86     EXPECT_EQ(_download, download);
87     _receivedContentLength += length;
88 }
89
90 - (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
91 {
92     EXPECT_TRUE(hasReceivedResponse);
93     EXPECT_EQ(_download, download);
94
95     WebCore::PlatformFileHandle fileHandle;
96     _destinationPath = WebCore::openTemporaryFile("TestWebKitAPI", fileHandle);
97     EXPECT_TRUE(fileHandle != WebCore::invalidPlatformFileHandle);
98     WebCore::closeFile(fileHandle);
99
100     *allowOverwrite = YES;
101     return _destinationPath;
102 }
103
104 - (void)_downloadDidFinish:(_WKDownload *)download
105 {
106     EXPECT_EQ(_download, download);
107     EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
108     EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast<uint64_t>(_expectedContentLength) == _receivedContentLength);
109     EXPECT_TRUE([[NSFileManager defaultManager] contentsEqualAtPath:_destinationPath andPath:[sourceURL path]]);
110     WebCore::deleteFile(_destinationPath);
111     isDone = true;
112 }
113
114 @end
115
116 TEST(_WKDownload, DownloadDelegate)
117 {
118     RetainPtr<WKProcessPool> processPool = adoptNS([[WKProcessPool alloc] init]);
119     DownloadDelegate *downloadDelegate = [[DownloadDelegate alloc] init];
120     [processPool _setDownloadDelegate:downloadDelegate];
121
122     @autoreleasepool {
123         EXPECT_EQ(downloadDelegate, [processPool _downloadDelegate]);
124     }
125
126     [downloadDelegate release];
127     EXPECT_NULL([processPool _downloadDelegate]);
128 }
129
130 static void runTest(id <WKNavigationDelegate> navigationDelegate, id <_WKDownloadDelegate> downloadDelegate, NSURL *url)
131 {
132     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
133     [webView setNavigationDelegate:navigationDelegate];
134     [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate];
135
136     isDone = false;
137     hasReceivedResponse = false;
138     expectedUserInitiatedState = false;
139     [webView loadRequest:[NSURLRequest requestWithURL:url]];
140     TestWebKitAPI::Util::run(&isDone);
141 }
142
143 @interface DownloadNavigationDelegate : NSObject <WKNavigationDelegate>
144 @end
145
146 @implementation DownloadNavigationDelegate
147 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
148 {
149     decisionHandler(_WKNavigationActionPolicyDownload);
150 }
151 @end
152
153 TEST(_WKDownload, DownloadRequest)
154 {
155     runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[DownloadDelegate alloc] init]).get(), sourceURL);
156 }
157
158 @interface ConvertResponseToDownloadNavigationDelegate : NSObject <WKNavigationDelegate>
159 @end
160
161 @implementation ConvertResponseToDownloadNavigationDelegate
162 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
163 {
164     decisionHandler(_WKNavigationResponsePolicyBecomeDownload);
165 }
166 @end
167
168 TEST(_WKDownload, ConvertResponseToDownload)
169 {
170     runTest(adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]).get(), adoptNS([[DownloadDelegate alloc] init]).get(), sourceURL);
171 }
172
173 @interface FailingDownloadDelegate : NSObject <_WKDownloadDelegate>
174 @end
175
176 @implementation FailingDownloadDelegate
177
178 - (void)_downloadDidFinish:(_WKDownload *)download
179 {
180     EXPECT_TRUE(false);
181     isDone = true;
182 }
183
184 - (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
185 {
186     isDone = true;
187 }
188
189 - (void)_downloadDidCancel:(_WKDownload *)download
190 {
191     EXPECT_TRUE(false);
192     isDone = true;
193 }
194
195 @end
196
197 TEST(_WKDownload, DownloadMissingResource)
198 {
199     runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[FailingDownloadDelegate alloc] init]).get(), [NSURL URLWithString:@"non-existant-scheme://"]);
200 }
201
202 @interface CancelledDownloadDelegate : NSObject <_WKDownloadDelegate>
203 @end
204
205 @implementation CancelledDownloadDelegate
206
207 - (void)_downloadDidStart:(_WKDownload *)download
208 {
209     [download cancel];
210 }
211
212 - (void)_downloadDidFinish:(_WKDownload *)download
213 {
214     EXPECT_TRUE(false);
215     isDone = true;
216 }
217
218 - (void)_download:(_WKDownload *)download didFailWithError:(NSError *)error
219 {
220     EXPECT_TRUE(false);
221     isDone = true;
222 }
223
224 - (void)_downloadDidCancel:(_WKDownload *)download
225 {
226     isDone = true;
227 }
228
229 @end
230
231 TEST(_WKDownload, CancelDownload)
232 {
233     runTest(adoptNS([[DownloadNavigationDelegate alloc] init]).get(), adoptNS([[CancelledDownloadDelegate alloc] init]).get(), sourceURL);
234 }
235
236 @interface OriginatingWebViewDownloadDelegate : NSObject <_WKDownloadDelegate>
237 - (instancetype)initWithWebView:(WKWebView *)webView;
238 @end
239
240 @implementation OriginatingWebViewDownloadDelegate {
241     RetainPtr<WKWebView> _webView;
242 }
243
244 - (instancetype)initWithWebView:(WKWebView *)webView
245 {
246     if (!(self = [super init]))
247         return nil;
248
249     _webView = webView;
250     return self;
251 }
252
253 - (void)_downloadDidStart:(_WKDownload *)download
254 {
255     @autoreleasepool {
256         EXPECT_EQ([download originatingWebView], _webView);
257     }
258
259     _webView = nullptr;
260     EXPECT_NULL([download originatingWebView]);
261     isDone = true;
262 }
263
264 @end
265
266 TEST(_WKDownload, OriginatingWebView)
267 {
268     RetainPtr<DownloadNavigationDelegate> navigationDelegate = adoptNS([[DownloadNavigationDelegate alloc] init]);                 
269     RetainPtr<OriginatingWebViewDownloadDelegate> downloadDelegate;
270     @autoreleasepool {
271         RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
272         [webView setNavigationDelegate:navigationDelegate.get()];
273         downloadDelegate = adoptNS([[OriginatingWebViewDownloadDelegate alloc] initWithWebView:webView.get()]);
274         [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
275         [webView loadRequest:[NSURLRequest requestWithURL:sourceURL]];
276     }
277
278     isDone = false;
279     TestWebKitAPI::Util::run(&isDone);
280 }
281
282 @interface DownloadRequestOriginalURLDelegate : NSObject <_WKDownloadDelegate>
283 - (instancetype)initWithExpectedOriginalURL:(NSURL *)expectOriginalURL;
284 @end
285
286 @implementation DownloadRequestOriginalURLDelegate {
287     NSURL *_expectedOriginalURL;
288 }
289
290 - (instancetype)initWithExpectedOriginalURL:(NSURL *)expectedOriginalURL
291 {
292     if (!(self = [super init]))
293         return nil;
294
295     _expectedOriginalURL = expectedOriginalURL;
296     return self;
297 }
298
299 - (void)_downloadDidStart:(_WKDownload *)download
300 {
301     if ([_expectedOriginalURL isEqual:sourceURL])
302         EXPECT_TRUE(!download.request.mainDocumentURL);
303     else
304         EXPECT_TRUE([_expectedOriginalURL isEqual:download.request.mainDocumentURL]);
305     isDone = true;
306 }
307
308 @end
309
310 @interface DownloadRequestOriginalURLNavigationDelegate : NSObject <WKNavigationDelegate>
311 @end
312
313 @implementation DownloadRequestOriginalURLNavigationDelegate
314 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
315 {
316     if ([navigationAction.request.URL isEqual:sourceURL])
317         decisionHandler(_WKNavigationActionPolicyDownload);
318     else
319         decisionHandler(WKNavigationActionPolicyAllow);
320 }
321 @end
322
323 TEST(_WKDownload, DownloadRequestOriginalURL)
324 {
325     NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestOriginalURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
326     runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:originalURL]).get(), originalURL);
327 }
328
329 TEST(_WKDownload, DownloadRequestOriginalURLFrame)
330 {
331     NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestOriginalURL2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
332     runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:originalURL]).get(), originalURL);
333 }
334
335 TEST(_WKDownload, DownloadRequestOriginalURLDirectDownload)
336 {
337     runTest(adoptNS([[DownloadRequestOriginalURLNavigationDelegate alloc] init]).get(), adoptNS([[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:sourceURL]).get(), sourceURL);
338 }
339
340 TEST(_WKDownload, DownloadRequestOriginalURLDirectDownloadWithLoadedContent)
341 {
342     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
343     [webView setNavigationDelegate:[[DownloadRequestOriginalURLNavigationDelegate alloc] init]];
344     [[[webView configuration] processPool] _setDownloadDelegate:[[DownloadRequestOriginalURLDelegate alloc] initWithExpectedOriginalURL:sourceURL]];
345
346     expectedUserInitiatedState = false;
347     NSURL *contentURL = [[NSBundle mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
348     // Here is to test if the original URL can be set correctly when the current document
349     // is completely unrelated to the download.
350     [webView loadRequest:[NSURLRequest requestWithURL:contentURL]];
351     [webView loadRequest:[NSURLRequest requestWithURL:sourceURL]];
352     isDone = false;
353     TestWebKitAPI::Util::run(&isDone);
354 }
355
356 @interface BlobDownloadDelegate : NSObject <_WKDownloadDelegate>
357 @end
358
359 @implementation BlobDownloadDelegate {
360     RetainPtr<_WKDownload> _download;
361     String _destinationPath;
362     long long _expectedContentLength;
363     uint64_t _receivedContentLength;
364 }
365
366 - (void)_downloadDidStart:(_WKDownload *)download
367 {
368     EXPECT_NULL(_download);
369     EXPECT_NOT_NULL(download);
370     EXPECT_TRUE([[[[download request] URL] scheme] isEqualToString:@"blob"]);
371     EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
372     _download = download;
373 }
374
375 - (void)_download:(_WKDownload *)download didReceiveResponse:(NSURLResponse *)response
376 {
377     hasReceivedResponse = true;
378     EXPECT_EQ(_download, download);
379     EXPECT_EQ(_expectedContentLength, 0U);
380     EXPECT_EQ(_receivedContentLength, 0U);
381     EXPECT_TRUE([[[response URL] scheme] isEqualToString:@"blob"]);
382     _expectedContentLength = [response expectedContentLength];
383 }
384
385 - (void)_download:(_WKDownload *)download didReceiveData:(uint64_t)length
386 {
387     EXPECT_EQ(_download, download);
388     _receivedContentLength += length;
389 }
390
391 - (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
392 {
393     EXPECT_TRUE(hasReceivedResponse);
394     EXPECT_EQ(_download, download);
395
396     WebCore::PlatformFileHandle fileHandle;
397     _destinationPath = WebCore::openTemporaryFile("TestWebKitAPI", fileHandle);
398     EXPECT_TRUE(fileHandle != WebCore::invalidPlatformFileHandle);
399     WebCore::closeFile(fileHandle);
400
401     *allowOverwrite = YES;
402     return _destinationPath;
403 }
404
405 - (void)_downloadDidFinish:(_WKDownload *)download
406 {
407     EXPECT_EQ(_download, download);
408     EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
409     EXPECT_TRUE(_expectedContentLength == NSURLResponseUnknownLength || static_cast<uint64_t>(_expectedContentLength) == _receivedContentLength);
410     NSString* expectedContent = @"{\"x\":42,\"s\":\"hello, world\"}";
411     NSData* expectedData = [expectedContent dataUsingEncoding:NSUTF8StringEncoding];
412     EXPECT_TRUE([[[NSFileManager defaultManager] contentsAtPath:_destinationPath] isEqualToData:expectedData]);
413     WebCore::deleteFile(_destinationPath);
414     isDone = true;
415 }
416
417 @end
418
419 @interface DownloadBlobURLNavigationDelegate : NSObject <WKNavigationDelegate>
420 @end
421
422 @implementation DownloadBlobURLNavigationDelegate
423 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
424 {
425     if ([navigationAction.request.URL.scheme isEqualToString:@"blob"])
426         decisionHandler(_WKNavigationActionPolicyDownload);
427     else
428         decisionHandler(WKNavigationActionPolicyAllow);
429 }
430 @end
431
432 TEST(_WKDownload, DownloadRequestBlobURL)
433 {
434     NSURL *originalURL = [[NSBundle mainBundle] URLForResource:@"DownloadRequestBlobURL" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
435     runTest(adoptNS([[DownloadBlobURLNavigationDelegate alloc] init]).get(), adoptNS([[BlobDownloadDelegate alloc] init]).get(), originalURL);
436 }
437
438 @interface UIDownloadAsFileTestDelegate : NSObject <WKUIDelegatePrivate>
439 @end
440
441 @implementation UIDownloadAsFileTestDelegate
442
443 - (NSMenu *)_webView:(WKWebView *)webView contextMenu:(NSMenu *)menu forElement:(_WKContextMenuElementInfo *)element
444 {
445     static const long downloadLinkedFileTag = 2;
446     auto index = [menu indexOfItemWithTag:downloadLinkedFileTag];
447     [menu performActionForItemAtIndex:index];
448     return nil;
449 }
450
451 @end
452
453 @interface RedirectedDownloadDelegate : NSObject <_WKDownloadDelegate>
454 @end
455
456 @implementation RedirectedDownloadDelegate {
457     String _destinationPath;
458 }
459
460 - (void)_downloadDidStart:(_WKDownload *)download
461 {
462     EXPECT_NOT_NULL(download);
463     EXPECT_EQ(expectedOriginatingWebView, download.originatingWebView);
464     EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
465 }
466
467 - (NSString *)_download:(_WKDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename allowOverwrite:(BOOL *)allowOverwrite
468 {
469     WebCore::PlatformFileHandle fileHandle;
470     _destinationPath = WebCore::openTemporaryFile("TestWebKitAPI", fileHandle);
471     EXPECT_TRUE(fileHandle != WebCore::invalidPlatformFileHandle);
472     WebCore::closeFile(fileHandle);
473     *allowOverwrite = YES;
474     return _destinationPath;
475 }
476
477 - (void)_download:(_WKDownload *)download didReceiveServerRedirectToURL:(NSURL *)url
478 {
479     if (!redirectCount)
480         EXPECT_STREQ("http://redirect/?pass", [url.absoluteString UTF8String]);
481     else
482         EXPECT_STREQ("http://pass/", [url.absoluteString UTF8String]);
483     ++redirectCount = true;
484 }
485
486 - (void)_downloadDidFinish:(_WKDownload *)download
487 {
488     EXPECT_EQ(expectedUserInitiatedState, download.wasUserInitiated);
489
490     NSArray<NSURL *> *redirectChain = download.redirectChain;
491     EXPECT_EQ(3U, redirectChain.count);
492     if (redirectChain.count > 0)
493         EXPECT_STREQ("http://redirect/?redirect/?pass", [redirectChain[0].absoluteString UTF8String]);
494     if (redirectChain.count > 1)
495         EXPECT_STREQ("http://redirect/?pass", [redirectChain[1].absoluteString UTF8String]);
496     if (redirectChain.count > 2)
497         EXPECT_STREQ("http://pass/", [redirectChain[2].absoluteString UTF8String]);
498
499     WebCore::deleteFile(_destinationPath);
500     isDone = true;
501 }
502
503 @end
504
505 TEST(_WKDownload, RedirectedDownload)
506 {
507     [TestProtocol registerWithScheme:@"http"];
508
509     redirectCount = 0;
510     isDone = false;
511
512     auto delegate = adoptNS([[UIDownloadAsFileTestDelegate alloc] init]);
513     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
514     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
515     [webView setUIDelegate:delegate.get()];
516     auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
517     [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
518
519     auto window = adoptNS([[NSWindow alloc] initWithContentRect:[webView frame] styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:YES]);
520     [[window contentView] addSubview:webView.get()];
521
522     // Do 2 loads in the same view to make sure the redirect chain is properly cleared between loads.
523     [webView synchronouslyLoadHTMLString:@"<div>First load</div>"];
524     [webView synchronouslyLoadHTMLString:@"<a style='display: block; height: 100%; width: 100%' href='http://redirect/?redirect/?pass'>test</a>"];
525
526     expectedOriginatingWebView = webView.get();
527     expectedUserInitiatedState = true;
528     NSPoint clickPoint = NSMakePoint(100, 100);
529     [[webView hitTest:clickPoint] mouseDown:[NSEvent mouseEventWithType:NSEventTypeRightMouseDown location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
530     [[webView hitTest:clickPoint] mouseUp:[NSEvent mouseEventWithType:NSEventTypeRightMouseUp location:clickPoint modifierFlags:0 timestamp:0 windowNumber:[window windowNumber] context:nil eventNumber:0 clickCount:1 pressure:1]];
531
532     isDone = false;
533     TestWebKitAPI::Util::run(&isDone);
534     EXPECT_EQ(1U, redirectCount);
535
536     [TestProtocol unregister];
537 }
538
539 TEST(_WKDownload, RedirectedLoadConvertedToDownload)
540 {
541     [TestProtocol registerWithScheme:@"http"];
542
543     auto navigationDelegate = adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]);
544     auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
545
546     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
547     [webView setNavigationDelegate:navigationDelegate.get()];
548     [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
549
550     expectedOriginatingWebView = webView.get();
551     expectedUserInitiatedState = false;
552     isDone = false;
553     redirectCount = 0;
554     hasReceivedResponse = false;
555     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://redirect/?redirect/?pass"]]];
556     TestWebKitAPI::Util::run(&isDone);
557     EXPECT_EQ(0U, redirectCount);
558
559     [TestProtocol unregister];
560 }
561
562 TEST(_WKDownload, RedirectedSubframeLoadConvertedToDownload)
563 {
564     [TestProtocol registerWithScheme:@"http"];
565
566     auto navigationDelegate = adoptNS([[ConvertResponseToDownloadNavigationDelegate alloc] init]);
567     auto downloadDelegate = adoptNS([[RedirectedDownloadDelegate alloc] init]);
568
569     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
570     [webView setNavigationDelegate:navigationDelegate.get()];
571     [[[webView configuration] processPool] _setDownloadDelegate:downloadDelegate.get()];
572
573     expectedOriginatingWebView = webView.get();
574     expectedUserInitiatedState = false;
575     isDone = false;
576     redirectCount = 0;
577     hasReceivedResponse = false;
578     [webView loadHTMLString:@"<body><iframe src='http://redirect/?redirect/?pass'></iframe></body>" baseURL:nil];
579     TestWebKitAPI::Util::run(&isDone);
580     EXPECT_EQ(0U, redirectCount);
581
582     [TestProtocol unregister];
583 }
584
585 #endif
586 #endif