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 45 class 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. Start()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. id()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. original_url()66 const GURL& original_url() const { return original_url_; } 67 68 // Returns the data uploaded on this URLFetcher. upload_data()69 const std::string& upload_data() const { return URLFetcher::upload_data(); } 70 71 // Returns the chunks of data uploaded on this URLFetcher. upload_chunks()72 const std::list<std::string>& upload_chunks() const { return chunks_; } 73 74 // Returns the delegate installed on the URLFetcher. delegate()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. 88 class 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 141 class 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