1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "ios/web/web_state/web_view_internal_creation_util.h"
7 #import <CoreGraphics/CoreGraphics.h>
8 #import <WebKit/WebKit.h>
10 #include "base/mac/scoped_nsobject.h"
11 #include "base/message_loop/message_loop.h"
12 #include "ios/web/net/request_group_util.h"
13 #include "ios/web/public/test/test_browser_state.h"
14 #import "ios/web/public/test/test_web_client.h"
15 #include "ios/web/public/test/test_web_thread.h"
16 #include "ios/web/public/test/web_test_util.h"
17 #import "ios/web/public/web_view_creation_util.h"
18 #import "ios/web/web_state/ui/crw_debug_web_view.h"
19 #import "ios/web/web_state/ui/crw_simple_web_view_controller.h"
20 #import "ios/web/web_state/ui/crw_static_file_web_view.h"
21 #import "ios/web/web_state/ui/wk_web_view_configuration_provider.h"
22 #include "ios/web/test/web_test.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest_mac.h"
26 @interface CRWStaticFileWebView (Testing)
27 + (BOOL)isStaticFileUserAgent:(NSString*)userAgent;
33 const CGRect kTestFrame = CGRectMake(5.0f, 10.0f, 15.0f, 20.0f);
34 NSString* const kTestRequestGroupID = @"100042";
36 // Returns user agent for given UIWebView.
37 NSString* GetWebViewUserAgent(UIWebView* web_view) {
38 NSString* const kGetUserAgentJS = @"navigator.userAgent";
39 return [web_view stringByEvaluatingJavaScriptFromString:kGetUserAgentJS];
42 // A WebClient that stubs PreWebViewCreation/PostWebViewCreation calls for
44 class CreationUtilsWebClient : public TestWebClient {
46 MOCK_CONST_METHOD0(PreWebViewCreation, void());
47 MOCK_CONST_METHOD1(PostWebViewCreation, void(UIWebView* web_view));
50 class WebViewCreationUtilsTest : public WebTest {
52 WebViewCreationUtilsTest() {}
55 void SetUp() override {
58 [[NSUserDefaults standardUserDefaults] boolForKey:@"LogJavascript"];
59 original_web_client_ = GetWebClient();
60 SetWebClient(&creation_utils_web_client_);
61 creation_utils_web_client_.SetUserAgent("TestUA", false);
63 void TearDown() override {
64 SetWebClient(original_web_client_);
65 [[NSUserDefaults standardUserDefaults] setBool:logJavaScriptPref_
66 forKey:@"LogJavascript"];
69 // Sets up expectation for WebClient::PreWebViewCreation and
70 // WebClient::PostWebViewCreation calls. Captures UIWebView passed to
71 // PostWebViewCreation into captured_web_view param.
72 void ExpectWebClientCalls(UIWebView** captured_web_view) const {
73 EXPECT_CALL(creation_utils_web_client_, PreWebViewCreation()).Times(1);
74 EXPECT_CALL(creation_utils_web_client_, PostWebViewCreation(testing::_))
76 .WillOnce(testing::SaveArg<0>(captured_web_view));
80 // Original value of @"LogJavascript" pref from NSUserDefaults.
81 BOOL logJavaScriptPref_;
82 // WebClient that stubs PreWebViewCreation/PostWebViewCreation.
83 CreationUtilsWebClient creation_utils_web_client_;
84 // The WebClient that was set before this test was run.
85 WebClient* original_web_client_;
88 // Tests that a web view created with a certain id returns the same
89 // requestGroupID in the user agent string.
90 TEST_F(WebViewCreationUtilsTest, CreationWithRequestGroupID) {
91 UIWebView* captured_web_view = nil;
92 ExpectWebClientCalls(&captured_web_view);
94 base::scoped_nsobject<UIWebView> web_view(
95 CreateWebView(kTestFrame, kTestRequestGroupID, NO));
96 EXPECT_TRUE([web_view isMemberOfClass:[UIWebView class]]);
97 EXPECT_TRUE(CGRectEqualToRect(kTestFrame, [web_view frame]));
98 EXPECT_NSEQ(web_view, captured_web_view);
100 NSString* const kExpectedUserAgent =
101 [NSString stringWithFormat:@"TestUA (%@)", kTestRequestGroupID];
102 NSString* const kActualUserAgent = GetWebViewUserAgent(web_view);
103 EXPECT_NSEQ(kExpectedUserAgent, kActualUserAgent);
104 EXPECT_TRUE([ExtractRequestGroupIDFromUserAgent(kActualUserAgent)
105 isEqualToString:kTestRequestGroupID]);
108 // Tests that a web view not created for displaying static file content from
109 // the application bundle does not return a user agent that allows static file
111 TEST_F(WebViewCreationUtilsTest, CRWStaticFileWebViewFalse) {
112 base::scoped_nsobject<UIWebView> web_view(
113 CreateWebView(CGRectZero, kTestRequestGroupID, NO));
114 EXPECT_FALSE([CRWStaticFileWebView
115 isStaticFileUserAgent:GetWebViewUserAgent(web_view)]);
118 // Tests web::CreateWebView function that it correctly returns a UIWebView with
119 // the correct frame and calls WebClient::PreWebViewCreation/
120 // WebClient::PostWebViewCreation methods.
121 TEST_F(WebViewCreationUtilsTest, Creation) {
122 [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"LogJavascript"];
124 UIWebView* captured_web_view = nil;
125 ExpectWebClientCalls(&captured_web_view);
127 base::scoped_nsobject<UIWebView> web_view(CreateWebView(kTestFrame));
128 EXPECT_TRUE([web_view isMemberOfClass:[UIWebView class]]);
129 EXPECT_TRUE(CGRectEqualToRect(kTestFrame, [web_view frame]));
130 EXPECT_NSEQ(web_view, captured_web_view);
133 // Tests web::CreateWKWebView function that it correctly returns a WKWebView
134 // with the correct frame and WKProcessPool.
135 TEST_F(WebViewCreationUtilsTest, WKWebViewCreationWithBrowserState) {
136 CR_TEST_REQUIRES_WK_WEB_VIEW();
138 base::scoped_nsobject<WKWebView> web_view(
139 CreateWKWebView(kTestFrame, GetBrowserState()));
141 EXPECT_TRUE([web_view isKindOfClass:[WKWebView class]]);
142 EXPECT_TRUE(CGRectEqualToRect(kTestFrame, [web_view frame]));
144 // Make sure that web view's configuration shares the same process pool with
145 // browser state's configuration. Otherwise cookie will not be immediately
146 // shared between different web views.
147 WKWebViewConfigurationProvider& config_provider =
148 WKWebViewConfigurationProvider::FromBrowserState(GetBrowserState());
149 EXPECT_EQ(config_provider.GetWebViewConfiguration().processPool,
150 [[web_view configuration] processPool]);
153 // Tests that web::CreateWKWebView always returns a web view with the same
155 TEST_F(WebViewCreationUtilsTest, WKWebViewsShareProcessPool) {
156 CR_TEST_REQUIRES_WK_WEB_VIEW();
158 base::scoped_nsobject<WKWebView> web_view(
159 CreateWKWebView(kTestFrame, GetBrowserState()));
160 ASSERT_TRUE(web_view);
161 base::scoped_nsobject<WKWebView> web_view2(
162 CreateWKWebView(kTestFrame, GetBrowserState()));
163 ASSERT_TRUE(web_view2);
165 // Make sure that web views share the same non-nil process pool. Otherwise
166 // cookie will not be immediately shared between different web views.
167 EXPECT_TRUE([[web_view configuration] processPool]);
168 EXPECT_EQ([[web_view configuration] processPool],
169 [[web_view2 configuration] processPool]);
174 // Tests web::CreateWebView function that it correctly returns a CRWDebugWebView
175 // with the correct frame and calls WebClient::PreWebViewCreation/
176 // WebClient::PostWebViewCreation methods.
177 TEST_F(WebViewCreationUtilsTest, DebugCreation) {
178 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"LogJavascript"];
180 UIWebView* captured_web_view = nil;
181 ExpectWebClientCalls(&captured_web_view);
183 base::scoped_nsobject<UIWebView> web_view(CreateWebView(kTestFrame));
184 EXPECT_TRUE([web_view isMemberOfClass:[CRWDebugWebView class]]);
185 EXPECT_TRUE(CGRectEqualToRect(kTestFrame, [web_view frame]));
186 EXPECT_NSEQ(web_view, captured_web_view);
189 // Tests that getting a WKWebView from the util methods correctly maintains
190 // the global active wkwebview count (which is debug-only).
191 TEST_F(WebViewCreationUtilsTest, GetActiveWKWebViewsCount) {
192 CR_TEST_REQUIRES_WK_WEB_VIEW();
193 base::scoped_nsobject<WKWebView> web_view1(
194 CreateWKWebView(CGRectZero, GetBrowserState()));
195 EXPECT_EQ(1U, GetActiveWKWebViewsCount());
196 base::scoped_nsobject<WKWebView> web_view2(
197 CreateWKWebView(CGRectZero, GetBrowserState()));
198 EXPECT_EQ(2U, GetActiveWKWebViewsCount());
200 EXPECT_EQ(1U, GetActiveWKWebViewsCount());
202 EXPECT_EQ(0U, GetActiveWKWebViewsCount());
205 #endif // defined(NDEBUG)
207 // Tests web::CreateStaticFileWebView that it correctly returns a
208 // CRWStaticFileWebView with the correct frame, user agent, and calls
209 // WebClient::PreWebViewCreation/WebClient::PostWebViewCreation methods.
210 TEST_F(WebViewCreationUtilsTest, TestNewStaticFileWebViewTrue) {
211 UIWebView* captured_web_view = nil;
212 ExpectWebClientCalls(&captured_web_view);
214 base::scoped_nsobject<UIWebView> web_view(
215 CreateStaticFileWebView(kTestFrame, GetBrowserState()));
216 ASSERT_TRUE([web_view isMemberOfClass:[CRWStaticFileWebView class]]);
217 EXPECT_TRUE(CGRectEqualToRect(kTestFrame, [web_view frame]));
218 EXPECT_NSEQ(web_view, captured_web_view);
220 NSString* user_agent = GetWebViewUserAgent(web_view);
221 EXPECT_TRUE([CRWStaticFileWebView isStaticFileUserAgent:user_agent]);
224 // Tests web::CreateSimpleWebViewController returns a CRWSimpleWebViewController
225 // instance with a web view.
226 TEST_F(WebViewCreationUtilsTest, CreateSimpleWebViewController) {
227 base::scoped_nsprotocol<id<CRWSimpleWebViewController>>
228 simpleWebViewController(
229 CreateSimpleWebViewController(CGRectZero, nullptr, UI_WEB_VIEW_TYPE));
230 EXPECT_TRUE([simpleWebViewController view]);