OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import "ios/chrome/browser/ui/static_content/static_html_view_controller.h" |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #import "base/mac/foundation_util.h" |
| 10 #include "base/mac/scoped_nsautorelease_pool.h" |
| 11 #include "base/mac/scoped_nsobject.h" |
| 12 #include "base/memory/ptr_util.h" |
| 13 #import "base/test/ios/wait_util.h" |
| 14 #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" |
| 15 #import "ios/chrome/browser/ui/url_loader.h" |
| 16 #include "ios/chrome/grit/ios_strings.h" |
| 17 #import "ios/testing/ocmock_complex_type_helper.h" |
| 18 #include "ios/web/public/referrer.h" |
| 19 #import "ios/web/public/test/js_test_util.h" |
| 20 #include "ios/web/public/test/scoped_testing_web_client.h" |
| 21 #import "ios/web/public/test/test_web_client.h" |
| 22 #include "ios/web/public/test/test_web_thread_bundle.h" |
| 23 #import "ios/web/public/web_state/ui/crw_native_content.h" |
| 24 #import "net/base/mac/url_conversions.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" |
| 26 #include "testing/gtest_mac.h" |
| 27 #include "testing/platform_test.h" |
| 28 #import "third_party/ocmock/OCMock/OCMock.h" |
| 29 #include "third_party/ocmock/gtest_support.h" |
| 30 #include "ui/base/l10n/l10n_util_mac.h" |
| 31 |
| 32 // Generator that returns the value of a localized identifier. |
| 33 @interface L10nHtmlGenerator : NSObject<HtmlGenerator> { |
| 34 @private |
| 35 int messageId_; |
| 36 } |
| 37 - (id)initWithMessageId:(int)messageId; |
| 38 @end |
| 39 |
| 40 @implementation L10nHtmlGenerator |
| 41 - (id)initWithMessageId:(int)messageId { |
| 42 if ((self = [super init])) { |
| 43 messageId_ = messageId; |
| 44 } |
| 45 return self; |
| 46 } |
| 47 - (void)generateHtml:(HtmlCallback)callback { |
| 48 callback(l10n_util::GetNSString(messageId_)); |
| 49 } |
| 50 @end |
| 51 |
| 52 @interface LoadTestMockLoader : OCMockComplexTypeHelper |
| 53 @end |
| 54 |
| 55 @implementation LoadTestMockLoader |
| 56 |
| 57 typedef void (^LoadURL_Referrer_transition_renderInitiated)( |
| 58 const GURL&, |
| 59 const web::Referrer&, |
| 60 ui::PageTransition, |
| 61 BOOL); |
| 62 |
| 63 - (void)loadURL:(const GURL&)url |
| 64 referrer:(const web::Referrer&)referrer |
| 65 transition:(ui::PageTransition)transition |
| 66 rendererInitiated:(BOOL)rendererInitiated { |
| 67 static_cast<LoadURL_Referrer_transition_renderInitiated>([self |
| 68 blockForSelector:_cmd])(url, referrer, transition, rendererInitiated); |
| 69 } |
| 70 |
| 71 @end |
| 72 |
| 73 namespace { |
| 74 |
| 75 bool isRunLoopDry = true; |
| 76 |
| 77 // Wait until either all event in the run loop at the time of execution are |
| 78 // executed, or 5.0 seconds, whichever happens first. If |publishSentinel| is |
| 79 // false, the caller is responsible to set |isRunLoopDry| to true when it |
| 80 // considers the run loop dry. |
| 81 void DryRunLoop(bool publishSentinel) { |
| 82 isRunLoopDry = false; |
| 83 if (publishSentinel) { |
| 84 dispatch_async(dispatch_get_main_queue(), ^{ |
| 85 isRunLoopDry = true; |
| 86 }); |
| 87 } |
| 88 NSDate* startDate = [NSDate date]; |
| 89 NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow:5.0]; |
| 90 |
| 91 while (!isRunLoopDry && (-[startDate timeIntervalSinceNow]) < 5.0) { |
| 92 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode |
| 93 beforeDate:endDate]; |
| 94 } |
| 95 } |
| 96 |
| 97 class StaticHtmlViewControllerTest : public PlatformTest { |
| 98 public: |
| 99 StaticHtmlViewControllerTest() |
| 100 : web_client_(base::MakeUnique<web::TestWebClient>()) {} |
| 101 |
| 102 protected: |
| 103 void SetUp() override { |
| 104 PlatformTest::SetUp(); |
| 105 chrome_browser_state_ = TestChromeBrowserState::Builder().Build(); |
| 106 } |
| 107 |
| 108 web::TestWebThreadBundle thread_bundle_; |
| 109 std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; |
| 110 // Private autorelease pool so objects are released as soon as possible. |
| 111 base::mac::ScopedNSAutoreleasePool pool_; |
| 112 web::ScopedTestingWebClient web_client_; |
| 113 }; |
| 114 |
| 115 // Tests the creation of a StaticHtmlViewController displaying a resource file. |
| 116 TEST_F(StaticHtmlViewControllerTest, LoadResourceTest) { |
| 117 base::scoped_nsobject<id> loader; |
| 118 loader.reset([[LoadTestMockLoader alloc] |
| 119 initWithRepresentedObject:[OCMockObject |
| 120 mockForProtocol:@protocol(UrlLoader)]]); |
| 121 |
| 122 id<CRWNativeContentDelegate> delegate = |
| 123 [OCMockObject mockForProtocol:@protocol(CRWNativeContentDelegate)]; |
| 124 GURL referrer_url("chrome://foo"); |
| 125 web::Referrer referrer(referrer_url, web::ReferrerPolicyDefault); |
| 126 base::scoped_nsobject<StaticHtmlViewController> content( |
| 127 [[StaticHtmlViewController alloc] |
| 128 initWithResource:@"terms_en.html" |
| 129 browserState:chrome_browser_state_.get()]); |
| 130 [content setLoader:loader referrer:referrer]; |
| 131 [content setDelegate:delegate]; |
| 132 [[(OCMockObject*)delegate expect] |
| 133 nativeContent:content.get() |
| 134 titleDidChange:[OCMArg checkWithBlock:^BOOL(id value) { |
| 135 isRunLoopDry = true; |
| 136 return [@"Google Chrome Terms of Service" |
| 137 isEqualToString:(NSString*)value]; |
| 138 }]]; |
| 139 [content triggerPendingLoad]; |
| 140 DryRunLoop(false); |
| 141 ASSERT_OCMOCK_VERIFY(loader.get()); |
| 142 ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate); |
| 143 base::scoped_nsobject<id> block( |
| 144 [(id) ^ (const GURL& url, const web::Referrer& referrer, |
| 145 ui::PageTransition transition, BOOL rendererInitiated) { |
| 146 EXPECT_EQ(url, GURL()); |
| 147 EXPECT_EQ(referrer.url, referrer_url); |
| 148 EXPECT_EQ(referrer.policy, web::ReferrerPolicyDefault); |
| 149 EXPECT_TRUE( |
| 150 PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK)); |
| 151 EXPECT_TRUE(rendererInitiated); |
| 152 } copy]); |
| 153 |
| 154 [loader onSelector:@selector(loadURL:referrer:transition:rendererInitiated:) |
| 155 callBlockExpectation:block]; |
| 156 |
| 157 DryRunLoop(true); |
| 158 ASSERT_OCMOCK_VERIFY(loader.get()); |
| 159 ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate); |
| 160 } |
| 161 |
| 162 // Tests the creation of a StaticHtmlViewController displaying a local file. |
| 163 TEST_F(StaticHtmlViewControllerTest, LoadFileURLTest) { |
| 164 base::scoped_nsobject<id> loader; |
| 165 loader.reset([[LoadTestMockLoader alloc] |
| 166 initWithRepresentedObject:[OCMockObject |
| 167 mockForProtocol:@protocol(UrlLoader)]]); |
| 168 |
| 169 id<CRWNativeContentDelegate> delegate = |
| 170 [OCMockObject mockForProtocol:@protocol(CRWNativeContentDelegate)]; |
| 171 GURL referrer_url("chrome://foo"); |
| 172 web::Referrer referrer(referrer_url, web::ReferrerPolicyDefault); |
| 173 NSURL* fileURL = [NSURL |
| 174 fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"terms_en.html" |
| 175 ofType:nil |
| 176 inDirectory:nil]]; |
| 177 base::scoped_nsobject<StaticHtmlViewController> content( |
| 178 [[StaticHtmlViewController alloc] |
| 179 initWithFileURL:net::GURLWithNSURL(fileURL) |
| 180 allowingReadAccessToURL:net::GURLWithNSURL( |
| 181 [fileURL URLByDeletingLastPathComponent]) |
| 182 browserState:chrome_browser_state_.get()]); |
| 183 [content setLoader:loader referrer:referrer]; |
| 184 [content setDelegate:delegate]; |
| 185 [[(OCMockObject*)delegate expect] |
| 186 nativeContent:content.get() |
| 187 titleDidChange:[OCMArg checkWithBlock:^BOOL(id value) { |
| 188 isRunLoopDry = true; |
| 189 return [@"Google Chrome Terms of Service" |
| 190 isEqualToString:(NSString*)value]; |
| 191 }]]; |
| 192 [content triggerPendingLoad]; |
| 193 DryRunLoop(false); |
| 194 ASSERT_OCMOCK_VERIFY(loader.get()); |
| 195 ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate); |
| 196 base::scoped_nsobject<id> block( |
| 197 [(id) ^ (const GURL& url, const web::Referrer& referrer, |
| 198 ui::PageTransition transition, BOOL rendererInitiated) { |
| 199 EXPECT_EQ(url, GURL()); |
| 200 EXPECT_EQ(referrer.url, referrer_url); |
| 201 EXPECT_EQ(referrer.policy, web::ReferrerPolicyDefault); |
| 202 EXPECT_TRUE( |
| 203 PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK)); |
| 204 EXPECT_TRUE(rendererInitiated); |
| 205 } copy]); |
| 206 |
| 207 [loader onSelector:@selector(loadURL:referrer:transition:rendererInitiated:) |
| 208 callBlockExpectation:block]; |
| 209 |
| 210 DryRunLoop(true); |
| 211 ASSERT_OCMOCK_VERIFY(loader.get()); |
| 212 ASSERT_OCMOCK_VERIFY((OCMockObject*)delegate); |
| 213 } |
| 214 |
| 215 // Tests that -[StaticHtmlViewController webView] returns a non-nil view. |
| 216 TEST_F(StaticHtmlViewControllerTest, WebViewNonNil) { |
| 217 base::scoped_nsobject<L10nHtmlGenerator> generator( |
| 218 [[L10nHtmlGenerator alloc] initWithMessageId:IDS_IOS_TOOLS_MENU]); |
| 219 base::scoped_nsobject<StaticHtmlViewController> staticHtmlViewController( |
| 220 [[StaticHtmlViewController alloc] |
| 221 initWithGenerator:generator |
| 222 browserState:chrome_browser_state_.get()]); |
| 223 EXPECT_TRUE([staticHtmlViewController webView]); |
| 224 } |
| 225 |
| 226 // Tests the generated HTML is localized. |
| 227 TEST_F(StaticHtmlViewControllerTest, L10NTest) { |
| 228 base::scoped_nsobject<L10nHtmlGenerator> generator( |
| 229 [[L10nHtmlGenerator alloc] initWithMessageId:IDS_IOS_TOOLS_MENU]); |
| 230 base::scoped_nsobject<StaticHtmlViewController> content( |
| 231 [[StaticHtmlViewController alloc] |
| 232 initWithGenerator:generator |
| 233 browserState:chrome_browser_state_.get()]); |
| 234 id<UrlLoader> loader = [OCMockObject mockForProtocol:@protocol(UrlLoader)]; |
| 235 [content setLoader:loader |
| 236 referrer:web::Referrer(GURL("chrome://foo"), |
| 237 web::ReferrerPolicyDefault)]; |
| 238 [content triggerPendingLoad]; |
| 239 ASSERT_OCMOCK_VERIFY((OCMockObject*)loader); |
| 240 __block id string_in_page = nil; |
| 241 base::test::ios::WaitUntilCondition(^bool { |
| 242 string_in_page = |
| 243 web::ExecuteJavaScript([content webView], @"document.body.innerHTML"); |
| 244 return ![string_in_page isEqual:@""]; |
| 245 }); |
| 246 EXPECT_TRUE([string_in_page isKindOfClass:[NSString class]]); |
| 247 NSString* to_find = l10n_util::GetNSString(IDS_IOS_TOOLS_MENU); |
| 248 EXPECT_TRUE([string_in_page rangeOfString:to_find].length); |
| 249 } |
| 250 |
| 251 } // namespace |
OLD | NEW |