| // Copyright (c) 2006-2008 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 <string> |
| #include <vector> |
| |
| #include "base/process.h" |
| #include "base/scoped_ptr.h" |
| #include "chrome/common/filter_policy.h" |
| #include "chrome/common/render_messages.h" |
| #include "chrome/common/resource_dispatcher.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "webkit/glue/webappcachecontext.h" |
| |
| using webkit_glue::ResourceLoaderBridge; |
| |
| static const char test_page_url[] = "http://www.google.com/"; |
| static const char test_page_headers[] = |
| "HTTP/1.1 200 OK\nContent-Type:text/html\n\n"; |
| static const char test_page_mime_type[] = "text/html"; |
| static const char test_page_charset[] = ""; |
| static const char test_page_contents[] = |
| "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>"; |
| static const int test_page_contents_len = arraysize(test_page_contents) - 1; |
| |
| // Listens for request response data and stores it so that it can be compared |
| // to the reference data. |
| class TestRequestCallback : public ResourceLoaderBridge::Peer { |
| public: |
| TestRequestCallback() : complete_(false) { |
| } |
| |
| virtual void OnReceivedRedirect(const GURL& new_url) { |
| } |
| |
| virtual void OnReceivedResponse( |
| const ResourceLoaderBridge::ResponseInfo& info, |
| bool content_filtered) { |
| } |
| |
| virtual void OnReceivedData(const char* data, int len) { |
| EXPECT_FALSE(complete_); |
| data_.append(data, len); |
| } |
| |
| virtual void OnUploadProgress(uint64 position, uint64 size) { |
| } |
| |
| virtual void OnCompletedRequest(const URLRequestStatus& status, |
| const std::string& security_info) { |
| EXPECT_FALSE(complete_); |
| complete_ = true; |
| } |
| |
| virtual std::string GetURLForDebugging() { |
| return std::string(); |
| } |
| |
| const std::string& data() const { |
| return data_; |
| } |
| const bool complete() const { |
| return complete_; |
| } |
| |
| private: |
| bool complete_; |
| std::string data_; |
| }; |
| |
| |
| // Sets up the message sender override for the unit test |
| class ResourceDispatcherTest : public testing::Test, |
| public IPC::Message::Sender { |
| public: |
| // Emulates IPC send operations (IPC::Message::Sender) by adding |
| // pending messages to the queue. |
| virtual bool Send(IPC::Message* msg) { |
| message_queue_.push_back(IPC::Message(*msg)); |
| delete msg; |
| return true; |
| } |
| |
| // Emulates the browser process and processes the pending IPC messages, |
| // returning the hardcoded file contents. |
| void ProcessMessages() { |
| while (!message_queue_.empty()) { |
| int request_id; |
| ViewHostMsg_Resource_Request request; |
| ASSERT_TRUE(ViewHostMsg_RequestResource::Read( |
| &message_queue_[0], &request_id, &request)); |
| |
| // check values |
| EXPECT_EQ(test_page_url, request.url.spec()); |
| |
| // received response message |
| ResourceResponseHead response; |
| std::string raw_headers(test_page_headers); |
| std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0'); |
| response.headers = new net::HttpResponseHeaders(raw_headers); |
| response.mime_type = test_page_mime_type; |
| response.charset = test_page_charset; |
| response.filter_policy = FilterPolicy::DONT_FILTER; |
| dispatcher_->OnReceivedResponse(request_id, response); |
| |
| // received data message with the test contents |
| base::SharedMemory shared_mem; |
| EXPECT_TRUE(shared_mem.Create(std::wstring(), |
| false, false, test_page_contents_len)); |
| EXPECT_TRUE(shared_mem.Map(test_page_contents_len)); |
| char* put_data_here = static_cast<char*>(shared_mem.memory()); |
| memcpy(put_data_here, test_page_contents, test_page_contents_len); |
| base::SharedMemoryHandle dup_handle; |
| EXPECT_TRUE(shared_mem.GiveToProcess( |
| base::Process::Current().handle(), &dup_handle)); |
| dispatcher_->OnReceivedData( |
| message_queue_[0], request_id, dup_handle, test_page_contents_len); |
| |
| message_queue_.erase(message_queue_.begin()); |
| |
| // read the ack message. |
| int request_ack = -1; |
| ASSERT_TRUE(ViewHostMsg_DataReceived_ACK::Read( |
| &message_queue_[0], &request_ack)); |
| |
| ASSERT_EQ(request_ack, request_id); |
| |
| message_queue_.erase(message_queue_.begin()); |
| } |
| } |
| |
| protected: |
| static ResourceDispatcher* GetResourceDispatcher(WebFrame* unused) { |
| return dispatcher_.get(); |
| } |
| |
| // testing::Test |
| virtual void SetUp() { |
| dispatcher_.reset(new ResourceDispatcher(this)); |
| } |
| virtual void TearDown() { |
| dispatcher_.reset(); |
| } |
| |
| std::vector<IPC::Message> message_queue_; |
| static scoped_ptr<ResourceDispatcher> dispatcher_; |
| }; |
| |
| /*static*/ |
| scoped_ptr<ResourceDispatcher> ResourceDispatcherTest::dispatcher_; |
| |
| // Does a simple request and tests that the correct data is received. |
| TEST_F(ResourceDispatcherTest, RoundTrip) { |
| TestRequestCallback callback; |
| ResourceLoaderBridge* bridge = |
| dispatcher_->CreateBridge("GET", GURL(test_page_url), GURL(test_page_url), |
| GURL(), "null", "null", std::string(), 0, 0, |
| ResourceType::SUB_RESOURCE, 0, |
| WebAppCacheContext::kNoAppCacheContextId, |
| MSG_ROUTING_CONTROL); |
| |
| bridge->Start(&callback); |
| |
| ProcessMessages(); |
| |
| // FIXME(brettw) when the request complete messages are actually handledo |
| // and dispatched, uncomment this. |
| //EXPECT_TRUE(callback.complete()); |
| //EXPECT_STREQ(test_page_contents, callback.data().c_str()); |
| |
| delete bridge; |
| } |
| |
| // Tests that the request IDs are straight when there are multiple requests. |
| TEST_F(ResourceDispatcherTest, MultipleRequests) { |
| // FIXME |
| } |
| |
| // Tests that the cancel method prevents other messages from being received |
| TEST_F(ResourceDispatcherTest, Cancel) { |
| // FIXME |
| } |
| |
| TEST_F(ResourceDispatcherTest, Cookies) { |
| // FIXME |
| } |
| |
| TEST_F(ResourceDispatcherTest, SerializedPostData) { |
| // FIXME |
| } |