| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #include <string> | 5 #include <string> |
| 6 #include <vector> | 6 #include <vector> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 // verifies JSON-RPC requests when the SpellingServiceClient class sends them to | 27 // verifies JSON-RPC requests when the SpellingServiceClient class sends them to |
| 28 // the Spelling service. This class also verifies the SpellingServiceClient | 28 // the Spelling service. This class also verifies the SpellingServiceClient |
| 29 // class does not either send cookies to the Spelling service or accept cookies | 29 // class does not either send cookies to the Spelling service or accept cookies |
| 30 // from it. | 30 // from it. |
| 31 class TestSpellingURLFetcher : public net::TestURLFetcher { | 31 class TestSpellingURLFetcher : public net::TestURLFetcher { |
| 32 public: | 32 public: |
| 33 TestSpellingURLFetcher(int id, | 33 TestSpellingURLFetcher(int id, |
| 34 const GURL& url, | 34 const GURL& url, |
| 35 net::URLFetcherDelegate* d, | 35 net::URLFetcherDelegate* d, |
| 36 int version, | 36 int version, |
| 37 const std::string& text, | 37 const std::string& sanitized_text, |
| 38 const std::string& language, | 38 const std::string& language, |
| 39 int status, | 39 int status, |
| 40 const std::string& response) | 40 const std::string& response) |
| 41 : net::TestURLFetcher(0, url, d), | 41 : net::TestURLFetcher(0, url, d), |
| 42 version_(base::StringPrintf("v%d", version)), | 42 version_(base::StringPrintf("v%d", version)), |
| 43 language_(language.empty() ? std::string("en") : language), | 43 language_(language.empty() ? std::string("en") : language), |
| 44 text_(text) { | 44 sanitized_text_(sanitized_text) { |
| 45 set_response_code(status); | 45 set_response_code(status); |
| 46 SetResponseString(response); | 46 SetResponseString(response); |
| 47 } | 47 } |
| 48 ~TestSpellingURLFetcher() override {} | 48 ~TestSpellingURLFetcher() override {} |
| 49 | 49 |
| 50 void SetUploadData(const std::string& upload_content_type, | 50 void SetUploadData(const std::string& upload_content_type, |
| 51 const std::string& upload_content) override { | 51 const std::string& upload_content) override { |
| 52 // Verify the given content type is JSON. (The Spelling service returns an | 52 // Verify the given content type is JSON. (The Spelling service returns an |
| 53 // internal server error when this content type is not JSON.) | 53 // internal server error when this content type is not JSON.) |
| 54 EXPECT_EQ("application/json", upload_content_type); | 54 EXPECT_EQ("application/json", upload_content_type); |
| 55 | 55 |
| 56 // Parse the JSON to be sent to the service, and verify its parameters. | 56 // Parse the JSON to be sent to the service, and verify its parameters. |
| 57 scoped_ptr<base::DictionaryValue> value( | 57 scoped_ptr<base::DictionaryValue> value( |
| 58 static_cast<base::DictionaryValue*>(base::JSONReader::DeprecatedRead( | 58 static_cast<base::DictionaryValue*>(base::JSONReader::DeprecatedRead( |
| 59 upload_content, base::JSON_ALLOW_TRAILING_COMMAS))); | 59 upload_content, base::JSON_ALLOW_TRAILING_COMMAS))); |
| 60 ASSERT_TRUE(value.get()); | 60 ASSERT_TRUE(value.get()); |
| 61 std::string method; | 61 std::string method; |
| 62 EXPECT_TRUE(value->GetString("method", &method)); | 62 EXPECT_TRUE(value->GetString("method", &method)); |
| 63 EXPECT_EQ("spelling.check", method); | 63 EXPECT_EQ("spelling.check", method); |
| 64 std::string version; | 64 std::string version; |
| 65 EXPECT_TRUE(value->GetString("apiVersion", &version)); | 65 EXPECT_TRUE(value->GetString("apiVersion", &version)); |
| 66 EXPECT_EQ(version_, version); | 66 EXPECT_EQ(version_, version); |
| 67 std::string text; | 67 std::string sanitized_text; |
| 68 EXPECT_TRUE(value->GetString("params.text", &text)); | 68 EXPECT_TRUE(value->GetString("params.text", &sanitized_text)); |
| 69 EXPECT_EQ(text_, text); | 69 EXPECT_EQ(sanitized_text_, sanitized_text); |
| 70 std::string language; | 70 std::string language; |
| 71 EXPECT_TRUE(value->GetString("params.language", &language)); | 71 EXPECT_TRUE(value->GetString("params.language", &language)); |
| 72 EXPECT_EQ(language_, language); | 72 EXPECT_EQ(language_, language); |
| 73 ASSERT_TRUE(GetExpectedCountry(language, &country_)); | 73 ASSERT_TRUE(GetExpectedCountry(language, &country_)); |
| 74 std::string country; | 74 std::string country; |
| 75 EXPECT_TRUE(value->GetString("params.originCountry", &country)); | 75 EXPECT_TRUE(value->GetString("params.originCountry", &country)); |
| 76 EXPECT_EQ(country_, country); | 76 EXPECT_EQ(country_, country); |
| 77 | 77 |
| 78 net::TestURLFetcher::SetUploadData(upload_content_type, upload_content); | 78 net::TestURLFetcher::SetUploadData(upload_content_type, upload_content); |
| 79 } | 79 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 99 country->assign(kCountries[i].country); | 99 country->assign(kCountries[i].country); |
| 100 return true; | 100 return true; |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 return false; | 103 return false; |
| 104 } | 104 } |
| 105 | 105 |
| 106 std::string version_; | 106 std::string version_; |
| 107 std::string language_; | 107 std::string language_; |
| 108 std::string country_; | 108 std::string country_; |
| 109 std::string text_; | 109 std::string sanitized_text_; |
| 110 }; | 110 }; |
| 111 | 111 |
| 112 // A class derived from the SpellingServiceClient class used by the | 112 // A class derived from the SpellingServiceClient class used by the |
| 113 // SpellingServiceClientTest class. This class overrides CreateURLFetcher so | 113 // SpellingServiceClientTest class. This class overrides CreateURLFetcher so |
| 114 // this test can use TestSpellingURLFetcher. This class also lets tests access | 114 // this test can use TestSpellingURLFetcher. This class also lets tests access |
| 115 // the ParseResponse method. | 115 // the ParseResponse method. |
| 116 class TestingSpellingServiceClient : public SpellingServiceClient { | 116 class TestingSpellingServiceClient : public SpellingServiceClient { |
| 117 public: | 117 public: |
| 118 TestingSpellingServiceClient() | 118 TestingSpellingServiceClient() |
| 119 : request_type_(0), | 119 : request_type_(0), |
| 120 response_status_(0), | 120 response_status_(0), |
| 121 success_(false), | 121 success_(false), |
| 122 fetcher_(NULL) { | 122 fetcher_(NULL) { |
| 123 } | 123 } |
| 124 ~TestingSpellingServiceClient() override {} | 124 ~TestingSpellingServiceClient() override {} |
| 125 | 125 |
| 126 void SetHTTPRequest(int type, | 126 void SetHTTPRequest(int type, |
| 127 const std::string& text, | 127 const std::string& sanitized_text, |
| 128 const std::string& language) { | 128 const std::string& language) { |
| 129 request_type_ = type; | 129 request_type_ = type; |
| 130 request_text_ = text; | 130 sanitized_request_text_ = sanitized_text; |
| 131 request_language_ = language; | 131 request_language_ = language; |
| 132 } | 132 } |
| 133 | 133 |
| 134 void SetHTTPResponse(int status, const char* data) { | 134 void SetHTTPResponse(int status, const char* data) { |
| 135 response_status_ = status; | 135 response_status_ = status; |
| 136 response_data_.assign(data); | 136 response_data_.assign(data); |
| 137 } | 137 } |
| 138 | 138 |
| 139 void SetExpectedTextCheckResult(bool success, const char* text) { | 139 void SetExpectedTextCheckResult(bool success, const char* text) { |
| 140 success_ = success; | 140 success_ = success; |
| 141 corrected_text_.assign(base::UTF8ToUTF16(text)); | 141 corrected_text_.assign(base::UTF8ToUTF16(text)); |
| 142 } | 142 } |
| 143 | 143 |
| 144 void CallOnURLFetchComplete() { | 144 void CallOnURLFetchComplete() { |
| 145 ASSERT_TRUE(fetcher_); | 145 ASSERT_TRUE(fetcher_); |
| 146 fetcher_->delegate()->OnURLFetchComplete(fetcher_); | 146 fetcher_->delegate()->OnURLFetchComplete(fetcher_); |
| 147 fetcher_ = NULL; | 147 fetcher_ = NULL; |
| 148 } | 148 } |
| 149 | 149 |
| 150 void VerifyResponse(bool success, | 150 void VerifyResponse(bool success, |
| 151 const base::string16& request_text, | 151 const base::string16& request_text, |
| 152 const std::vector<SpellCheckResult>& results) { | 152 const std::vector<SpellCheckResult>& results) { |
| 153 EXPECT_EQ(success_, success); | 153 EXPECT_EQ(success_, success); |
| 154 base::string16 text(base::UTF8ToUTF16(request_text_)); | 154 base::string16 text(base::UTF8ToUTF16(sanitized_request_text_)); |
| 155 EXPECT_EQ(text, request_text); | |
| 156 for (std::vector<SpellCheckResult>::const_iterator it = results.begin(); | 155 for (std::vector<SpellCheckResult>::const_iterator it = results.begin(); |
| 157 it != results.end(); ++it) { | 156 it != results.end(); ++it) { |
| 158 text.replace(it->location, it->length, it->replacement); | 157 text.replace(it->location, it->length, it->replacement); |
| 159 } | 158 } |
| 160 EXPECT_EQ(corrected_text_, text); | 159 EXPECT_EQ(corrected_text_, text); |
| 161 } | 160 } |
| 162 | 161 |
| 163 bool ParseResponseSuccess(const std::string& data) { | 162 bool ParseResponseSuccess(const std::string& data) { |
| 164 std::vector<SpellCheckResult> results; | 163 std::vector<SpellCheckResult> results; |
| 165 return ParseResponse(data, &results); | 164 return ParseResponse(data, &results); |
| 166 } | 165 } |
| 167 | 166 |
| 168 private: | 167 private: |
| 169 scoped_ptr<net::URLFetcher> CreateURLFetcher(const GURL& url) override { | 168 scoped_ptr<net::URLFetcher> CreateURLFetcher(const GURL& url) override { |
| 170 EXPECT_EQ("https://www.googleapis.com/rpc", url.spec()); | 169 EXPECT_EQ("https://www.googleapis.com/rpc", url.spec()); |
| 171 fetcher_ = new TestSpellingURLFetcher(0, url, this, | 170 fetcher_ = new TestSpellingURLFetcher( |
| 172 request_type_, request_text_, | 171 0, url, this, request_type_, sanitized_request_text_, request_language_, |
| 173 request_language_, | 172 response_status_, response_data_); |
| 174 response_status_, response_data_); | |
| 175 return scoped_ptr<net::URLFetcher>(fetcher_); | 173 return scoped_ptr<net::URLFetcher>(fetcher_); |
| 176 } | 174 } |
| 177 | 175 |
| 178 int request_type_; | 176 int request_type_; |
| 179 std::string request_text_; | 177 std::string sanitized_request_text_; |
| 180 std::string request_language_; | 178 std::string request_language_; |
| 181 int response_status_; | 179 int response_status_; |
| 182 std::string response_data_; | 180 std::string response_data_; |
| 183 bool success_; | 181 bool success_; |
| 184 base::string16 corrected_text_; | 182 base::string16 corrected_text_; |
| 185 TestSpellingURLFetcher* fetcher_; // weak | 183 TestSpellingURLFetcher* fetcher_; // weak |
| 186 }; | 184 }; |
| 187 | 185 |
| 188 // A test class used for testing the SpellingServiceClient class. This class | 186 // A test class used for testing the SpellingServiceClient class. This class |
| 189 // implements a callback function used by the SpellingServiceClient class to | 187 // implements a callback function used by the SpellingServiceClient class to |
| (...skipping 20 matching lines...) Expand all Loading... |
| 210 // that it parses a JSON response from the service and calls the callback | 208 // that it parses a JSON response from the service and calls the callback |
| 211 // function. To avoid sending JSON-RPC requests to the service, this test uses a | 209 // function. To avoid sending JSON-RPC requests to the service, this test uses a |
| 212 // custom TestURLFecher class (TestSpellingURLFetcher) which calls | 210 // custom TestURLFecher class (TestSpellingURLFetcher) which calls |
| 213 // SpellingServiceClient::OnURLFetchComplete() with the parameters set by this | 211 // SpellingServiceClient::OnURLFetchComplete() with the parameters set by this |
| 214 // test. This test also uses a custom callback function that replaces all | 212 // test. This test also uses a custom callback function that replaces all |
| 215 // misspelled words with ones suggested by the service so this test can compare | 213 // misspelled words with ones suggested by the service so this test can compare |
| 216 // the corrected text with the expected results. (If there are not any | 214 // the corrected text with the expected results. (If there are not any |
| 217 // misspelled words, |corrected_text| should be equal to |request_text|.) | 215 // misspelled words, |corrected_text| should be equal to |request_text|.) |
| 218 TEST_F(SpellingServiceClientTest, RequestTextCheck) { | 216 TEST_F(SpellingServiceClientTest, RequestTextCheck) { |
| 219 static const struct { | 217 static const struct { |
| 220 const char* request_text; | 218 const wchar_t* request_text; |
| 219 const char* sanitized_request_text; |
| 221 SpellingServiceClient::ServiceType request_type; | 220 SpellingServiceClient::ServiceType request_type; |
| 222 int response_status; | 221 int response_status; |
| 223 const char* response_data; | 222 const char* response_data; |
| 224 bool success; | 223 bool success; |
| 225 const char* corrected_text; | 224 const char* corrected_text; |
| 226 const char* language; | 225 const char* language; |
| 227 } kTests[] = { | 226 } kTests[] = { |
| 228 { | 227 { |
| 228 L"", |
| 229 "", | 229 "", |
| 230 SpellingServiceClient::SUGGEST, | 230 SpellingServiceClient::SUGGEST, |
| 231 500, | 231 500, |
| 232 "", | 232 "", |
| 233 false, | 233 false, |
| 234 "", | 234 "", |
| 235 "af", | 235 "af", |
| 236 }, { | 236 }, { |
| 237 L"chromebook", |
| 237 "chromebook", | 238 "chromebook", |
| 238 SpellingServiceClient::SUGGEST, | 239 SpellingServiceClient::SUGGEST, |
| 239 200, | 240 200, |
| 240 "{}", | 241 "{}", |
| 241 true, | 242 true, |
| 242 "chromebook", | 243 "chromebook", |
| 243 "af", | 244 "af", |
| 244 }, { | 245 }, { |
| 246 L"chrombook", |
| 245 "chrombook", | 247 "chrombook", |
| 246 SpellingServiceClient::SUGGEST, | 248 SpellingServiceClient::SUGGEST, |
| 247 200, | 249 200, |
| 248 "{\n" | 250 "{\n" |
| 249 " \"result\": {\n" | 251 " \"result\": {\n" |
| 250 " \"spellingCheckResponse\": {\n" | 252 " \"spellingCheckResponse\": {\n" |
| 251 " \"misspellings\": [{\n" | 253 " \"misspellings\": [{\n" |
| 252 " \"charStart\": 0,\n" | 254 " \"charStart\": 0,\n" |
| 253 " \"charLength\": 9,\n" | 255 " \"charLength\": 9,\n" |
| 254 " \"suggestions\": [{ \"suggestion\": \"chromebook\" }],\n" | 256 " \"suggestions\": [{ \"suggestion\": \"chromebook\" }],\n" |
| 255 " \"canAutoCorrect\": false\n" | 257 " \"canAutoCorrect\": false\n" |
| 256 " }]\n" | 258 " }]\n" |
| 257 " }\n" | 259 " }\n" |
| 258 " }\n" | 260 " }\n" |
| 259 "}", | 261 "}", |
| 260 true, | 262 true, |
| 261 "chromebook", | 263 "chromebook", |
| 262 "af", | 264 "af", |
| 263 }, { | 265 }, { |
| 266 L"", |
| 264 "", | 267 "", |
| 265 SpellingServiceClient::SPELLCHECK, | 268 SpellingServiceClient::SPELLCHECK, |
| 266 500, | 269 500, |
| 267 "", | 270 "", |
| 268 false, | 271 false, |
| 269 "", | 272 "", |
| 270 "en", | 273 "en", |
| 271 }, { | 274 }, { |
| 275 L"I have been to USA.", |
| 272 "I have been to USA.", | 276 "I have been to USA.", |
| 273 SpellingServiceClient::SPELLCHECK, | 277 SpellingServiceClient::SPELLCHECK, |
| 274 200, | 278 200, |
| 275 "{}", | 279 "{}", |
| 276 true, | 280 true, |
| 277 "I have been to USA.", | 281 "I have been to USA.", |
| 278 "en", | 282 "en", |
| 279 }, { | 283 }, { |
| 284 L"I have bean to USA.", |
| 280 "I have bean to USA.", | 285 "I have bean to USA.", |
| 281 SpellingServiceClient::SPELLCHECK, | 286 SpellingServiceClient::SPELLCHECK, |
| 282 200, | 287 200, |
| 283 "{\n" | 288 "{\n" |
| 284 " \"result\": {\n" | 289 " \"result\": {\n" |
| 285 " \"spellingCheckResponse\": {\n" | 290 " \"spellingCheckResponse\": {\n" |
| 286 " \"misspellings\": [{\n" | 291 " \"misspellings\": [{\n" |
| 287 " \"charStart\": 7,\n" | 292 " \"charStart\": 7,\n" |
| 288 " \"charLength\": 4,\n" | 293 " \"charLength\": 4,\n" |
| 289 " \"suggestions\": [{ \"suggestion\": \"been\" }],\n" | 294 " \"suggestions\": [{ \"suggestion\": \"been\" }],\n" |
| 290 " \"canAutoCorrect\": false\n" | 295 " \"canAutoCorrect\": false\n" |
| 291 " }]\n" | 296 " }]\n" |
| 292 " }\n" | 297 " }\n" |
| 293 " }\n" | 298 " }\n" |
| 294 "}", | 299 "}", |
| 295 true, | 300 true, |
| 296 "I have been to USA.", | 301 "I have been to USA.", |
| 297 "en", | 302 "en", |
| 303 }, { |
| 304 L"I\x2019mattheIn'n'Out.", |
| 305 "I'mattheIn'n'Out.", |
| 306 SpellingServiceClient::SPELLCHECK, |
| 307 200, |
| 308 "{\n" |
| 309 " \"result\": {\n" |
| 310 " \"spellingCheckResponse\": {\n" |
| 311 " \"misspellings\": [{\n" |
| 312 " \"charStart\": 0,\n" |
| 313 " \"charLength\": 16,\n" |
| 314 " \"suggestions\":" |
| 315 " [{ \"suggestion\": \"I'm at the In'N'Out\" }],\n" |
| 316 " \"canAutoCorrect\": false\n" |
| 317 " }]\n" |
| 318 " }\n" |
| 319 " }\n" |
| 320 "}", |
| 321 true, |
| 322 "I'm at the In'N'Out.", |
| 323 "en", |
| 298 }, | 324 }, |
| 299 }; | 325 }; |
| 300 | 326 |
| 301 PrefService* pref = profile_.GetPrefs(); | 327 PrefService* pref = profile_.GetPrefs(); |
| 302 pref->SetBoolean(prefs::kEnableContinuousSpellcheck, true); | 328 pref->SetBoolean(prefs::kEnableContinuousSpellcheck, true); |
| 303 pref->SetBoolean(prefs::kSpellCheckUseSpellingService, true); | 329 pref->SetBoolean(prefs::kSpellCheckUseSpellingService, true); |
| 304 | 330 |
| 305 for (size_t i = 0; i < arraysize(kTests); ++i) { | 331 for (size_t i = 0; i < arraysize(kTests); ++i) { |
| 306 client_.SetHTTPRequest(kTests[i].request_type, kTests[i].request_text, | 332 client_.SetHTTPRequest(kTests[i].request_type, |
| 333 kTests[i].sanitized_request_text, |
| 307 kTests[i].language); | 334 kTests[i].language); |
| 308 client_.SetHTTPResponse(kTests[i].response_status, kTests[i].response_data); | 335 client_.SetHTTPResponse(kTests[i].response_status, kTests[i].response_data); |
| 309 client_.SetExpectedTextCheckResult(kTests[i].success, | 336 client_.SetExpectedTextCheckResult(kTests[i].success, |
| 310 kTests[i].corrected_text); | 337 kTests[i].corrected_text); |
| 311 pref->SetString(prefs::kSpellCheckDictionary, kTests[i].language); | 338 pref->SetString(prefs::kSpellCheckDictionary, kTests[i].language); |
| 312 client_.RequestTextCheck( | 339 client_.RequestTextCheck( |
| 313 &profile_, | 340 &profile_, |
| 314 kTests[i].request_type, | 341 kTests[i].request_type, |
| 315 base::ASCIIToUTF16(kTests[i].request_text), | 342 base::WideToUTF16(kTests[i].request_text), |
| 316 base::Bind(&SpellingServiceClientTest::OnTextCheckComplete, | 343 base::Bind(&SpellingServiceClientTest::OnTextCheckComplete, |
| 317 base::Unretained(this), 0)); | 344 base::Unretained(this), 0)); |
| 318 client_.CallOnURLFetchComplete(); | 345 client_.CallOnURLFetchComplete(); |
| 319 } | 346 } |
| 320 } | 347 } |
| 321 | 348 |
| 322 // Verify that SpellingServiceClient::IsAvailable() returns true only when it | 349 // Verify that SpellingServiceClient::IsAvailable() returns true only when it |
| 323 // can send suggest requests or spellcheck requests. | 350 // can send suggest requests or spellcheck requests. |
| 324 TEST_F(SpellingServiceClientTest, AvailableServices) { | 351 TEST_F(SpellingServiceClientTest, AvailableServices) { |
| 325 const SpellingServiceClient::ServiceType kSuggest = | 352 const SpellingServiceClient::ServiceType kSuggest = |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 } | 402 } |
| 376 #endif // !defined(OS_MACOSX) | 403 #endif // !defined(OS_MACOSX) |
| 377 } | 404 } |
| 378 | 405 |
| 379 // Verify that an error in JSON response from spelling service will result in | 406 // Verify that an error in JSON response from spelling service will result in |
| 380 // ParseResponse returning false. | 407 // ParseResponse returning false. |
| 381 TEST_F(SpellingServiceClientTest, ResponseErrorTest) { | 408 TEST_F(SpellingServiceClientTest, ResponseErrorTest) { |
| 382 EXPECT_TRUE(client_.ParseResponseSuccess("{\"result\": {}}")); | 409 EXPECT_TRUE(client_.ParseResponseSuccess("{\"result\": {}}")); |
| 383 EXPECT_FALSE(client_.ParseResponseSuccess("{\"error\": {}}")); | 410 EXPECT_FALSE(client_.ParseResponseSuccess("{\"error\": {}}")); |
| 384 } | 411 } |
| OLD | NEW |