1 // Copyright 2015 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/ui/wk_web_view_configuration_provider.h"
7 #import <WebKit/WebKit.h>
9 #import "base/ios/weak_nsobject.h"
10 #include "ios/web/public/test/test_browser_state.h"
11 #include "ios/web/public/test/web_test_util.h"
12 #include "ios/web/public/web_client.h"
13 #import "ios/web/web_state/js/page_script_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/gtest_mac.h"
16 #include "testing/platform_test.h"
21 class WKWebViewConfigurationProviderTest : public PlatformTest {
23 void SetUp() override {
24 PlatformTest::SetUp();
25 SetWebClient(&web_client_);
27 void TearDown() override {
28 SetWebClient(nullptr);
29 PlatformTest::TearDown();
31 // Returns WKWebViewConfigurationProvider associated with |browser_state_|.
32 WKWebViewConfigurationProvider& GetProvider() {
33 return GetProvider(&browser_state_);
35 // Returns WKWebViewConfigurationProvider for given |browser_state|.
36 WKWebViewConfigurationProvider& GetProvider(
37 BrowserState* browser_state) const {
38 return WKWebViewConfigurationProvider::FromBrowserState(browser_state);
40 // BrowserState required for WKWebViewConfigurationProvider creation.
41 TestBrowserState browser_state_;
44 // WebClient required for getting early page script.
45 WebClient web_client_;
48 // Tests that each WKWebViewConfigurationProvider has own, non-nil
49 // configuration and configurations returned by the same provider will always
50 // have the same process pool.
51 TEST_F(WKWebViewConfigurationProviderTest, ConfigurationOwnerhip) {
52 CR_TEST_REQUIRES_WK_WEB_VIEW();
54 // Configuration is not nil.
55 WKWebViewConfigurationProvider& provider = GetProvider(&browser_state_);
56 ASSERT_TRUE(provider.GetWebViewConfiguration());
58 // Same non-nil WKProcessPool for the same provider.
59 ASSERT_TRUE(provider.GetWebViewConfiguration().processPool);
60 EXPECT_EQ(provider.GetWebViewConfiguration().processPool,
61 provider.GetWebViewConfiguration().processPool);
63 // Different WKProcessPools for different providers.
64 TestBrowserState other_browser_state;
65 WKWebViewConfigurationProvider& other_provider =
66 GetProvider(&other_browser_state);
67 EXPECT_NE(provider.GetWebViewConfiguration().processPool,
68 other_provider.GetWebViewConfiguration().processPool);
71 // Tests that internal configuration object can not be changed by clients.
72 TEST_F(WKWebViewConfigurationProviderTest, ConfigurationProtection) {
73 CR_TEST_REQUIRES_WK_WEB_VIEW();
75 WKWebViewConfigurationProvider& provider = GetProvider(&browser_state_);
76 WKWebViewConfiguration* config = provider.GetWebViewConfiguration();
77 base::scoped_nsobject<WKProcessPool> pool([[config processPool] retain]);
78 base::scoped_nsobject<WKPreferences> prefs([[config preferences] retain]);
79 base::scoped_nsobject<WKUserContentController> userContentController(
80 [[config userContentController] retain]);
82 // nil-out the properties of returned configuration object.
83 config.processPool = nil;
84 config.preferences = nil;
85 config.userContentController = nil;
87 // Make sure that the properties of internal configuration were not changed.
88 EXPECT_TRUE(provider.GetWebViewConfiguration().processPool);
89 EXPECT_EQ(pool.get(), provider.GetWebViewConfiguration().processPool);
90 EXPECT_TRUE(provider.GetWebViewConfiguration().preferences);
91 EXPECT_EQ(prefs.get(), provider.GetWebViewConfiguration().preferences);
92 EXPECT_TRUE(provider.GetWebViewConfiguration().userContentController);
93 EXPECT_EQ(userContentController.get(),
94 provider.GetWebViewConfiguration().userContentController);
97 // Tests that |HasWebViewConfiguration| returns false by default.
98 TEST_F(WKWebViewConfigurationProviderTest, NoConfigurationByDefault) {
99 CR_TEST_REQUIRES_WK_WEB_VIEW();
101 EXPECT_FALSE(GetProvider().HasWebViewConfiguration());
104 // Tests that |HasWebViewConfiguration| returns true after
105 // |GetWebViewConfiguration| call and false after |Purge| call.
106 TEST_F(WKWebViewConfigurationProviderTest, HasWebViewConfiguration) {
107 CR_TEST_REQUIRES_WK_WEB_VIEW();
109 // Valid configuration after |GetWebViewConfiguration| call.
110 @autoreleasepool { // Make sure that resulting copy is deallocated.
111 GetProvider().GetWebViewConfiguration();
113 EXPECT_TRUE(GetProvider().HasWebViewConfiguration());
115 // No configuration after |Purge| call.
116 GetProvider().Purge();
117 EXPECT_FALSE(GetProvider().HasWebViewConfiguration());
119 // Valid configuration after |GetWebViewConfiguration| call.
120 GetProvider().GetWebViewConfiguration();
121 EXPECT_TRUE(GetProvider().HasWebViewConfiguration());
124 // Tests that configuration is deallocated after |Purge| call.
125 TEST_F(WKWebViewConfigurationProviderTest, Purge) {
126 CR_TEST_REQUIRES_WK_WEB_VIEW();
128 base::WeakNSObject<id> config;
129 @autoreleasepool { // Make sure that resulting copy is deallocated.
130 config.reset(GetProvider().GetWebViewConfiguration());
134 // No configuration after |Purge| call.
135 GetProvider().Purge();
136 EXPECT_FALSE(config);
139 // Tests that configuration's userContentController has only one script with the
140 // same content as web::GetEarlyPageScript(WK_WEB_VIEW_TYPE) returns.
141 TEST_F(WKWebViewConfigurationProviderTest, UserScript) {
142 CR_TEST_REQUIRES_WK_WEB_VIEW();
144 WKWebViewConfiguration* config = GetProvider().GetWebViewConfiguration();
145 NSArray* scripts = config.userContentController.userScripts;
146 EXPECT_EQ(1U, scripts.count);
147 NSString* early_script = GetEarlyPageScript(WK_WEB_VIEW_TYPE);
148 // |earlyScript| is a substring of |userScripts|. The latter wraps the
149 // former with "if (!injected)" check to avoid double injections.
150 EXPECT_LT(0U, [[scripts[0] source] rangeOfString:early_script].length);