// Copyright 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 "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/test_content_client.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {
namespace {

const int kDummyStringId = 123;
const int kDummyDefaultResourceId = 456;
const int kDummyResourceId = 789;

const char kDummyString[] = "foo";
const char kDummyDefaultResource[] = "<html>foo</html>";
const char kDummyResource[] = "<html>blah</html>";

class TestClient : public TestContentClient {
 public:
  TestClient() {}
  ~TestClient() override {}

  base::string16 GetLocalizedString(int message_id) const override {
    if (message_id == kDummyStringId)
      return base::UTF8ToUTF16(kDummyString);
    return base::string16();
  }

  base::RefCountedMemory* GetDataResourceBytes(
      int resource_id) const override {
    base::RefCountedStaticMemory* bytes = NULL;
    if (resource_id == kDummyDefaultResourceId) {
      bytes = new base::RefCountedStaticMemory(
          kDummyDefaultResource, arraysize(kDummyDefaultResource));
    } else if (resource_id == kDummyResourceId) {
      bytes = new base::RefCountedStaticMemory(kDummyResource,
                                               arraysize(kDummyResource));
    }
    return bytes;
  }
};

}  // namespace

class WebUIDataSourceTest : public testing::Test {
 public:
  WebUIDataSourceTest() {}
  ~WebUIDataSourceTest() override {}
  WebUIDataSourceImpl* source() { return source_.get(); }

  void StartDataRequest(const std::string& path,
                        const URLDataSource::GotDataCallback& callback) {
    source_->StartDataRequest(path, ResourceRequestInfo::WebContentsGetter(),
                              callback);
  }

  std::string GetMimeType(const std::string& path) const {
    return source_->GetMimeType(path);
  }

  bool HandleRequest(const std::string& path,
                     const WebUIDataSourceImpl::GotDataCallback&) {
    request_path_ = path;
    return true;
  }

  void RequestFilterQueryStringCallback(
      scoped_refptr<base::RefCountedMemory> data);

 protected:
  std::string request_path_;

 private:
  void SetUp() override {
    SetContentClient(&client_);
    WebUIDataSource* source = WebUIDataSourceImpl::Create("host");
    WebUIDataSourceImpl* source_impl = static_cast<WebUIDataSourceImpl*>(
        source);
    source_impl->disable_load_time_data_defaults_for_testing();
    source_ = make_scoped_refptr(source_impl);
  }

  TestBrowserThreadBundle thread_bundle_;
  scoped_refptr<WebUIDataSourceImpl> source_;
  TestClient client_;
};

void EmptyStringsCallback(scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  EXPECT_NE(result.find("loadTimeData.data = {"), std::string::npos);
  EXPECT_NE(result.find("};"), std::string::npos);
}

TEST_F(WebUIDataSourceTest, EmptyStrings) {
  source()->SetJsonPath("strings.js");
  StartDataRequest("strings.js", base::Bind(&EmptyStringsCallback));
}

void SomeValuesCallback(scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  EXPECT_NE(result.find("\"flag\":true"), std::string::npos);
  EXPECT_NE(result.find("\"counter\":10"), std::string::npos);
  EXPECT_NE(result.find("\"debt\":-456"), std::string::npos);
  EXPECT_NE(result.find("\"planet\":\"pluto\""), std::string::npos);
  EXPECT_NE(result.find("\"button\":\"foo\""), std::string::npos);
}

TEST_F(WebUIDataSourceTest, SomeValues) {
  source()->SetJsonPath("strings.js");
  source()->AddBoolean("flag", true);
  source()->AddInteger("counter", 10);
  source()->AddInteger("debt", -456);
  source()->AddString("planet", base::ASCIIToUTF16("pluto"));
  source()->AddLocalizedString("button", kDummyStringId);
  StartDataRequest("strings.js", base::Bind(&SomeValuesCallback));
}

void DefaultResourceFoobarCallback(scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
}

void DefaultResourceStringsCallback(
    scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
}

TEST_F(WebUIDataSourceTest, DefaultResource) {
  source()->SetDefaultResource(kDummyDefaultResourceId);
  StartDataRequest("foobar", base::Bind(&DefaultResourceFoobarCallback));
  StartDataRequest("strings.js", base::Bind(&DefaultResourceStringsCallback));
}

void NamedResourceFoobarCallback(scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  EXPECT_NE(result.find(kDummyResource), std::string::npos);
}

void NamedResourceStringsCallback(scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  EXPECT_NE(result.find(kDummyDefaultResource), std::string::npos);
}

TEST_F(WebUIDataSourceTest, NamedResource) {
  source()->SetDefaultResource(kDummyDefaultResourceId);
  source()->AddResourcePath("foobar", kDummyResourceId);
  StartDataRequest("foobar", base::Bind(&NamedResourceFoobarCallback));
  StartDataRequest("strings.js", base::Bind(&NamedResourceStringsCallback));
}

void NamedResourceWithQueryStringCallback(
    scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  EXPECT_NE(result.find(kDummyResource), std::string::npos);
}

TEST_F(WebUIDataSourceTest, NamedResourceWithQueryString) {
  source()->SetDefaultResource(kDummyDefaultResourceId);
  source()->AddResourcePath("foobar", kDummyResourceId);
  StartDataRequest("foobar?query?string",
                   base::Bind(&NamedResourceWithQueryStringCallback));
}

void WebUIDataSourceTest::RequestFilterQueryStringCallback(
    scoped_refptr<base::RefCountedMemory> data) {
  std::string result(data->front_as<char>(), data->size());
  // Check that the query string is passed to the request filter (and not
  // trimmed).
  EXPECT_EQ("foobar?query?string", request_path_);
}

TEST_F(WebUIDataSourceTest, RequestFilterQueryString) {
  request_path_ = std::string();
  source()->SetRequestFilter(
      base::Bind(&WebUIDataSourceTest::HandleRequest, base::Unretained(this)));
  source()->SetDefaultResource(kDummyDefaultResourceId);
  source()->AddResourcePath("foobar", kDummyResourceId);
  StartDataRequest(
      "foobar?query?string",
      base::Bind(&WebUIDataSourceTest::RequestFilterQueryStringCallback,
                 base::Unretained(this)));
}

TEST_F(WebUIDataSourceTest, MimeType) {
  const char* css = "text/css";
  const char* html = "text/html";
  const char* js = "application/javascript";
  EXPECT_EQ(GetMimeType(std::string()), html);
  EXPECT_EQ(GetMimeType("foo"), html);
  EXPECT_EQ(GetMimeType("foo.html"), html);
  EXPECT_EQ(GetMimeType(".js"), js);
  EXPECT_EQ(GetMimeType("foo.js"), js);
  EXPECT_EQ(GetMimeType("js"), html);
  EXPECT_EQ(GetMimeType("foojs"), html);
  EXPECT_EQ(GetMimeType("foo.jsp"), html);
  EXPECT_EQ(GetMimeType("foocss"), html);
  EXPECT_EQ(GetMimeType("foo.css"), css);
  EXPECT_EQ(GetMimeType(".css.foo"), html);

  // With query strings.
  EXPECT_EQ(GetMimeType("foo?abc?abc"), html);
  EXPECT_EQ(GetMimeType("foo.html?abc?abc"), html);
  EXPECT_EQ(GetMimeType("foo.css?abc?abc"), css);
  EXPECT_EQ(GetMimeType("foo.js?abc?abc"), js);
}

}  // namespace content
