OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/translate/ios/browser/js_language_detection_manager.h" | 5 #import "components/translate/ios/browser/js_language_detection_manager.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/mac/scoped_nsobject.h" | |
14 #import "base/test/ios/wait_util.h" | 13 #import "base/test/ios/wait_util.h" |
15 #include "base/values.h" | 14 #include "base/values.h" |
16 #import "ios/chrome/browser/web/chrome_web_test.h" | 15 #import "ios/chrome/browser/web/chrome_web_test.h" |
17 #include "ios/chrome/common/string_util.h" | 16 #include "ios/chrome/common/string_util.h" |
18 #import "ios/web/public/test/js_test_util.h" | 17 #import "ios/web/public/test/js_test_util.h" |
19 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" | 18 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h" |
20 #import "ios/web/public/web_state/web_state.h" | 19 #import "ios/web/public/web_state/web_state.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "testing/gtest_mac.h" | 21 #include "testing/gtest_mac.h" |
23 | 22 |
| 23 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 24 #error "This file requires ARC support." |
| 25 #endif |
| 26 |
24 namespace { | 27 namespace { |
25 | 28 |
26 const char kExpectedLanguage[] = "Foo"; | 29 const char kExpectedLanguage[] = "Foo"; |
27 | 30 |
28 // Returns an NSString filled with the char 'a' of length |length|. | 31 // Returns an NSString filled with the char 'a' of length |length|. |
29 NSString* GetLongString(NSUInteger length) { | 32 NSString* GetLongString(NSUInteger length) { |
30 base::scoped_nsobject<NSMutableData> data( | 33 NSMutableData* data = [[NSMutableData alloc] initWithLength:length]; |
31 [[NSMutableData alloc] initWithLength:length]); | |
32 memset([data mutableBytes], 'a', length); | 34 memset([data mutableBytes], 'a', length); |
33 NSString* long_string = | 35 NSString* long_string = |
34 [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; | 36 [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; |
35 return [long_string autorelease]; | 37 return long_string; |
36 } | 38 } |
37 | 39 |
38 } // namespace | 40 } // namespace |
39 | 41 |
40 // TODO(shreyasv): Moved this to the translate component. | 42 // TODO(shreyasv): Moved this to the translate component. |
41 // Test fixture to test language detection. | 43 // Test fixture to test language detection. |
42 class JsLanguageDetectionManagerTest : public ChromeWebTest { | 44 class JsLanguageDetectionManagerTest : public ChromeWebTest { |
43 protected: | 45 protected: |
44 void SetUp() override { | 46 void SetUp() override { |
45 ChromeWebTest::SetUp(); | 47 ChromeWebTest::SetUp(); |
46 manager_.reset(static_cast<JsLanguageDetectionManager*>( | 48 manager_ = static_cast<JsLanguageDetectionManager*>( |
47 [[web_state()->GetJSInjectionReceiver() | 49 [web_state()->GetJSInjectionReceiver() |
48 instanceOfClass:[JsLanguageDetectionManager class]] retain])); | 50 instanceOfClass:[JsLanguageDetectionManager class]]); |
49 ASSERT_TRUE(manager_); | 51 ASSERT_TRUE(manager_); |
50 } | 52 } |
51 | 53 |
52 void LoadHtmlAndInject(NSString* html) { | 54 void LoadHtmlAndInject(NSString* html) { |
53 ChromeWebTest::LoadHtml(html); | 55 ChromeWebTest::LoadHtml(html); |
54 [manager_ inject]; | 56 [manager_ inject]; |
55 ASSERT_TRUE([manager_ hasBeenInjected]); | 57 ASSERT_TRUE([manager_ hasBeenInjected]); |
56 } | 58 } |
57 | 59 |
58 // Injects JS, waits for the completion handler and verifies if the result | 60 // Injects JS, waits for the completion handler and verifies if the result |
(...skipping 27 matching lines...) Expand all Loading... |
86 void ExpectHttpContentLanguage(NSString* expected_http_content_language) { | 88 void ExpectHttpContentLanguage(NSString* expected_http_content_language) { |
87 NSString* const kMetaTagContentJS = | 89 NSString* const kMetaTagContentJS = |
88 @"__gCrWeb.languageDetection.getMetaContentByHttpEquiv(" | 90 @"__gCrWeb.languageDetection.getMetaContentByHttpEquiv(" |
89 @"'content-language');"; | 91 @"'content-language');"; |
90 InjectJsAndVerify(kMetaTagContentJS, expected_http_content_language); | 92 InjectJsAndVerify(kMetaTagContentJS, expected_http_content_language); |
91 } | 93 } |
92 | 94 |
93 // Verifies if |__gCrWeb.languageDetection.getTextContent| correctly extracts | 95 // Verifies if |__gCrWeb.languageDetection.getTextContent| correctly extracts |
94 // the text content from an HTML page. | 96 // the text content from an HTML page. |
95 void ExpectTextContent(NSString* expected_text_content) { | 97 void ExpectTextContent(NSString* expected_text_content) { |
96 base::scoped_nsobject<NSString> script([[NSString alloc] | 98 NSString* script = [[NSString alloc] |
97 initWithFormat: | 99 initWithFormat: |
98 @"__gCrWeb.languageDetection.getTextContent(document.body, %lu);", | 100 @"__gCrWeb.languageDetection.getTextContent(document.body, %lu);", |
99 language_detection::kMaxIndexChars]); | 101 language_detection::kMaxIndexChars]; |
100 InjectJsAndVerify(script, expected_text_content); | 102 InjectJsAndVerify(script, expected_text_content); |
101 } | 103 } |
102 | 104 |
103 base::scoped_nsobject<JsLanguageDetectionManager> manager_; | 105 JsLanguageDetectionManager* manager_; |
104 }; | 106 }; |
105 | 107 |
106 // Tests that |hasBeenInjected| returns YES after |inject| call. | 108 // Tests that |hasBeenInjected| returns YES after |inject| call. |
107 TEST_F(JsLanguageDetectionManagerTest, InitAndInject) { | 109 TEST_F(JsLanguageDetectionManagerTest, InitAndInject) { |
108 LoadHtmlAndInject(@"<html></html>"); | 110 LoadHtmlAndInject(@"<html></html>"); |
109 } | 111 } |
110 | 112 |
111 // Tests |__gCrWeb.languageDetection.translationAllowed| JS call. | 113 // Tests |__gCrWeb.languageDetection.translationAllowed| JS call. |
112 TEST_F(JsLanguageDetectionManagerTest, IsTranslationAllowed) { | 114 TEST_F(JsLanguageDetectionManagerTest, IsTranslationAllowed) { |
113 LoadHtmlAndInject(@"<html></html>"); | 115 LoadHtmlAndInject(@"<html></html>"); |
114 ExpectTranslationAllowed(YES); | 116 ExpectTranslationAllowed(YES); |
115 | 117 |
116 LoadHtmlAndInject(@"<html><head>" | 118 LoadHtmlAndInject(@"<html><head>" |
117 "<meta name='google' content='notranslate'>" | 119 "<meta name='google' content='notranslate'>" |
118 "</head></html>"); | 120 "</head></html>"); |
119 ExpectTranslationAllowed(NO); | 121 ExpectTranslationAllowed(NO); |
120 | 122 |
121 LoadHtmlAndInject(@"<html><head>" | 123 LoadHtmlAndInject(@"<html><head>" |
122 "<meta name='google' value='notranslate'>" | 124 "<meta name='google' value='notranslate'>" |
123 "</head></html>"); | 125 "</head></html>"); |
124 ExpectTranslationAllowed(NO); | 126 ExpectTranslationAllowed(NO); |
125 } | 127 } |
126 | 128 |
127 // Tests correctness of |document.documentElement.lang| attribute. | 129 // Tests correctness of |document.documentElement.lang| attribute. |
128 TEST_F(JsLanguageDetectionManagerTest, HtmlLang) { | 130 TEST_F(JsLanguageDetectionManagerTest, HtmlLang) { |
129 base::scoped_nsobject<NSString> html; | 131 NSString* html; |
130 // Non-empty attribute. | 132 // Non-empty attribute. |
131 html.reset([[NSString alloc] | 133 html = [[NSString alloc] |
132 initWithFormat:@"<html lang='%s'></html>", kExpectedLanguage]); | 134 initWithFormat:@"<html lang='%s'></html>", kExpectedLanguage]; |
133 LoadHtmlAndInject(html); | 135 LoadHtmlAndInject(html); |
134 ExpectHtmlLang(@(kExpectedLanguage)); | 136 ExpectHtmlLang(@(kExpectedLanguage)); |
135 | 137 |
136 // Empty attribute. | 138 // Empty attribute. |
137 LoadHtmlAndInject(@"<html></html>"); | 139 LoadHtmlAndInject(@"<html></html>"); |
138 ExpectHtmlLang(@""); | 140 ExpectHtmlLang(@""); |
139 | 141 |
140 // Test with mixed case. | 142 // Test with mixed case. |
141 html.reset([[NSString alloc] | 143 html = [[NSString alloc] |
142 initWithFormat:@"<html lAnG='%s'></html>", kExpectedLanguage]); | 144 initWithFormat:@"<html lAnG='%s'></html>", kExpectedLanguage]; |
143 LoadHtmlAndInject(html); | 145 LoadHtmlAndInject(html); |
144 ExpectHtmlLang(@(kExpectedLanguage)); | 146 ExpectHtmlLang(@(kExpectedLanguage)); |
145 } | 147 } |
146 | 148 |
147 // Tests |__gCrWeb.languageDetection.getMetaContentByHttpEquiv| JS call. | 149 // Tests |__gCrWeb.languageDetection.getMetaContentByHttpEquiv| JS call. |
148 TEST_F(JsLanguageDetectionManagerTest, HttpContentLanguage) { | 150 TEST_F(JsLanguageDetectionManagerTest, HttpContentLanguage) { |
149 // No content language. | 151 // No content language. |
150 LoadHtmlAndInject(@"<html></html>"); | 152 LoadHtmlAndInject(@"<html></html>"); |
151 ExpectHttpContentLanguage(@""); | 153 ExpectHttpContentLanguage(@""); |
152 base::scoped_nsobject<NSString> html; | 154 NSString* html; |
153 | 155 |
154 // Some content language. | 156 // Some content language. |
155 html.reset(([[NSString alloc] | 157 html = ([[NSString alloc] |
156 initWithFormat:@"<html><head>" | 158 initWithFormat:@"<html><head>" |
157 "<meta http-equiv='content-language' content='%s'>" | 159 "<meta http-equiv='content-language' content='%s'>" |
158 "</head></html>", | 160 "</head></html>", |
159 kExpectedLanguage])); | 161 kExpectedLanguage]); |
160 LoadHtmlAndInject(html); | 162 LoadHtmlAndInject(html); |
161 ExpectHttpContentLanguage(@(kExpectedLanguage)); | 163 ExpectHttpContentLanguage(@(kExpectedLanguage)); |
162 | 164 |
163 // Test with mixed case. | 165 // Test with mixed case. |
164 html.reset(([[NSString alloc] | 166 html = ([[NSString alloc] |
165 initWithFormat:@"<html><head>" | 167 initWithFormat:@"<html><head>" |
166 "<meta http-equiv='cOnTenT-lAngUAge' content='%s'>" | 168 "<meta http-equiv='cOnTenT-lAngUAge' content='%s'>" |
167 "</head></html>", | 169 "</head></html>", |
168 kExpectedLanguage])); | 170 kExpectedLanguage]); |
169 LoadHtmlAndInject(html); | 171 LoadHtmlAndInject(html); |
170 ExpectHttpContentLanguage(@(kExpectedLanguage)); | 172 ExpectHttpContentLanguage(@(kExpectedLanguage)); |
171 } | 173 } |
172 | 174 |
173 // Tests |__gCrWeb.languageDetection.getTextContent| JS call. | 175 // Tests |__gCrWeb.languageDetection.getTextContent| JS call. |
174 TEST_F(JsLanguageDetectionManagerTest, ExtractTextContent) { | 176 TEST_F(JsLanguageDetectionManagerTest, ExtractTextContent) { |
175 LoadHtmlAndInject(@"<html><body>" | 177 LoadHtmlAndInject(@"<html><body>" |
176 "<script>var text = 'No scripts!'</script>" | 178 "<script>var text = 'No scripts!'</script>" |
177 "<p style='display: none;'>Not displayed!</p>" | 179 "<p style='display: none;'>Not displayed!</p>" |
178 "<p style='visibility: hidden;'>Hidden!</p>" | 180 "<p style='visibility: hidden;'>Hidden!</p>" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 "<ul><li>One</li><li>T<a href='foo'>wo</a></li></ul><p>Three</p>" | 214 "<ul><li>One</li><li>T<a href='foo'>wo</a></li></ul><p>Three</p>" |
213 "</body></html>"); | 215 "</body></html>"); |
214 ExpectTextContent(@"\n\nOne\nTwo\nThree"); | 216 ExpectTextContent(@"\n\nOne\nTwo\nThree"); |
215 } | 217 } |
216 | 218 |
217 // Tests that |__gCrWeb.languageDetection.getTextContent| returns only until the | 219 // Tests that |__gCrWeb.languageDetection.getTextContent| returns only until the |
218 // kMaxIndexChars number of characters even if the text content is very large. | 220 // kMaxIndexChars number of characters even if the text content is very large. |
219 TEST_F(JsLanguageDetectionManagerTest, LongTextContent) { | 221 TEST_F(JsLanguageDetectionManagerTest, LongTextContent) { |
220 // Very long string. | 222 // Very long string. |
221 NSUInteger kLongStringLength = language_detection::kMaxIndexChars - 5; | 223 NSUInteger kLongStringLength = language_detection::kMaxIndexChars - 5; |
222 base::scoped_nsobject<NSMutableString> long_string( | 224 NSMutableString* long_string = [GetLongString(kLongStringLength) mutableCopy]; |
223 [GetLongString(kLongStringLength) mutableCopy]); | |
224 [long_string appendString:@" b cdefghijklmnopqrstuvwxyz"]; | 225 [long_string appendString:@" b cdefghijklmnopqrstuvwxyz"]; |
225 | 226 |
226 // The string should be cut at the last whitespace, after the 'b' character. | 227 // The string should be cut at the last whitespace, after the 'b' character. |
227 base::scoped_nsobject<NSString> html([[NSString alloc] | 228 NSString* html = [[NSString alloc] |
228 initWithFormat:@"<html><body>%@</html></body>", long_string.get()]); | 229 initWithFormat:@"<html><body>%@</html></body>", long_string]; |
229 LoadHtmlAndInject(html); | 230 LoadHtmlAndInject(html); |
230 | 231 |
231 base::scoped_nsobject<NSString> script([[NSString alloc] | 232 NSString* script = [[NSString alloc] |
232 initWithFormat: | 233 initWithFormat: |
233 @"__gCrWeb.languageDetection.getTextContent(document.body, %lu);", | 234 @"__gCrWeb.languageDetection.getTextContent(document.body, %lu);", |
234 language_detection::kMaxIndexChars]); | 235 language_detection::kMaxIndexChars]; |
235 NSString* result = web::ExecuteJavaScript(manager_, script); | 236 NSString* result = web::ExecuteJavaScript(manager_, script); |
236 EXPECT_EQ(language_detection::kMaxIndexChars, [result length]); | 237 EXPECT_EQ(language_detection::kMaxIndexChars, [result length]); |
237 } | 238 } |
238 | 239 |
239 // Tests if |__gCrWeb.languageDetection.retrieveBufferedTextContent| correctly | 240 // Tests if |__gCrWeb.languageDetection.retrieveBufferedTextContent| correctly |
240 // retrieves the cache and then purges it. | 241 // retrieves the cache and then purges it. |
241 TEST_F(JsLanguageDetectionManagerTest, RetrieveBufferedTextContent) { | 242 TEST_F(JsLanguageDetectionManagerTest, RetrieveBufferedTextContent) { |
242 LoadHtmlAndInject(@"<html></html>"); | 243 LoadHtmlAndInject(@"<html></html>"); |
243 // Set some cached text content. | 244 // Set some cached text content. |
244 [manager_ executeJavaScript: | 245 [manager_ executeJavaScript: |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 | 345 |
345 EXPECT_TRUE(value->HasKey("translationAllowed")); | 346 EXPECT_TRUE(value->HasKey("translationAllowed")); |
346 EXPECT_TRUE(value->HasKey("captureTextTime")); | 347 EXPECT_TRUE(value->HasKey("captureTextTime")); |
347 EXPECT_TRUE(value->HasKey("htmlLang")); | 348 EXPECT_TRUE(value->HasKey("htmlLang")); |
348 EXPECT_TRUE(value->HasKey("httpContentLanguage")); | 349 EXPECT_TRUE(value->HasKey("httpContentLanguage")); |
349 | 350 |
350 bool translation_allowed = false; | 351 bool translation_allowed = false; |
351 value->GetBoolean("translationAllowed", &translation_allowed); | 352 value->GetBoolean("translationAllowed", &translation_allowed); |
352 EXPECT_TRUE(translation_allowed); | 353 EXPECT_TRUE(translation_allowed); |
353 } | 354 } |
OLD | NEW |