// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/spellcheck/browser/spelling_service_client.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/values.h"
#include "chrome/test/base/testing_profile.h"
#include "components/prefs/pref_service.h"
#include "components/spellcheck/browser/pref_names.h"
#include "components/spellcheck/common/spellcheck_result.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/load_flags.h"
#include "net/http/http_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const char kSpellingServiceURL[] = "https://www.googleapis.com/rpc";

// A class derived from the SpellingServiceClient class used by the
// SpellingServiceClientTest class. This class sets the URLLoaderFactory so
// tests can control requests and responses.
class TestingSpellingServiceClient : public SpellingServiceClient {
 public:
  TestingSpellingServiceClient()
      : success_(false),
        test_shared_loader_factory_(
            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
                &test_url_loader_factory_)) {
    SetURLLoaderFactoryForTesting(test_shared_loader_factory_);
  }
  ~TestingSpellingServiceClient() {}

  void SetExpectedTextCheckResult(bool success,
                                  const std::string& sanitized_request_text,
                                  const char* text) {
    success_ = success;
    sanitized_request_text_ = sanitized_request_text;
    corrected_text_.assign(base::UTF8ToUTF16(text));
  }

  void VerifyResponse(bool success,
                      const base::string16& request_text,
                      const std::vector<SpellCheckResult>& results) {
    EXPECT_EQ(success_, success);
    base::string16 text(base::UTF8ToUTF16(sanitized_request_text_));
    for (auto it = results.begin(); it != results.end(); ++it) {
      text.replace(it->location, it->length, it->replacements[0]);
    }
    EXPECT_EQ(corrected_text_, text);
  }

  bool ParseResponseSuccess(const std::string& data) {
    std::vector<SpellCheckResult> results;
    return ParseResponse(data, &results);
  }

  network::TestURLLoaderFactory* test_url_loader_factory() {
    return &test_url_loader_factory_;
  }

 private:
  bool success_;
  std::string sanitized_request_text_;
  base::string16 corrected_text_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
};

// A test class used for testing the SpellingServiceClient class. This class
// implements a callback function used by the SpellingServiceClient class to
// monitor the class calls the callback with expected results.
class SpellingServiceClientTest : public testing::Test {
 public:
  void OnTextCheckComplete(int tag,
                           bool success,
                           const base::string16& text,
                           const std::vector<SpellCheckResult>& results) {
    client_.VerifyResponse(success, text, results);
  }

 protected:
  bool GetExpectedCountry(const std::string& language, std::string* country) {
    static const struct {
      const char* language;
      const char* country;
    } kCountries[] = {
        {"af", "ZAF"}, {"en", "USA"},
    };
    for (size_t i = 0; i < base::size(kCountries); ++i) {
      if (!language.compare(kCountries[i].language)) {
        country->assign(kCountries[i].country);
        return true;
      }
    }
    return false;
  }

  content::TestBrowserThreadBundle thread_bundle_;
  TestingSpellingServiceClient client_;
  TestingProfile profile_;
};

}  // namespace

// Verifies that SpellingServiceClient::RequestTextCheck() creates a JSON
// request sent to the Spelling service as we expect. This test also verifies
// that it parses a JSON response from the service and calls the callback
// function. To avoid sending JSON-RPC requests to the service, this test uses a
// subclass of SpellingServiceClient that in turn sets the client's URL loader
// factory to a TestURLLoaderFactory. The client thinks it is issuing real
// network requests, but in fact the responses are entirely under our control
// and no network activity takes place.
// This test also uses a custom callback function that replaces all
// misspelled words with ones suggested by the service so this test can compare
// the corrected text with the expected results. (If there are not any
// misspelled words, |corrected_text| should be equal to |request_text|.)
TEST_F(SpellingServiceClientTest, RequestTextCheck) {
  static const struct {
    const wchar_t* request_text;
    std::string sanitized_request_text;
    SpellingServiceClient::ServiceType request_type;
    net::HttpStatusCode response_status;
    std::string response_data;
    bool success;
    const char* corrected_text;
    std::string language;
  } kTests[] = {
      {
          L"", "", SpellingServiceClient::SUGGEST, net::HttpStatusCode(500), "",
          false, "", "af",
      },
      {
          L"chromebook", "chromebook", SpellingServiceClient::SUGGEST,
          net::HttpStatusCode(200), "{}", true, "chromebook", "af",
      },
      {
          L"chrombook", "chrombook", SpellingServiceClient::SUGGEST,
          net::HttpStatusCode(200),
          "{\n"
          "  \"result\": {\n"
          "    \"spellingCheckResponse\": {\n"
          "      \"misspellings\": [{\n"
          "        \"charStart\": 0,\n"
          "        \"charLength\": 9,\n"
          "        \"suggestions\": [{ \"suggestion\": \"chromebook\" }],\n"
          "        \"canAutoCorrect\": false\n"
          "      }]\n"
          "    }\n"
          "  }\n"
          "}",
          true, "chromebook", "af",
      },
      {
          L"", "", SpellingServiceClient::SPELLCHECK, net::HttpStatusCode(500),
          "", false, "", "en",
      },
      {
          L"I have been to USA.", "I have been to USA.",
          SpellingServiceClient::SPELLCHECK, net::HttpStatusCode(200), "{}",
          true, "I have been to USA.", "en",
      },
      {
          L"I have bean to USA.", "I have bean to USA.",
          SpellingServiceClient::SPELLCHECK, net::HttpStatusCode(200),
          "{\n"
          "  \"result\": {\n"
          "    \"spellingCheckResponse\": {\n"
          "      \"misspellings\": [{\n"
          "        \"charStart\": 7,\n"
          "        \"charLength\": 4,\n"
          "        \"suggestions\": [{ \"suggestion\": \"been\" }],\n"
          "        \"canAutoCorrect\": false\n"
          "      }]\n"
          "    }\n"
          "  }\n"
          "}",
          true, "I have been to USA.", "en",
      },
      {
          L"I\x2019mattheIn'n'Out.", "I'mattheIn'n'Out.",
          SpellingServiceClient::SPELLCHECK, net::HttpStatusCode(200),
          "{\n"
          "  \"result\": {\n"
          "    \"spellingCheckResponse\": {\n"
          "      \"misspellings\": [{\n"
          "        \"charStart\": 0,\n"
          "        \"charLength\": 16,\n"
          "        \"suggestions\":"
          " [{ \"suggestion\": \"I'm at the In'N'Out\" }],\n"
          "        \"canAutoCorrect\": false\n"
          "      }]\n"
          "    }\n"
          "  }\n"
          "}",
          true, "I'm at the In'N'Out.", "en",
      },
  };

  PrefService* pref = profile_.GetPrefs();
  pref->SetBoolean(spellcheck::prefs::kSpellCheckEnable, true);
  pref->SetBoolean(spellcheck::prefs::kSpellCheckUseSpellingService, true);

  for (size_t i = 0; i < base::size(kTests); ++i) {
    client_.test_url_loader_factory()->ClearResponses();
    net::HttpStatusCode http_status = kTests[i].response_status;
    network::ResourceResponseHead head;
    std::string headers(base::StringPrintf(
        "HTTP/1.1 %d %s\nContent-type: application/json\n\n",
        static_cast<int>(http_status), net::GetHttpReasonPhrase(http_status)));
    head.headers = new net::HttpResponseHeaders(
        net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
    head.mime_type = "application/json";
    network::URLLoaderCompletionStatus status;
    status.decoded_body_length = kTests[i].response_data.size();
    client_.test_url_loader_factory()->AddResponse(
        GURL(kSpellingServiceURL), head, kTests[i].response_data, status);
    net::HttpRequestHeaders intercepted_headers;
    std::string intercepted_body;
    client_.test_url_loader_factory()->SetInterceptor(
        base::BindLambdaForTesting(
            [&](const network::ResourceRequest& request) {
              intercepted_headers = request.headers;
              intercepted_body = network::GetUploadData(request);
            }));
    client_.SetExpectedTextCheckResult(kTests[i].success,
                                       kTests[i].sanitized_request_text,
                                       kTests[i].corrected_text);
    base::ListValue dictionary;
    dictionary.AppendString(kTests[i].language);
    pref->Set(spellcheck::prefs::kSpellCheckDictionaries, dictionary);

    client_.RequestTextCheck(
        &profile_, kTests[i].request_type,
        base::WideToUTF16(kTests[i].request_text),
        base::BindOnce(&SpellingServiceClientTest::OnTextCheckComplete,
                       base::Unretained(this), 0));
    thread_bundle_.RunUntilIdle();

    // Verify the request content type was JSON. (The Spelling service returns
    // an internal server error when this content type is not JSON.)
    std::string request_content_type;
    ASSERT_TRUE(intercepted_headers.GetHeader(
        net::HttpRequestHeaders::kContentType, &request_content_type));
    EXPECT_EQ("application/json", request_content_type);

    // Parse the JSON sent to the service, and verify its parameters.
    std::unique_ptr<base::DictionaryValue> value(
        static_cast<base::DictionaryValue*>(
            base::JSONReader::Read(intercepted_body,
                                   base::JSON_ALLOW_TRAILING_COMMAS)
                .release()));
    ASSERT_TRUE(value.get());
    std::string method;
    EXPECT_TRUE(value->GetString("method", &method));
    EXPECT_EQ("spelling.check", method);
    std::string version;
    EXPECT_TRUE(value->GetString("apiVersion", &version));
    EXPECT_EQ(base::StringPrintf("v%d", kTests[i].request_type), version);
    std::string sanitized_text;
    EXPECT_TRUE(value->GetString("params.text", &sanitized_text));
    EXPECT_EQ(kTests[i].sanitized_request_text, sanitized_text);
    std::string language;
    EXPECT_TRUE(value->GetString("params.language", &language));
    std::string expected_language =
        kTests[i].language.empty() ? std::string("en") : kTests[i].language;
    EXPECT_EQ(expected_language, language);
    std::string expected_country;
    ASSERT_TRUE(GetExpectedCountry(language, &expected_country));
    std::string country;
    EXPECT_TRUE(value->GetString("params.originCountry", &country));
    EXPECT_EQ(expected_country, country);
  }
}

// Verify that SpellingServiceClient::IsAvailable() returns true only when it
// can send suggest requests or spellcheck requests.
TEST_F(SpellingServiceClientTest, AvailableServices) {
  const SpellingServiceClient::ServiceType kSuggest =
      SpellingServiceClient::SUGGEST;
  const SpellingServiceClient::ServiceType kSpellcheck =
      SpellingServiceClient::SPELLCHECK;

  // When a user disables spellchecking or prevent using the Spelling service,
  // this function should return false both for suggestions and for spellcheck.
  PrefService* pref = profile_.GetPrefs();
  pref->SetBoolean(spellcheck::prefs::kSpellCheckEnable, false);
  pref->SetBoolean(spellcheck::prefs::kSpellCheckUseSpellingService, false);
  EXPECT_FALSE(client_.IsAvailable(&profile_, kSuggest));
  EXPECT_FALSE(client_.IsAvailable(&profile_, kSpellcheck));

  pref->SetBoolean(spellcheck::prefs::kSpellCheckEnable, true);
  pref->SetBoolean(spellcheck::prefs::kSpellCheckUseSpellingService, true);

  // For locales supported by the SpellCheck service, this function returns
  // false for suggestions and true for spellcheck. (The comment in
  // SpellingServiceClient::IsAvailable() describes why this function returns
  // false for suggestions.) If there is no language set, then we
  // do not allow any remote.
  pref->Set(spellcheck::prefs::kSpellCheckDictionaries, base::ListValue());

  EXPECT_FALSE(client_.IsAvailable(&profile_, kSuggest));
  EXPECT_FALSE(client_.IsAvailable(&profile_, kSpellcheck));

  static const char* kSupported[] = {
      "en-AU", "en-CA", "en-GB", "en-US", "da-DK", "es-ES",
  };
  // If spellcheck is allowed, then suggest is not since spellcheck is a
  // superset of suggest.
  for (size_t i = 0; i < base::size(kSupported); ++i) {
    base::ListValue dictionary;
    dictionary.AppendString(kSupported[i]);
    pref->Set(spellcheck::prefs::kSpellCheckDictionaries, dictionary);

    EXPECT_FALSE(client_.IsAvailable(&profile_, kSuggest));
    EXPECT_TRUE(client_.IsAvailable(&profile_, kSpellcheck));
  }

  // This function returns true for suggestions for all and false for
  // spellcheck for unsupported locales.
  static const char* kUnsupported[] = {
      "af-ZA", "bg-BG", "ca-ES", "cs-CZ", "de-DE", "el-GR", "et-EE", "fo-FO",
      "fr-FR", "he-IL", "hi-IN", "hr-HR", "hu-HU", "id-ID", "it-IT", "lt-LT",
      "lv-LV", "nb-NO", "nl-NL", "pl-PL", "pt-BR", "pt-PT", "ro-RO", "ru-RU",
      "sk-SK", "sl-SI", "sh",    "sr",    "sv-SE", "tr-TR", "uk-UA", "vi-VN",
  };
  for (size_t i = 0; i < base::size(kUnsupported); ++i) {
    SCOPED_TRACE(std::string("Expected language ") + kUnsupported[i]);
    base::ListValue dictionary;
    dictionary.AppendString(kUnsupported[i]);
    pref->Set(spellcheck::prefs::kSpellCheckDictionaries, dictionary);

    EXPECT_TRUE(client_.IsAvailable(&profile_, kSuggest));
    EXPECT_FALSE(client_.IsAvailable(&profile_, kSpellcheck));
  }
}

// Verify that an error in JSON response from spelling service will result in
// ParseResponse returning false.
TEST_F(SpellingServiceClientTest, ResponseErrorTest) {
  EXPECT_TRUE(client_.ParseResponseSuccess("{\"result\": {}}"));
  EXPECT_FALSE(client_.ParseResponseSuccess("{\"error\": {}}"));
}
