1// Copyright (c) 2010 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#ifndef CHROME_COMMON_NET_TEST_URL_FETCHER_FACTORY_H_ 6#define CHROME_COMMON_NET_TEST_URL_FETCHER_FACTORY_H_ 7#pragma once 8 9#include <list> 10#include <map> 11#include <string> 12#include <utility> 13 14#include "chrome/common/net/url_fetcher.h" 15#include "googleurl/src/gurl.h" 16 17// TestURLFetcher and TestURLFetcherFactory are used for testing consumers of 18// URLFetcher. TestURLFetcherFactory is a URLFetcher::Factory that creates 19// TestURLFetchers. TestURLFetcher::Start is overriden to do nothing. It is 20// expected that you'll grab the delegate from the TestURLFetcher and invoke 21// the callback method when appropriate. In this way it's easy to mock a 22// URLFetcher. 23// Typical usage: 24// // TestURLFetcher requires a MessageLoop: 25// MessageLoopForUI message_loop; 26// // And io_thread to release URLRequestContextGetter in URLFetcher::Core. 27// BrowserThread io_thread(BrowserThread::IO, &message_loop); 28// // Create and register factory. 29// TestURLFetcherFactory factory; 30// URLFetcher::set_factory(&factory); 31// // Do something that triggers creation of a URLFetcher. 32// TestURLFetcher* fetcher = factory.GetFetcherByID(expected_id); 33// DCHECK(fetcher); 34// // Notify delegate with whatever data you want. 35// fetcher->delegate()->OnURLFetchComplete(...); 36// // Make sure consumer of URLFetcher does the right thing. 37// ... 38// // Reset factory. 39// URLFetcher::set_factory(NULL); 40// 41// Note: if you don't know when your request objects will be created you 42// might want to use the FakeUrlFetcher and FakeUrlFetcherFactory classes 43// below. 44 45class TestURLFetcher : public URLFetcher { 46 public: 47 TestURLFetcher(int id, 48 const GURL& url, 49 RequestType request_type, 50 Delegate* d); 51 ~TestURLFetcher(); 52 53 // Overriden to do nothing. It is assumed the caller will notify the delegate. 54 virtual void Start() {} 55 56 // Overriden to cache the chunks uploaded. Caller can read back the uploaded 57 // chunks with the upload_data() accessor. 58 virtual void AppendChunkToUpload(const std::string& data, bool is_last_chunk); 59 60 // Unique ID in our factory. 61 int id() const { return id_; } 62 63 // URL we were created with. Because of how we're using URLFetcher url() 64 // always returns an empty URL. Chances are you'll want to use original_url() 65 // in your tests. 66 const GURL& original_url() const { return original_url_; } 67 68 // Returns the data uploaded on this URLFetcher. 69 const std::string& upload_data() const { return URLFetcher::upload_data(); } 70 71 // Returns the chunks of data uploaded on this URLFetcher. 72 const std::list<std::string>& upload_chunks() const { return chunks_; } 73 74 // Returns the delegate installed on the URLFetcher. 75 Delegate* delegate() const { return URLFetcher::delegate(); } 76 77 private: 78 const int id_; 79 const GURL original_url_; 80 std::list<std::string> chunks_; 81 bool did_receive_last_chunk_; 82 83 DISALLOW_COPY_AND_ASSIGN(TestURLFetcher); 84}; 85 86// Simple URLFetcher::Factory method that creates TestURLFetchers. All fetchers 87// are registered in a map by the id passed to the create method. 88class TestURLFetcherFactory : public URLFetcher::Factory { 89 public: 90 TestURLFetcherFactory(); 91 virtual ~TestURLFetcherFactory(); 92 93 virtual URLFetcher* CreateURLFetcher(int id, 94 const GURL& url, 95 URLFetcher::RequestType request_type, 96 URLFetcher::Delegate* d); 97 TestURLFetcher* GetFetcherByID(int id) const; 98 void RemoveFetcherFromMap(int id); 99 100 private: 101 // Maps from id passed to create to the returned URLFetcher. 102 typedef std::map<int, TestURLFetcher*> Fetchers; 103 Fetchers fetchers_; 104 105 DISALLOW_COPY_AND_ASSIGN(TestURLFetcherFactory); 106}; 107 108// The FakeUrlFetcher and FakeUrlFetcherFactory classes are similar to the 109// ones above but don't require you to know when exactly the URLFetcher objects 110// will be created. 111// 112// These classes let you set pre-baked HTTP responses for particular URLs. 113// E.g., if the user requests http://a.com/ then respond with an HTTP/500. 114// 115// We assume that the thread that is calling Start() on the URLFetcher object 116// has a message loop running. 117// 118// This class is not thread-safe. You should not call SetFakeResponse or 119// ClearFakeResponse at the same time you call CreateURLFetcher. However, it is 120// OK to start URLFetcher objects while setting or clearning fake responses 121// since already created URLFetcher objects will not be affected by any changes 122// made to the fake responses (once a URLFetcher object is created you cannot 123// change its fake response). 124// 125// Example usage: 126// FakeURLFetcherFactory factory; 127// URLFetcher::set_factory(&factory); 128// 129// // You know that class SomeService will request url http://a.com/ and you 130// // want to test the service class by returning an error. 131// factory.SetFakeResponse("http://a.com/", "", false); 132// // But if the service requests http://b.com/asdf you want to respond with 133// // a simple html page and an HTTP/200 code. 134// factory.SetFakeResponse("http://b.com/asdf", 135// "<html><body>hello world</body></html>", 136// true); 137// 138// SomeService service; 139// service.Run(); // Will eventually request these two URLs. 140 141class FakeURLFetcherFactory : public URLFetcher::Factory { 142 public: 143 FakeURLFetcherFactory(); 144 virtual ~FakeURLFetcherFactory(); 145 146 // If no fake response is set for the given URL this method will return NULL. 147 // Otherwise, it will return a URLFetcher object which will respond with the 148 // pre-baked response that the client has set by calling SetFakeResponse(). 149 virtual URLFetcher* CreateURLFetcher(int id, 150 const GURL& url, 151 URLFetcher::RequestType request_type, 152 URLFetcher::Delegate* d); 153 154 // Sets the fake response for a given URL. If success is true we will serve 155 // an HTTP/200 and an HTTP/500 otherwise. The |response_data| may be empty. 156 void SetFakeResponse(const std::string& url, 157 const std::string& response_data, 158 bool success); 159 160 // Clear all the fake responses that were previously set via 161 // SetFakeResponse(). 162 void ClearFakeReponses(); 163 164 private: 165 typedef std::map<GURL, std::pair<std::string, bool> > FakeResponseMap; 166 FakeResponseMap fake_responses_; 167 168 DISALLOW_COPY_AND_ASSIGN(FakeURLFetcherFactory); 169}; 170 171#endif // CHROME_COMMON_NET_TEST_URL_FETCHER_FACTORY_H_ 172