Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: ios/web/web_state/ui/crw_web_controller_unittest.mm

Issue 2692803004: Refactor callbacks for opening a new window. (Closed)
Patch Set: Addressed review comment Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/web/web_state/ui/crw_web_controller.h" 5 #import "ios/web/web_state/ui/crw_web_controller.h"
6 6
7 #import <WebKit/WebKit.h> 7 #import <WebKit/WebKit.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 13 matching lines...) Expand all
24 #import "ios/web/public/test/fakes/test_web_view_content_view.h" 24 #import "ios/web/public/test/fakes/test_web_view_content_view.h"
25 #import "ios/web/public/web_state/crw_web_controller_observer.h" 25 #import "ios/web/public/web_state/crw_web_controller_observer.h"
26 #import "ios/web/public/web_state/ui/crw_content_view.h" 26 #import "ios/web/public/web_state/ui/crw_content_view.h"
27 #import "ios/web/public/web_state/ui/crw_native_content.h" 27 #import "ios/web/public/web_state/ui/crw_native_content.h"
28 #import "ios/web/public/web_state/ui/crw_native_content_provider.h" 28 #import "ios/web/public/web_state/ui/crw_native_content_provider.h"
29 #import "ios/web/public/web_state/ui/crw_web_view_content_view.h" 29 #import "ios/web/public/web_state/ui/crw_web_view_content_view.h"
30 #include "ios/web/public/web_state/url_verification_constants.h" 30 #include "ios/web/public/web_state/url_verification_constants.h"
31 #include "ios/web/public/web_state/web_state_observer.h" 31 #include "ios/web/public/web_state/web_state_observer.h"
32 #import "ios/web/test/web_test_with_web_controller.h" 32 #import "ios/web/test/web_test_with_web_controller.h"
33 #import "ios/web/test/wk_web_view_crash_utils.h" 33 #import "ios/web/test/wk_web_view_crash_utils.h"
34 #import "ios/web/web_state/blocked_popup_info.h"
35 #import "ios/web/web_state/ui/crw_web_controller_container_view.h" 34 #import "ios/web/web_state/ui/crw_web_controller_container_view.h"
36 #import "ios/web/web_state/web_state_impl.h" 35 #import "ios/web/web_state/web_state_impl.h"
37 #import "ios/web/web_state/wk_web_view_security_util.h" 36 #import "ios/web/web_state/wk_web_view_security_util.h"
38 #import "net/base/mac/url_conversions.h" 37 #import "net/base/mac/url_conversions.h"
39 #include "net/ssl/ssl_info.h" 38 #include "net/ssl/ssl_info.h"
40 #include "net/test/cert_test_util.h" 39 #include "net/test/cert_test_util.h"
41 #include "net/test/test_data_directory.h" 40 #include "net/test/test_data_directory.h"
42 #include "testing/gtest/include/gtest/gtest.h" 41 #include "testing/gtest/include/gtest/gtest.h"
43 #import "testing/gtest_mac.h" 42 #import "testing/gtest_mac.h"
44 #include "third_party/ocmock/OCMock/OCMock.h" 43 #include "third_party/ocmock/OCMock/OCMock.h"
45 #include "third_party/ocmock/gtest_support.h" 44 #include "third_party/ocmock/gtest_support.h"
46 #include "third_party/ocmock/ocmock_extensions.h" 45 #include "third_party/ocmock/ocmock_extensions.h"
47 #import "ui/base/test/ios/ui_view_test_utils.h" 46 #import "ui/base/test/ios/ui_view_test_utils.h"
48 47
49 using web::NavigationManagerImpl; 48 using web::NavigationManagerImpl;
50 49
51 @interface CRWWebController (PrivateAPI) 50 @interface CRWWebController (PrivateAPI)
52 @property(nonatomic, readwrite) web::PageDisplayState pageDisplayState; 51 @property(nonatomic, readwrite) web::PageDisplayState pageDisplayState;
53 - (GURL)URLForHistoryNavigationFromItem:(web::NavigationItem*)fromItem 52 - (GURL)URLForHistoryNavigationFromItem:(web::NavigationItem*)fromItem
54 toItem:(web::NavigationItem*)toItem; 53 toItem:(web::NavigationItem*)toItem;
55 @end 54 @end
56 55
57 // Used to mock CRWWebDelegate methods with C++ params. 56 // Used to mock CRWWebDelegate methods with C++ params.
58 @interface MockInteractionLoader : OCMockComplexTypeHelper 57 @interface MockInteractionLoader : OCMockComplexTypeHelper
59 // popupURL passed to webController:shouldBlockPopupWithURL:sourceURL:
60 // Used for testing.
61 @property(nonatomic, assign) GURL popupURL;
62 // sourceURL passed to webController:shouldBlockPopupWithURL:sourceURL:
63 // Used for testing.
64 @property(nonatomic, assign) GURL sourceURL;
65 // Whether or not the delegate should block popups. 58 // Whether or not the delegate should block popups.
66 @property(nonatomic, assign) BOOL blockPopups; 59 @property(nonatomic, assign) BOOL blockPopups;
67 // A web controller that will be returned by webPageOrdered... methods. 60 // A web controller that will be returned by webPageOrdered... methods.
68 @property(nonatomic, assign) CRWWebController* childWebController; 61 @property(nonatomic, assign) CRWWebController* childWebController;
69 // Blocked popup info received in |webController:didBlockPopup:| call. 62
70 // nullptr if that delegate method was not called. 63 // Values of arguments passed to
71 @property(nonatomic, readonly) web::BlockedPopupInfo* blockedPopupInfo; 64 // |webController:createWebControllerForURL:openerURL:initiatedByUser:|.
65 @property(nonatomic, readonly) CRWWebController* webController;
66 @property(nonatomic, readonly) GURL childURL;
67 @property(nonatomic, readonly) GURL openerURL;
68 @property(nonatomic, readonly) BOOL initiatedByUser;
72 @end 69 @end
73 70
74 @implementation MockInteractionLoader { 71 @implementation MockInteractionLoader
75 // Backs up the property with the same name. 72
76 std::unique_ptr<web::BlockedPopupInfo> _blockedPopupInfo;
77 }
78 @synthesize popupURL = _popupURL;
79 @synthesize sourceURL = _sourceURL;
80 @synthesize blockPopups = _blockPopups; 73 @synthesize blockPopups = _blockPopups;
81 @synthesize childWebController = _childWebController; 74 @synthesize childWebController = _childWebController;
82 75 @synthesize webController = _webController;
83 typedef void (^webPageOrderedOpenBlankBlockType)(); 76 @synthesize childURL = _childURL;
84 typedef void (^webPageOrderedOpenBlockType)(const GURL&, 77 @synthesize openerURL = _openerURL;
85 const web::Referrer&, 78 @synthesize initiatedByUser = _initiatedByUser;
86 NSString*,
87 BOOL);
88 79
89 - (instancetype)initWithRepresentedObject:(id)representedObject { 80 - (instancetype)initWithRepresentedObject:(id)representedObject {
90 self = [super initWithRepresentedObject:representedObject]; 81 self = [super initWithRepresentedObject:representedObject];
91 if (self) { 82 if (self) {
92 _blockPopups = YES; 83 _blockPopups = YES;
93 } 84 }
94 return self; 85 return self;
95 } 86 }
96 87
97 - (CRWWebController*)webPageOrderedOpen { 88 - (CRWWebController*)webController:(CRWWebController*)webController
98 static_cast<webPageOrderedOpenBlankBlockType>([self blockForSelector:_cmd])(); 89 createWebControllerForURL:(const GURL&)childURL
99 return _childWebController; 90 openerURL:(const GURL&)openerURL
100 } 91 initiatedByUser:(BOOL)initiatedByUser {
92 _webController = webController;
93 _childURL = childURL;
94 _openerURL = openerURL;
95 _initiatedByUser = initiatedByUser;
101 96
102 - (CRWWebController*)webPageOrderedOpen:(const GURL&)url 97 return (_blockPopups && !initiatedByUser) ? nil : _childWebController;
103 referrer:(const web::Referrer&)referrer
104 windowName:(NSString*)windowName
105 inBackground:(BOOL)inBackground {
106 static_cast<webPageOrderedOpenBlockType>([self blockForSelector:_cmd])(
107 url, referrer, windowName, inBackground);
108 return _childWebController;
109 } 98 }
110 99
111 typedef BOOL (^openExternalURLBlockType)(const GURL&); 100 typedef BOOL (^openExternalURLBlockType)(const GURL&);
112 101
113 - (BOOL)openExternalURL:(const GURL&)url { 102 - (BOOL)openExternalURL:(const GURL&)url {
114 return static_cast<openExternalURLBlockType>([self blockForSelector:_cmd])( 103 return static_cast<openExternalURLBlockType>([self blockForSelector:_cmd])(
115 url); 104 url);
116 } 105 }
117 106
118 - (BOOL)webController:(CRWWebController*)webController 107 - (BOOL)webController:(CRWWebController*)webController
119 shouldBlockPopupWithURL:(const GURL&)popupURL
120 sourceURL:(const GURL&)sourceURL {
121 self.popupURL = popupURL;
122 self.sourceURL = sourceURL;
123 return _blockPopups;
124 }
125
126 - (void)webController:(CRWWebController*)webController
127 didBlockPopup:(const web::BlockedPopupInfo&)blockedPopupInfo {
128 _blockedPopupInfo.reset(new web::BlockedPopupInfo(blockedPopupInfo));
129 }
130
131 - (web::BlockedPopupInfo*)blockedPopupInfo {
132 return _blockedPopupInfo.get();
133 }
134 - (BOOL)webController:(CRWWebController*)webController
135 shouldOpenURL:(const GURL&)URL 108 shouldOpenURL:(const GURL&)URL
136 mainDocumentURL:(const GURL&)mainDocumentURL 109 mainDocumentURL:(const GURL&)mainDocumentURL
137 linkClicked:(BOOL)linkClicked { 110 linkClicked:(BOOL)linkClicked {
138 return YES; 111 return YES;
139 } 112 }
140 @end 113 @end
141 114
142 @interface CountingObserver : NSObject<CRWWebControllerObserver> 115 @interface CountingObserver : NSObject<CRWWebControllerObserver>
143 116
144 @property(nonatomic, readonly) int pageLoadedCount; 117 @property(nonatomic, readonly) int pageLoadedCount;
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 [delegate_ setChildWebController:child_web_state_->GetWebController()]; 880 [delegate_ setChildWebController:child_web_state_->GetWebController()];
908 881
909 // Configure child web controller's session controller mock. 882 // Configure child web controller's session controller mock.
910 id sessionController = 883 id sessionController =
911 [OCMockObject niceMockForClass:[CRWSessionController class]]; 884 [OCMockObject niceMockForClass:[CRWSessionController class]];
912 BOOL yes = YES; 885 BOOL yes = YES;
913 [[[sessionController stub] andReturnValue:OCMOCK_VALUE(yes)] isOpenedByDOM]; 886 [[[sessionController stub] andReturnValue:OCMOCK_VALUE(yes)] isOpenedByDOM];
914 child_web_state_->GetNavigationManagerImpl().SetSessionController( 887 child_web_state_->GetNavigationManagerImpl().SetSessionController(
915 sessionController); 888 sessionController);
916 889
917 LoadHtml(@"<html><body></body></html>"); 890 LoadHtml(@"<html><body></body></html>", GURL("http://test"));
918 } 891 }
919 void TearDown() override { 892 void TearDown() override {
920 EXPECT_OCMOCK_VERIFY(delegate_); 893 EXPECT_OCMOCK_VERIFY(delegate_);
921 [web_controller() setDelegate:nil]; 894 [web_controller() setDelegate:nil];
922 895
923 web::WebTestWithWebController::TearDown(); 896 web::WebTestWithWebController::TearDown();
924 } 897 }
925 // Executes JavaScript that opens a new window and returns evaluation result 898 // Executes JavaScript that opens a new window and returns evaluation result
926 // as a string. 899 // as a string.
927 id OpenWindowByDOM() { 900 id OpenWindowByDOM() {
928 NSString* const kOpenWindowScript = 901 NSString* const kOpenWindowScript =
929 @"var w = window.open('javascript:void(0);', target='_blank');" 902 @"var w = window.open('javascript:void(0);', target='_blank');"
930 "w ? w.toString() : null;"; 903 "w ? w.toString() : null;";
931 id windowJSObject = ExecuteJavaScript(kOpenWindowScript); 904 id windowJSObject = ExecuteJavaScript(kOpenWindowScript);
932 WaitForBackgroundTasks(); 905 WaitForBackgroundTasks();
933 return windowJSObject; 906 return windowJSObject;
934 } 907 }
935 // A CRWWebDelegate mock used for testing. 908 // A CRWWebDelegate mock used for testing.
936 base::scoped_nsobject<id> delegate_; 909 base::scoped_nsobject<id> delegate_;
937 // A child WebState used for testing. 910 // A child WebState used for testing.
938 std::unique_ptr<web::WebStateImpl> child_web_state_; 911 std::unique_ptr<web::WebStateImpl> child_web_state_;
939 }; 912 };
940 913
941 // Tests that absence of web delegate is handled gracefully. 914 // Tests that absence of web delegate is handled gracefully.
942 TEST_F(CRWWebControllerWindowOpenTest, NoDelegate) { 915 TEST_F(CRWWebControllerWindowOpenTest, NoDelegate) {
943 [web_controller() setDelegate:nil]; 916 [web_controller() setDelegate:nil];
944 917
945 EXPECT_NSEQ([NSNull null], OpenWindowByDOM()); 918 EXPECT_NSEQ([NSNull null], OpenWindowByDOM());
946 919
947 EXPECT_FALSE([delegate_ blockedPopupInfo]); 920 EXPECT_FALSE([delegate_ webController]);
921 EXPECT_FALSE([delegate_ childURL].is_valid());
922 EXPECT_FALSE([delegate_ openerURL].is_valid());
923 EXPECT_FALSE([delegate_ initiatedByUser]);
948 } 924 }
949 925
950 // Tests that window.open triggered by user gesture opens a new non-popup 926 // Tests that window.open triggered by user gesture opens a new non-popup
951 // window. 927 // window.
952 TEST_F(CRWWebControllerWindowOpenTest, OpenWithUserGesture) { 928 TEST_F(CRWWebControllerWindowOpenTest, OpenWithUserGesture) {
953 SEL selector = @selector(webPageOrderedOpen);
954 [delegate_ onSelector:selector
955 callBlockExpectation:^(){
956 }];
957
958 [web_controller() touched:YES]; 929 [web_controller() touched:YES];
959 EXPECT_NSEQ(@"[object Window]", OpenWindowByDOM()); 930 EXPECT_NSEQ(@"[object Window]", OpenWindowByDOM());
960 EXPECT_FALSE([delegate_ blockedPopupInfo]); 931
932 EXPECT_EQ(web_controller(), [delegate_ webController]);
933 EXPECT_EQ("javascript:void(0);", [delegate_ childURL].spec());
934 EXPECT_EQ("http://test/", [delegate_ openerURL].spec());
935 EXPECT_TRUE([delegate_ initiatedByUser]);
961 } 936 }
962 937
963 // Tests that window.open executed w/o user gesture does not open a new window. 938 // Tests that window.open executed w/o user gesture does not open a new window.
964 // Once the blocked popup is allowed a new window is opened. 939 // Once the blocked popup is allowed a new window is opened.
965 TEST_F(CRWWebControllerWindowOpenTest, AllowPopup) { 940 TEST_F(CRWWebControllerWindowOpenTest, AllowPopup) {
966 SEL selector =
967 @selector(webPageOrderedOpen:referrer:windowName:inBackground:);
968 [delegate_ onSelector:selector
969 callBlockExpectation:^(const GURL& new_window_url,
970 const web::Referrer& referrer,
971 NSString* obsoleted_window_name,
972 BOOL in_background) {
973 EXPECT_EQ("javascript:void(0);", new_window_url.spec());
974 EXPECT_EQ("", referrer.url.spec());
975 EXPECT_FALSE(in_background);
976 }];
977
978 ASSERT_FALSE([web_controller() userIsInteracting]); 941 ASSERT_FALSE([web_controller() userIsInteracting]);
979 EXPECT_NSEQ([NSNull null], OpenWindowByDOM()); 942 EXPECT_NSEQ([NSNull null], OpenWindowByDOM());
980 base::test::ios::WaitUntilCondition(^bool() {
981 return [delegate_ blockedPopupInfo];
982 });
983 943
984 if ([delegate_ blockedPopupInfo]) 944 EXPECT_EQ(web_controller(), [delegate_ webController]);
985 [delegate_ blockedPopupInfo]->ShowPopup(); 945 EXPECT_EQ("javascript:void(0);", [delegate_ childURL].spec());
986 946 EXPECT_EQ("http://test/", [delegate_ openerURL].spec());
987 EXPECT_EQ("", [delegate_ sourceURL].spec()); 947 EXPECT_FALSE([delegate_ initiatedByUser]);
988 EXPECT_EQ("javascript:void(0);", [delegate_ popupURL].spec());
989 } 948 }
990 949
991 // Tests that window.open executed w/o user gesture opens a new window, assuming 950 // Tests that window.open executed w/o user gesture opens a new window, assuming
992 // that delegate allows popups. 951 // that delegate allows popups.
993 TEST_F(CRWWebControllerWindowOpenTest, DontBlockPopup) { 952 TEST_F(CRWWebControllerWindowOpenTest, DontBlockPopup) {
994 [delegate_ setBlockPopups:NO]; 953 [delegate_ setBlockPopups:NO];
995 SEL selector = @selector(webPageOrderedOpen); 954 EXPECT_NSEQ(@"[object Window]", OpenWindowByDOM());
996 [delegate_ onSelector:selector
997 callBlockExpectation:^(){
998 }];
999 955
1000 EXPECT_NSEQ(@"[object Window]", OpenWindowByDOM()); 956 EXPECT_EQ(web_controller(), [delegate_ webController]);
1001 EXPECT_FALSE([delegate_ blockedPopupInfo]); 957 EXPECT_EQ("javascript:void(0);", [delegate_ childURL].spec());
1002 958 EXPECT_EQ("http://test/", [delegate_ openerURL].spec());
1003 EXPECT_EQ("", [delegate_ sourceURL].spec()); 959 EXPECT_FALSE([delegate_ initiatedByUser]);
1004 EXPECT_EQ("javascript:void(0);", [delegate_ popupURL].spec());
1005 } 960 }
1006 961
1007 // Tests that window.open executed w/o user gesture does not open a new window. 962 // Tests that window.open executed w/o user gesture does not open a new window.
1008 TEST_F(CRWWebControllerWindowOpenTest, BlockPopup) { 963 TEST_F(CRWWebControllerWindowOpenTest, BlockPopup) {
1009 ASSERT_FALSE([web_controller() userIsInteracting]); 964 ASSERT_FALSE([web_controller() userIsInteracting]);
1010 EXPECT_NSEQ([NSNull null], OpenWindowByDOM()); 965 EXPECT_NSEQ([NSNull null], OpenWindowByDOM());
1011 base::test::ios::WaitUntilCondition(^bool() {
1012 return [delegate_ blockedPopupInfo];
1013 });
1014 966
1015 EXPECT_EQ("", [delegate_ sourceURL].spec()); 967 EXPECT_EQ(web_controller(), [delegate_ webController]);
1016 EXPECT_EQ("javascript:void(0);", [delegate_ popupURL].spec()); 968 EXPECT_EQ("javascript:void(0);", [delegate_ childURL].spec());
969 EXPECT_EQ("http://test/", [delegate_ openerURL].spec());
970 EXPECT_FALSE([delegate_ initiatedByUser]);
1017 }; 971 };
1018 972
1019 // Fixture class to test WKWebView crashes. 973 // Fixture class to test WKWebView crashes.
1020 class CRWWebControllerWebProcessTest : public web::WebTestWithWebController { 974 class CRWWebControllerWebProcessTest : public web::WebTestWithWebController {
1021 protected: 975 protected:
1022 void SetUp() override { 976 void SetUp() override {
1023 web::WebTestWithWebController::SetUp(); 977 web::WebTestWithWebController::SetUp();
1024 webView_.reset([web::BuildTerminatedWKWebView() retain]); 978 webView_.reset([web::BuildTerminatedWKWebView() retain]);
1025 base::scoped_nsobject<TestWebViewContentView> webViewContentView( 979 base::scoped_nsobject<TestWebViewContentView> webViewContentView(
1026 [[TestWebViewContentView alloc] 980 [[TestWebViewContentView alloc]
(...skipping 28 matching lines...) Expand all
1055 }; 1009 };
1056 1010
1057 RenderProcessGoneObserver observer(web_state()); 1011 RenderProcessGoneObserver observer(web_state());
1058 web::SimulateWKWebViewCrash(webView_); 1012 web::SimulateWKWebViewCrash(webView_);
1059 observer.WaitForRenderProcessGone(); 1013 observer.WaitForRenderProcessGone();
1060 1014
1061 EXPECT_FALSE([web_controller() isViewAlive]); 1015 EXPECT_FALSE([web_controller() isViewAlive]);
1062 }; 1016 };
1063 1017
1064 } // namespace 1018 } // namespace
OLDNEW
« ios/chrome/browser/tabs/tab.mm ('K') | « ios/web/web_state/ui/crw_web_controller.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698