• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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