Home | History | Annotate | Download | only in net
      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.
     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.
     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