1// Copyright (c) 2011 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/common/net/test_url_fetcher_factory.h" 6 7#include <string> 8 9#include "base/compiler_specific.h" 10#include "base/message_loop.h" 11#include "net/url_request/url_request_status.h" 12 13TestURLFetcher::TestURLFetcher(int id, 14 const GURL& url, 15 URLFetcher::RequestType request_type, 16 URLFetcher::Delegate* d) 17 : URLFetcher(url, request_type, d), 18 id_(id), 19 original_url_(url), 20 did_receive_last_chunk_(false) { 21} 22 23TestURLFetcher::~TestURLFetcher() { 24} 25 26void TestURLFetcher::AppendChunkToUpload(const std::string& data, 27 bool is_last_chunk) { 28 DCHECK(!did_receive_last_chunk_); 29 did_receive_last_chunk_ = is_last_chunk; 30 chunks_.push_back(data); 31} 32 33TestURLFetcherFactory::TestURLFetcherFactory() {} 34 35TestURLFetcherFactory::~TestURLFetcherFactory() {} 36 37URLFetcher* TestURLFetcherFactory::CreateURLFetcher( 38 int id, 39 const GURL& url, 40 URLFetcher::RequestType request_type, 41 URLFetcher::Delegate* d) { 42 TestURLFetcher* fetcher = new TestURLFetcher(id, url, request_type, d); 43 fetchers_[id] = fetcher; 44 return fetcher; 45} 46 47TestURLFetcher* TestURLFetcherFactory::GetFetcherByID(int id) const { 48 Fetchers::const_iterator i = fetchers_.find(id); 49 return i == fetchers_.end() ? NULL : i->second; 50} 51 52void TestURLFetcherFactory::RemoveFetcherFromMap(int id) { 53 Fetchers::iterator i = fetchers_.find(id); 54 DCHECK(i != fetchers_.end()); 55 fetchers_.erase(i); 56} 57 58// This class is used by the FakeURLFetcherFactory below. 59class FakeURLFetcher : public URLFetcher { 60 public: 61 // Normal URL fetcher constructor but also takes in a pre-baked response. 62 FakeURLFetcher(const GURL& url, RequestType request_type, Delegate* d, 63 const std::string& response_data, bool success) 64 : URLFetcher(url, request_type, d), 65 url_(url), 66 response_data_(response_data), 67 success_(success), 68 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 69 } 70 71 // Start the request. This will call the given delegate asynchronously 72 // with the pre-baked response as parameter. 73 virtual void Start() { 74 MessageLoop::current()->PostTask( 75 FROM_HERE, 76 method_factory_.NewRunnableMethod(&FakeURLFetcher::RunDelegate)); 77 } 78 79 private: 80 virtual ~FakeURLFetcher() { 81 } 82 83 // This is the method which actually calls the delegate that is passed in the 84 // constructor. 85 void RunDelegate() { 86 net::URLRequestStatus status; 87 status.set_status(success_ ? net::URLRequestStatus::SUCCESS : 88 net::URLRequestStatus::FAILED); 89 delegate()->OnURLFetchComplete(this, url_, status, success_ ? 200 : 500, 90 ResponseCookies(), response_data_); 91 } 92 93 // Pre-baked response data and flag which indicates whether the request should 94 // be successful or not. 95 GURL url_; 96 std::string response_data_; 97 bool success_; 98 99 // Method factory used to run the delegate. 100 ScopedRunnableMethodFactory<FakeURLFetcher> method_factory_; 101 102 DISALLOW_COPY_AND_ASSIGN(FakeURLFetcher); 103}; 104 105FakeURLFetcherFactory::FakeURLFetcherFactory() {} 106 107FakeURLFetcherFactory::~FakeURLFetcherFactory() {} 108 109URLFetcher* FakeURLFetcherFactory::CreateURLFetcher( 110 int id, 111 const GURL& url, 112 URLFetcher::RequestType request_type, 113 URLFetcher::Delegate* d) { 114 FakeResponseMap::const_iterator it = fake_responses_.find(url); 115 if (it == fake_responses_.end()) { 116 // If we don't have a baked response for that URL we return NULL. 117 DLOG(ERROR) << "No baked response for URL: " << url.spec(); 118 return NULL; 119 } 120 return new FakeURLFetcher(url, request_type, d, 121 it->second.first, it->second.second); 122} 123 124void FakeURLFetcherFactory::SetFakeResponse(const std::string& url, 125 const std::string& response_data, 126 bool success) { 127 // Overwrite existing URL if it already exists. 128 fake_responses_[GURL(url)] = std::make_pair(response_data, success); 129} 130 131void FakeURLFetcherFactory::ClearFakeReponses() { 132 fake_responses_.clear(); 133} 134