15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/spellchecker/spelling_service_client.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/spellcheck_result.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 19a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/test/test_browser_thread_bundle.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A mock URL fetcher used in the TestingSpellingServiceClient class. This class 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// verifies JSON-RPC requests when the SpellingServiceClient class sends them to 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the Spelling service. This class also verifies the SpellingServiceClient 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class does not either send cookies to the Spelling service or accept cookies 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from it. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestSpellingURLFetcher : public net::TestURLFetcher { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestSpellingURLFetcher(int id, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLFetcherDelegate* d, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int version, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& text, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& language, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int status, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& response) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::TestURLFetcher(0, url, d), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_(base::StringPrintf("v%d", version)), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) language_(language.empty() ? std::string("en") : language), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_(text) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_response_code(status); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetResponseString(response); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestSpellingURLFetcher() { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUploadData(const std::string& upload_content_type, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& upload_content) OVERRIDE { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify the given content type is JSON. (The Spelling service returns an 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // internal server error when this content type is not JSON.) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("application/json", upload_content_type); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the JSON to be sent to the service, and verify its parameters. 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> value(static_cast<base::DictionaryValue*>( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::JSONReader::Read(upload_content, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::JSON_ALLOW_TRAILING_COMMAS))); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(!!value.get()); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string method; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value->GetString("method", &method)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("spelling.check", method); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string version; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value->GetString("apiVersion", &version)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(version_, version); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string text; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value->GetString("params.text", &text)); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(text_, text); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string language; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value->GetString("params.language", &language)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(language_, language); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(GetExpectedCountry(language, &country_)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string country; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(value->GetString("params.originCountry", &country)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(country_, country); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::TestURLFetcher::SetUploadData(upload_content_type, upload_content); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Start() OVERRIDE { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that this client does not either send cookies to the Spelling 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // service or accept cookies from it. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLoadFlags()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetExpectedCountry(const std::string& language, std::string* country) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const struct { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* language; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* country; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } kCountries[] = { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"af", "ZAF"}, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"en", "USA"}, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCountries); ++i) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!language.compare(kCountries[i].language)) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) country->assign(kCountries[i].country); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string version_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string language_; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string country_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string text_; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class derived from the SpellingServiceClient class used by the 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SpellingServiceClientTest class. This class overrides CreateURLFetcher so 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// this test can use TestSpellingURLFetcher. This class also lets tests access 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// the ParseResponse method. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestingSpellingServiceClient : public SpellingServiceClient { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestingSpellingServiceClient() 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : request_type_(0), 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_status_(0), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_(false), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_(NULL) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestingSpellingServiceClient() { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetHTTPRequest(int type, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& text, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& language) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_ = type; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_text_ = text; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_language_ = language; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetHTTPResponse(int status, const char* data) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_status_ = status; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_data_.assign(data); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetExpectedTextCheckResult(bool success, const char* text) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_ = success; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) corrected_text_.assign(base::UTF8ToUTF16(text)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CallOnURLFetchComplete() { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(!!fetcher_); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_->delegate()->OnURLFetchComplete(fetcher_); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_ = NULL; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void VerifyResponse(bool success, 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& request_text, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<SpellCheckResult>& results) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(success_, success); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 text(base::UTF8ToUTF16(request_text_)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(text, request_text); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<SpellCheckResult>::const_iterator it = results.begin(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != results.end(); ++it) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text.replace(it->location, it->length, it->replacement); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(corrected_text_, text); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool ParseResponseSuccess(const std::string& data) { 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<SpellCheckResult> results; 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return ParseResponse(data, &results); 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual net::URLFetcher* CreateURLFetcher(const GURL& url) OVERRIDE { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("https://www.googleapis.com/rpc", url.spec()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_ = new TestSpellingURLFetcher(0, url, this, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_, request_text_, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_language_, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_status_, response_data_); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fetcher_; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int request_type_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string request_text_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string request_language_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_status_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response_data_; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success_; 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 corrected_text_; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestSpellingURLFetcher* fetcher_; // weak 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A test class used for testing the SpellingServiceClient class. This class 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implements a callback function used by the SpellingServiceClient class to 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// monitor the class calls the callback with expected results. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpellingServiceClientTest : public testing::Test { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnTextCheckComplete(int tag, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success, 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& text, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<SpellCheckResult>& results) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.VerifyResponse(success, text, results); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 203a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch content::TestBrowserThreadBundle thread_bundle_; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestingSpellingServiceClient client_; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestingProfile profile_; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that SpellingServiceClient::RequestTextCheck() creates a JSON 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// request sent to the Spelling service as we expect. This test also verifies 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that it parses a JSON response from the service and calls the callback 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function. To avoid sending JSON-RPC requests to the service, this test uses a 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// custom TestURLFecher class (TestSpellingURLFetcher) which calls 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SpellingServiceClient::OnURLFetchComplete() with the parameters set by this 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// test. This test also uses a custom callback function that replaces all 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// misspelled words with ones suggested by the service so this test can compare 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the corrected text with the expected results. (If there are not any 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// misspelled words, |corrected_text| should be equal to |request_text|.) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SpellingServiceClientTest, RequestTextCheck) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const struct { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* request_text; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::ServiceType request_type; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_status; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* response_data; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* corrected_text; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* language; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } kTests[] = { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SUGGEST, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 500, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "af", 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "chromebook", 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SUGGEST, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 200, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{}", 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "chromebook", 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "af", 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "chrombook", 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SUGGEST, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 200, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{\n" 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"result\": {\n" 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"spellingCheckResponse\": {\n" 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"misspellings\": [{\n" 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"charStart\": 0,\n" 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"charLength\": 9,\n" 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"suggestions\": [{ \"suggestion\": \"chromebook\" }],\n" 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"canAutoCorrect\": false\n" 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }]\n" 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }\n" 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }\n" 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}", 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "chromebook", 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "af", 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SPELLCHECK, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 500, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "en", 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "I have been to USA.", 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SPELLCHECK, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 200, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{}", 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "I have been to USA.", 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "en", 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "I have bean to USA.", 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SPELLCHECK, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 200, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{\n" 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"result\": {\n" 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"spellingCheckResponse\": {\n" 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"misspellings\": [{\n" 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"charStart\": 7,\n" 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"charLength\": 4,\n" 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"suggestions\": [{ \"suggestion\": \"been\" }],\n" 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " \"canAutoCorrect\": false\n" 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }]\n" 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }\n" 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }\n" 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}", 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "I have been to USA.", 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "en", 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* pref = profile_.GetPrefs(); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pref->SetBoolean(prefs::kEnableContinuousSpellcheck, true); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->SetBoolean(prefs::kSpellCheckUseSpellingService, true); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.SetHTTPRequest(kTests[i].request_type, kTests[i].request_text, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTests[i].language); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.SetHTTPResponse(kTests[i].response_status, kTests[i].response_data); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.SetExpectedTextCheckResult(kTests[i].success, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTests[i].corrected_text); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->SetString(prefs::kSpellCheckDictionary, kTests[i].language); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.RequestTextCheck( 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &profile_, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTests[i].request_type, 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ASCIIToUTF16(kTests[i].request_text), 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SpellingServiceClientTest::OnTextCheckComplete, 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 0)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.CallOnURLFetchComplete(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify that SpellingServiceClient::IsAvailable() returns true only when it 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can send suggest requests or spellcheck requests. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(SpellingServiceClientTest, AvailableServices) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpellingServiceClient::ServiceType kSuggest = 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SUGGEST; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SpellingServiceClient::ServiceType kSpellcheck = 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpellingServiceClient::SPELLCHECK; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When a user disables spellchecking or prevent using the Spelling service, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this function should return false both for suggestions and for spellcheck. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* pref = profile_.GetPrefs(); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pref->SetBoolean(prefs::kEnableContinuousSpellcheck, false); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->SetBoolean(prefs::kSpellCheckUseSpellingService, false); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(client_.IsAvailable(&profile_, kSuggest)); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(client_.IsAvailable(&profile_, kSpellcheck)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pref->SetBoolean(prefs::kEnableContinuousSpellcheck, true); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->SetBoolean(prefs::kSpellCheckUseSpellingService, true); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For locales supported by the SpellCheck service, this function returns 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false for suggestions and true for spellcheck. (The comment in 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SpellingServiceClient::IsAvailable() describes why this function returns 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false for suggestions.) If there is no language set, then we 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // do not allow any remote. 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pref->SetString(prefs::kSpellCheckDictionary, std::string()); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(client_.IsAvailable(&profile_, kSuggest)); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(client_.IsAvailable(&profile_, kSpellcheck)); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* kSupported[] = { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "en-AU", "en-CA", "en-GB", "en-US", 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If spellcheck is allowed, then suggest is not since spellcheck is a 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // superset of suggest. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSupported); ++i) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->SetString(prefs::kSpellCheckDictionary, kSupported[i]); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(client_.IsAvailable(&profile_, kSuggest)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(client_.IsAvailable(&profile_, kSpellcheck)); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function returns true for suggestions for all and false for 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // spellcheck for unsupported locales. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* kUnsupported[] = { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "af-ZA", "bg-BG", "ca-ES", "cs-CZ", "da-DK", "de-DE", "el-GR", "es-ES", 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "et-EE", "fo-FO", "fr-FR", "he-IL", "hi-IN", "hr-HR", "hu-HU", "id-ID", 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "it-IT", "lt-LT", "lv-LV", "nb-NO", "nl-NL", "pl-PL", "pt-BR", "pt-PT", 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ro-RO", "ru-RU", "sk-SK", "sl-SI", "sh", "sr", "sv-SE", "tr-TR", 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "uk-UA", "vi-VN", 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kUnsupported); ++i) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->SetString(prefs::kSpellCheckDictionary, kUnsupported[i]); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(client_.IsAvailable(&profile_, kSuggest)); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(client_.IsAvailable(&profile_, kSpellcheck)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Verify that an error in JSON response from spelling service will result in 384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// ParseResponse returning false. 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(SpellingServiceClientTest, ResponseErrorTest) { 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(client_.ParseResponseSuccess("{\"result\": {}}")); 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_FALSE(client_.ParseResponseSuccess("{\"error\": {}}")); 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 389