// Copyright 2017 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 "chrome/browser/search/one_google_bar/one_google_bar_loader_impl.h"

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "base/test/test_simple_task_runner.h"
#include "base/time/time.h"
#include "chrome/browser/search/one_google_bar/one_google_bar_data.h"
#include "components/google/core/browser/google_url_tracker.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_service_manager_context.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "services/data_decoder/public/cpp/testing_json_parser.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/pref_names.h"

using testing::_;
using testing::Eq;
using testing::IsEmpty;
using testing::SaveArg;
using testing::StartsWith;

namespace {

const char kApplicationLocale[] = "de";

const char kMinimalValidResponse[] = R"json({"update": { "ogb": {
  "html": { "private_do_not_access_or_else_safe_html_wrapped_value": "" },
  "page_hooks": {}
}}})json";

// Required to instantiate a GoogleUrlTracker in UNIT_TEST_MODE.
class GoogleURLTrackerClientStub : public GoogleURLTrackerClient {
 public:
  GoogleURLTrackerClientStub() {}
  ~GoogleURLTrackerClientStub() override {}

  bool IsBackgroundNetworkingEnabled() override { return true; }
  PrefService* GetPrefs() override { return nullptr; }
  network::SharedURLLoaderFactory* GetURLLoaderFactory() override {
    return nullptr;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(GoogleURLTrackerClientStub);
};

}  // namespace

ACTION_P(Quit, run_loop) {
  run_loop->Quit();
}

class OneGoogleBarLoaderImplTest : public testing::Test {
 public:
  OneGoogleBarLoaderImplTest()
      : OneGoogleBarLoaderImplTest(
            /*api_url_override=*/base::nullopt,
            /*account_consistency_mirror_required=*/false) {}

  explicit OneGoogleBarLoaderImplTest(
      const base::Optional<std::string>& api_url_override)
      : OneGoogleBarLoaderImplTest(
            api_url_override,
            /*account_consistency_mirror_required=*/false) {}

  explicit OneGoogleBarLoaderImplTest(bool account_consistency_mirror_required)
      : OneGoogleBarLoaderImplTest(/*api_url_override=*/base::nullopt,
                                   account_consistency_mirror_required) {}

  OneGoogleBarLoaderImplTest(
      const base::Optional<std::string>& api_url_override,
      bool account_consistency_mirror_required)
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
        google_url_tracker_(std::make_unique<GoogleURLTrackerClientStub>(),
                            GoogleURLTracker::ALWAYS_DOT_COM_MODE),
        test_shared_loader_factory_(
            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
                &test_url_loader_factory_)),
        api_url_override_(api_url_override),
        account_consistency_mirror_required_(
            account_consistency_mirror_required) {}

  ~OneGoogleBarLoaderImplTest() override {
    static_cast<KeyedService&>(google_url_tracker_).Shutdown();
  }

  void SetUp() override {
    testing::Test::SetUp();

    one_google_bar_loader_ = std::make_unique<OneGoogleBarLoaderImpl>(
        test_shared_loader_factory_, &google_url_tracker_, kApplicationLocale,
        api_url_override_, account_consistency_mirror_required_);
  }

  void SetUpResponseWithData(const std::string& response) {
    test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
        [&](const network::ResourceRequest& request) {
          last_request_url_ = request.url;
          last_request_headers_ = request.headers;
        }));
    test_url_loader_factory_.AddResponse(
        one_google_bar_loader_->GetLoadURLForTesting().spec(), response);
  }

  void SetUpResponseWithNetworkError() {
    test_url_loader_factory_.AddResponse(
        one_google_bar_loader_->GetLoadURLForTesting(),
        network::ResourceResponseHead(), std::string(),
        network::URLLoaderCompletionStatus(net::HTTP_NOT_FOUND));
  }

  OneGoogleBarLoaderImpl* one_google_bar_loader() {
    return one_google_bar_loader_.get();
  }

  GURL last_request_url() { return last_request_url_; }
  net::HttpRequestHeaders last_request_headers() {
    return last_request_headers_;
  }

 private:
  // variations::AppendVariationHeaders and SafeJsonParser require a
  // threads and a ServiceManagerConnection to be set.
  content::TestBrowserThreadBundle thread_bundle_;
  content::TestServiceManagerContext service_manager_context_;

  data_decoder::TestingJsonParser::ScopedFactoryOverride factory_override_;

  GoogleURLTracker google_url_tracker_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
  base::Optional<std::string> api_url_override_;
  bool account_consistency_mirror_required_;

  GURL last_request_url_;
  net::HttpRequestHeaders last_request_headers_;

  std::unique_ptr<OneGoogleBarLoaderImpl> one_google_bar_loader_;
};

TEST_F(OneGoogleBarLoaderImplTest, RequestUrlContainsLanguage) {
  SetUpResponseWithData(kMinimalValidResponse);

  // Trigger a request.
  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
  loop.Run();

  // Make sure the request URL contains the "hl=" query param.
  std::string expected_query =
      base::StringPrintf("hl=%s&async=fixed:0", kApplicationLocale);
  EXPECT_EQ(expected_query, last_request_url().query());
}

TEST_F(OneGoogleBarLoaderImplTest, RequestReturns) {
  SetUpResponseWithData(kMinimalValidResponse);

  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::Optional<OneGoogleBarData> data;
  base::RunLoop loop;
  EXPECT_CALL(callback, Run(OneGoogleBarLoader::Status::OK, _))
      .WillOnce(DoAll(SaveArg<1>(&data), Quit(&loop)));
  loop.Run();

  EXPECT_TRUE(data.has_value());
}

TEST_F(OneGoogleBarLoaderImplTest, HandlesResponsePreamble) {
  // The reponse may contain a ")]}'" prefix. The loader should ignore that
  // during parsing.
  SetUpResponseWithData(std::string(")]}'") + kMinimalValidResponse);

  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::Optional<OneGoogleBarData> data;
  base::RunLoop loop;
  EXPECT_CALL(callback, Run(OneGoogleBarLoader::Status::OK, _))
      .WillOnce(DoAll(SaveArg<1>(&data), Quit(&loop)));
  loop.Run();

  EXPECT_TRUE(data.has_value());
}

TEST_F(OneGoogleBarLoaderImplTest, ParsesFullResponse) {
  SetUpResponseWithData(R"json({"update": { "ogb": {
    "html": {
      "private_do_not_access_or_else_safe_html_wrapped_value": "bar_html_value"
    },
    "page_hooks": {
      "in_head_script": {
        "private_do_not_access_or_else_safe_script_wrapped_value":
          "in_head_script_value"
      },
      "in_head_style": {
        "private_do_not_access_or_else_safe_style_sheet_wrapped_value":
          "in_head_style_value"
      },
      "after_bar_script": {
        "private_do_not_access_or_else_safe_script_wrapped_value":
          "after_bar_script_value"
      },
      "end_of_body_html": {
        "private_do_not_access_or_else_safe_html_wrapped_value":
          "end_of_body_html_value"
      },
      "end_of_body_script": {
        "private_do_not_access_or_else_safe_script_wrapped_value":
          "end_of_body_script_value"
      }
    }
  }}})json");

  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::Optional<OneGoogleBarData> data;
  base::RunLoop loop;
  EXPECT_CALL(callback, Run(OneGoogleBarLoader::Status::OK, _))
      .WillOnce(DoAll(SaveArg<1>(&data), Quit(&loop)));
  loop.Run();

  ASSERT_TRUE(data.has_value());
  EXPECT_THAT(data->bar_html, Eq("bar_html_value"));
  EXPECT_THAT(data->in_head_script, Eq("in_head_script_value"));
  EXPECT_THAT(data->in_head_style, Eq("in_head_style_value"));
  EXPECT_THAT(data->after_bar_script, Eq("after_bar_script_value"));
  EXPECT_THAT(data->end_of_body_html, Eq("end_of_body_html_value"));
  EXPECT_THAT(data->end_of_body_script, Eq("end_of_body_script_value"));
}

TEST_F(OneGoogleBarLoaderImplTest, CoalescesMultipleRequests) {
  SetUpResponseWithData(kMinimalValidResponse);

  // Trigger two requests.
  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> first_callback;
  one_google_bar_loader()->Load(first_callback.Get());
  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> second_callback;
  one_google_bar_loader()->Load(second_callback.Get());

  // Make sure that a single response causes both callbacks to be called.
  base::Optional<OneGoogleBarData> first_data;
  base::Optional<OneGoogleBarData> second_data;

  base::RunLoop loop;
  EXPECT_CALL(first_callback, Run(OneGoogleBarLoader::Status::OK, _))
      .WillOnce(SaveArg<1>(&first_data));
  EXPECT_CALL(second_callback, Run(OneGoogleBarLoader::Status::OK, _))
      .WillOnce(DoAll(SaveArg<1>(&second_data), Quit(&loop)));
  loop.Run();

  // Ensure that both requests received a response.
  EXPECT_TRUE(first_data.has_value());
  EXPECT_TRUE(second_data.has_value());
}

TEST_F(OneGoogleBarLoaderImplTest, NetworkErrorIsTransient) {
  SetUpResponseWithNetworkError();

  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback, Run(OneGoogleBarLoader::Status::TRANSIENT_ERROR,
                            Eq(base::nullopt)))
      .WillOnce(Quit(&loop));
  loop.Run();
}

TEST_F(OneGoogleBarLoaderImplTest, InvalidJsonErrorIsFatal) {
  SetUpResponseWithData(kMinimalValidResponse + std::string(")"));

  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback,
              Run(OneGoogleBarLoader::Status::FATAL_ERROR, Eq(base::nullopt)))
      .WillOnce(Quit(&loop));
  loop.Run();
}

TEST_F(OneGoogleBarLoaderImplTest, IncompleteJsonErrorIsFatal) {
  SetUpResponseWithData(R"json({"update": { "ogb": {
  "html": {},
  "page_hooks": {}
}}})json");

  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback,
              Run(OneGoogleBarLoader::Status::FATAL_ERROR, Eq(base::nullopt)))
      .WillOnce(Quit(&loop));
  loop.Run();
}

TEST_F(OneGoogleBarLoaderImplTest, MirrorAccountConsistencyNotRequired) {
  SetUpResponseWithData(kMinimalValidResponse);

  // Trigger a request.
  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
  loop.Run();

#if defined(OS_CHROMEOS)
  // On Chrome OS, X-Chrome-Connected header is present, but
  // enable_account_consistency is set to false.
  std::string header_value;
  EXPECT_TRUE(last_request_headers().GetHeader(signin::kChromeConnectedHeader,
                                               &header_value));
  // mode = PROFILE_MODE_DEFAULT
  EXPECT_EQ("mode=0,enable_account_consistency=false", header_value);
#else
  // On not Chrome OS, the X-Chrome-Connected header must not be present.
  EXPECT_FALSE(
      last_request_headers().HasHeader(signin::kChromeConnectedHeader));
#endif
}

class OneGoogleBarLoaderImplWithMirrorAccountConsistencyTest
    : public OneGoogleBarLoaderImplTest {
 public:
  OneGoogleBarLoaderImplWithMirrorAccountConsistencyTest()
      : OneGoogleBarLoaderImplTest(true) {}
};

TEST_F(OneGoogleBarLoaderImplWithMirrorAccountConsistencyTest,
       MirrorAccountConsistencyRequired) {
  SetUpResponseWithData(kMinimalValidResponse);

  // Trigger a request.
  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
  loop.Run();

  // Make sure mirror account consistency is requested.
#if defined(OS_CHROMEOS)
  // On Chrome OS, X-Chrome-Connected header is present, and
  // enable_account_consistency is set to true.
  std::string header_value;
  EXPECT_TRUE(last_request_headers().GetHeader(signin::kChromeConnectedHeader,
                                               &header_value));
  // mode = PROFILE_MODE_INCOGNITO_DISABLED | PROFILE_MODE_ADD_ACCOUNT_DISABLED
  EXPECT_EQ("mode=3,enable_account_consistency=true", header_value);
#else
  // This is not a valid case (mirror account consistency can only be required
  // on Chrome OS). This ensures in this case nothing happens.
  EXPECT_FALSE(
      last_request_headers().HasHeader(signin::kChromeConnectedHeader));
#endif
}

class OneGoogleBarLoaderImplWithRelativeApiUrlOverrideTest
    : public OneGoogleBarLoaderImplTest {
 public:
  OneGoogleBarLoaderImplWithRelativeApiUrlOverrideTest()
      : OneGoogleBarLoaderImplTest(std::string("/testapi?q=a")) {}
};

TEST_F(OneGoogleBarLoaderImplWithRelativeApiUrlOverrideTest,
       RequestUrlRespectsOverride) {
  SetUpResponseWithData(kMinimalValidResponse);

  // Trigger a request.
  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
  loop.Run();

  // Make sure the request URL corresponds to the override, but also contains
  // the "hl=" query param.
  EXPECT_EQ("/testapi", last_request_url().path());
  std::string expected_query =
      base::StringPrintf("q=a&hl=%s&async=fixed:0", kApplicationLocale);
  EXPECT_EQ(expected_query, last_request_url().query());
}

class OneGoogleBarLoaderImplWithAbsoluteApiUrlOverrideTest
    : public OneGoogleBarLoaderImplTest {
 public:
  OneGoogleBarLoaderImplWithAbsoluteApiUrlOverrideTest()
      : OneGoogleBarLoaderImplTest(std::string("http://test.com/path?q=a")) {}
};

TEST_F(OneGoogleBarLoaderImplWithAbsoluteApiUrlOverrideTest,
       RequestUrlRespectsOverride) {
  SetUpResponseWithData(kMinimalValidResponse);

  // Trigger a request.
  base::MockCallback<OneGoogleBarLoader::OneGoogleCallback> callback;
  one_google_bar_loader()->Load(callback.Get());

  base::RunLoop loop;
  EXPECT_CALL(callback, Run(_, _)).WillOnce(Quit(&loop));
  loop.Run();

  // Make sure the request URL corresponds to the override, but also contains
  // the "hl=" query param.
  GURL expected_url = GURL(base::StringPrintf(
      "http://test.com/path?q=a&hl=%s&async=fixed:0", kApplicationLocale));
  EXPECT_EQ(expected_url, last_request_url());
}
