Home | History | Annotate | Download | only in drive
      1 // Copyright (c) 2012 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 "google_apis/drive/base_requests.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/run_loop.h"
     11 #include "base/values.h"
     12 #include "google_apis/drive/dummy_auth_service.h"
     13 #include "google_apis/drive/request_sender.h"
     14 #include "google_apis/drive/test_util.h"
     15 #include "net/test/embedded_test_server/embedded_test_server.h"
     16 #include "net/test/embedded_test_server/http_request.h"
     17 #include "net/test/embedded_test_server/http_response.h"
     18 #include "net/url_request/url_request_test_util.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace google_apis {
     22 
     23 namespace {
     24 
     25 const char kValidJsonString[] = "{ \"test\": 123 }";
     26 const char kInvalidJsonString[] = "$$$";
     27 
     28 class FakeUrlFetchRequest : public UrlFetchRequestBase {
     29  public:
     30   explicit FakeUrlFetchRequest(RequestSender* sender,
     31                                const EntryActionCallback& callback,
     32                                const GURL& url)
     33       : UrlFetchRequestBase(sender),
     34         callback_(callback),
     35         url_(url) {
     36   }
     37 
     38   virtual ~FakeUrlFetchRequest() {
     39   }
     40 
     41  protected:
     42   virtual GURL GetURL() const OVERRIDE { return url_; }
     43   virtual void ProcessURLFetchResults(const net::URLFetcher* source) OVERRIDE {
     44     callback_.Run(GetErrorCode());
     45   }
     46   virtual void RunCallbackOnPrematureFailure(GDataErrorCode code) OVERRIDE {
     47     callback_.Run(code);
     48   }
     49 
     50   EntryActionCallback callback_;
     51   GURL url_;
     52 };
     53 
     54 class FakeGetDataRequest : public GetDataRequest {
     55  public:
     56   explicit FakeGetDataRequest(RequestSender* sender,
     57                               const GetDataCallback& callback,
     58                               const GURL& url)
     59       : GetDataRequest(sender, callback),
     60         url_(url) {
     61   }
     62 
     63   virtual ~FakeGetDataRequest() {
     64   }
     65 
     66  protected:
     67   virtual GURL GetURL() const OVERRIDE { return url_; }
     68 
     69   GURL url_;
     70 };
     71 
     72 }  // namespace
     73 
     74 class BaseRequestsTest : public testing::Test {
     75  public:
     76   BaseRequestsTest() : response_code_(net::HTTP_OK) {}
     77 
     78   virtual void SetUp() OVERRIDE {
     79     request_context_getter_ = new net::TestURLRequestContextGetter(
     80         message_loop_.message_loop_proxy());
     81 
     82     sender_.reset(new RequestSender(new DummyAuthService,
     83                                     request_context_getter_.get(),
     84                                     message_loop_.message_loop_proxy(),
     85                                     std::string() /* custom user agent */));
     86 
     87     ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
     88     test_server_.RegisterRequestHandler(
     89         base::Bind(&BaseRequestsTest::HandleRequest, base::Unretained(this)));
     90   }
     91 
     92   scoped_ptr<net::test_server::HttpResponse> HandleRequest(
     93       const net::test_server::HttpRequest& request) {
     94     scoped_ptr<net::test_server::BasicHttpResponse> response(
     95         new net::test_server::BasicHttpResponse);
     96     response->set_code(response_code_);
     97     response->set_content(response_body_);
     98     response->set_content_type("application/json");
     99     return response.PassAs<net::test_server::HttpResponse>();
    100   }
    101 
    102   base::MessageLoopForIO message_loop_;
    103   scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
    104   scoped_ptr<RequestSender> sender_;
    105   net::test_server::EmbeddedTestServer test_server_;
    106 
    107   net::HttpStatusCode response_code_;
    108   std::string response_body_;
    109 };
    110 
    111 TEST_F(BaseRequestsTest, ParseValidJson) {
    112   scoped_ptr<base::Value> json;
    113   ParseJson(message_loop_.message_loop_proxy(),
    114             kValidJsonString,
    115             base::Bind(test_util::CreateCopyResultCallback(&json)));
    116   base::RunLoop().RunUntilIdle();
    117 
    118   base::DictionaryValue* root_dict = NULL;
    119   ASSERT_TRUE(json);
    120   ASSERT_TRUE(json->GetAsDictionary(&root_dict));
    121 
    122   int int_value = 0;
    123   ASSERT_TRUE(root_dict->GetInteger("test", &int_value));
    124   EXPECT_EQ(123, int_value);
    125 }
    126 
    127 TEST_F(BaseRequestsTest, ParseInvalidJson) {
    128   // Initialize with a valid pointer to verify that null is indeed assigned.
    129   scoped_ptr<base::Value> json(base::Value::CreateNullValue());
    130   ParseJson(message_loop_.message_loop_proxy(),
    131             kInvalidJsonString,
    132             base::Bind(test_util::CreateCopyResultCallback(&json)));
    133   base::RunLoop().RunUntilIdle();
    134 
    135   EXPECT_FALSE(json);
    136 }
    137 
    138 TEST_F(BaseRequestsTest, UrlFetchRequestBaseResponseCodeOverride) {
    139   response_code_ = net::HTTP_FORBIDDEN;
    140   response_body_ =
    141       "{\"error\": {\n"
    142       "  \"errors\": [\n"
    143       "   {\n"
    144       "    \"domain\": \"usageLimits\",\n"
    145       "    \"reason\": \"rateLimitExceeded\",\n"
    146       "    \"message\": \"Rate Limit Exceeded\"\n"
    147       "   }\n"
    148       "  ],\n"
    149       "  \"code\": 403,\n"
    150       "  \"message\": \"Rate Limit Exceeded\"\n"
    151       " }\n"
    152       "}\n";
    153 
    154   GDataErrorCode error = GDATA_OTHER_ERROR;
    155   base::RunLoop run_loop;
    156   sender_->StartRequestWithRetry(
    157       new FakeUrlFetchRequest(
    158           sender_.get(),
    159           test_util::CreateQuitCallback(
    160               &run_loop, test_util::CreateCopyResultCallback(&error)),
    161           test_server_.base_url()));
    162   run_loop.Run();
    163 
    164   // HTTP_FORBIDDEN (403) is overridden by the error reason.
    165   EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE, error);
    166 }
    167 
    168 TEST_F(BaseRequestsTest, GetDataRequestParseValidResponse) {
    169   response_body_ = kValidJsonString;
    170 
    171   GDataErrorCode error = GDATA_OTHER_ERROR;
    172   scoped_ptr<base::Value> value;
    173   base::RunLoop run_loop;
    174   sender_->StartRequestWithRetry(
    175       new FakeGetDataRequest(
    176           sender_.get(),
    177           test_util::CreateQuitCallback(
    178               &run_loop, test_util::CreateCopyResultCallback(&error, &value)),
    179           test_server_.base_url()));
    180   run_loop.Run();
    181 
    182   EXPECT_EQ(HTTP_SUCCESS, error);
    183   EXPECT_TRUE(value);
    184 }
    185 
    186 TEST_F(BaseRequestsTest, GetDataRequestParseInvalidResponse) {
    187   response_body_ = kInvalidJsonString;
    188 
    189   GDataErrorCode error = GDATA_OTHER_ERROR;
    190   scoped_ptr<base::Value> value;
    191   base::RunLoop run_loop;
    192   sender_->StartRequestWithRetry(
    193       new FakeGetDataRequest(
    194           sender_.get(),
    195           test_util::CreateQuitCallback(
    196               &run_loop, test_util::CreateCopyResultCallback(&error, &value)),
    197           test_server_.base_url()));
    198   run_loop.Run();
    199 
    200   EXPECT_EQ(GDATA_PARSE_ERROR, error);
    201   EXPECT_FALSE(value);
    202 }
    203 
    204 }  // namespace google_apis
    205