|  | // 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 |