// 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/macros.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 < arraysize(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 < arraysize(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 < arraysize(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 < arraysize(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\": {}}"));
}
