- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / search / iframe_source_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/search/iframe_source.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ref_counted_memory.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "chrome/browser/search/instant_io_context.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/test/mock_resource_context.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "grit/browser_resources.h"
17 #include "net/base/request_priority.h"
18 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_context.h"
20 #include "net/url_request/url_request_test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "url/gurl.h"
23
24 const int kNonInstantRendererPID = 0;
25 const char kNonInstantOrigin[] = "http://evil";
26 const int kInstantRendererPID = 1;
27 const char kInstantOrigin[] = "chrome-search://instant";
28 const int kInvalidRendererPID = 42;
29
30 class TestIframeSource : public IframeSource {
31  public:
32   using IframeSource::GetMimeType;
33   using IframeSource::ShouldServiceRequest;
34   using IframeSource::SendResource;
35   using IframeSource::SendJSWithOrigin;
36
37  protected:
38   virtual std::string GetSource() const OVERRIDE {
39     return "test";
40   }
41
42   virtual bool ServesPath(const std::string& path) const OVERRIDE {
43     return path == "/valid.html" || path == "/valid.js";
44   }
45
46   virtual void StartDataRequest(
47       const std::string& path,
48       int render_process_id,
49       int render_view_id,
50       const content::URLDataSource::GotDataCallback& callback) OVERRIDE {
51   }
52
53   // RenderViewHost is hard to mock in concert with everything else, so stub
54   // this method out for testing.
55   virtual bool GetOrigin(
56       int process_id,
57       int render_view_id,
58       std::string* origin) const OVERRIDE {
59     if (process_id == kInstantRendererPID) {
60       *origin = kInstantOrigin;
61       return true;
62     }
63     if (process_id == kNonInstantRendererPID) {
64       *origin = kNonInstantOrigin;
65       return true;
66     }
67     return false;
68   }
69 };
70
71 class IframeSourceTest : public testing::Test {
72  public:
73   // net::URLRequest wants to be executed with a message loop that has TYPE_IO.
74   // InstantIOContext needs to be created on the UI thread and have everything
75   // else happen on the IO thread. This setup is a hacky way to satisfy all
76   // those constraints.
77   IframeSourceTest()
78       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
79         resource_context_(&test_url_request_context_),
80         instant_io_context_(NULL),
81         response_(NULL) {
82   }
83
84   TestIframeSource* source() { return source_.get(); }
85
86   std::string response_string() {
87     if (response_.get()) {
88       return std::string(reinterpret_cast<const char*>(response_->front()),
89                          response_->size());
90     }
91     return "";
92   }
93
94   net::URLRequest* MockRequest(
95       const std::string& url,
96       bool allocate_info,
97       int render_process_id,
98       int render_view_id) {
99     net::URLRequest* request =
100         new net::URLRequest(GURL(url),
101                             net::DEFAULT_PRIORITY,
102                             NULL,
103                             resource_context_.GetRequestContext());
104     if (allocate_info) {
105       content::ResourceRequestInfo::AllocateForTesting(request,
106                                                        ResourceType::SUB_FRAME,
107                                                        &resource_context_,
108                                                        render_process_id,
109                                                        render_view_id,
110                                                        false);
111     }
112     return request;
113   }
114
115   void SendResource(int resource_id) {
116     source()->SendResource(resource_id, callback_);
117   }
118
119   void SendJSWithOrigin(
120       int resource_id,
121       int render_process_id,
122       int render_view_id) {
123     source()->SendJSWithOrigin(resource_id, render_process_id, render_view_id,
124                                callback_);
125   }
126
127  private:
128   virtual void SetUp() OVERRIDE {
129     source_.reset(new TestIframeSource());
130     callback_ = base::Bind(&IframeSourceTest::SaveResponse,
131                            base::Unretained(this));
132     instant_io_context_ = new InstantIOContext;
133     InstantIOContext::SetUserDataOnIO(&resource_context_, instant_io_context_);
134     InstantIOContext::AddInstantProcessOnIO(instant_io_context_,
135                                             kInstantRendererPID);
136     response_ = NULL;
137   }
138
139   virtual void TearDown() {
140     source_.reset();
141   }
142
143   void SaveResponse(base::RefCountedMemory* data) {
144     response_ = data;
145   }
146
147   content::TestBrowserThreadBundle thread_bundle_;
148
149   net::TestURLRequestContext test_url_request_context_;
150   content::MockResourceContext resource_context_;
151   scoped_ptr<TestIframeSource> source_;
152   content::URLDataSource::GotDataCallback callback_;
153   scoped_refptr<InstantIOContext> instant_io_context_;
154   scoped_refptr<base::RefCountedMemory> response_;
155 };
156
157 TEST_F(IframeSourceTest, ShouldServiceRequest) {
158   scoped_ptr<net::URLRequest> request;
159   request.reset(MockRequest("http://test/loader.js", true,
160                             kNonInstantRendererPID, 0));
161   EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
162   request.reset(MockRequest("chrome-search://bogus/valid.js", true,
163                             kInstantRendererPID, 0));
164   EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
165   request.reset(MockRequest("chrome-search://test/bogus.js", true,
166                             kInstantRendererPID, 0));
167   EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
168   request.reset(MockRequest("chrome-search://test/valid.js", true,
169                             kInstantRendererPID, 0));
170   EXPECT_TRUE(source()->ShouldServiceRequest(request.get()));
171   request.reset(MockRequest("chrome-search://test/valid.js", true,
172                             kNonInstantRendererPID, 0));
173   EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
174   request.reset(MockRequest("chrome-search://test/valid.js", true,
175                             kInvalidRendererPID, 0));
176   EXPECT_FALSE(source()->ShouldServiceRequest(request.get()));
177 }
178
179 TEST_F(IframeSourceTest, GetMimeType) {
180   // URLDataManagerBackend does not include / in path_and_query.
181   EXPECT_EQ("text/html", source()->GetMimeType("foo.html"));
182   EXPECT_EQ("application/javascript", source()->GetMimeType("foo.js"));
183   EXPECT_EQ("text/css", source()->GetMimeType("foo.css"));
184   EXPECT_EQ("image/png", source()->GetMimeType("foo.png"));
185   EXPECT_EQ("", source()->GetMimeType("bogus"));
186 }
187
188 TEST_F(IframeSourceTest, SendResource) {
189   SendResource(IDR_MOST_VISITED_TITLE_HTML);
190   EXPECT_FALSE(response_string().empty());
191 }
192
193 TEST_F(IframeSourceTest, SendJSWithOrigin) {
194   SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kInstantRendererPID, 0);
195   EXPECT_FALSE(response_string().empty());
196   SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kNonInstantRendererPID, 0);
197   EXPECT_FALSE(response_string().empty());
198   SendJSWithOrigin(IDR_MOST_VISITED_TITLE_JS, kInvalidRendererPID, 0);
199   EXPECT_TRUE(response_string().empty());
200 }