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
21namespace google_apis {
22
23namespace {
24
25const char kValidJsonString[] = "{ \"test\": 123 }";
26const char kInvalidJsonString[] = "$$$";
27
28class FakeUrlFetchRequest : public UrlFetchRequestBase {
29 public:
30  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}  // namespace
55
56class BaseRequestsTest : public testing::Test {
57 public:
58  BaseRequestsTest() : response_code_(net::HTTP_OK) {}
59
60  virtual void SetUp() OVERRIDE {
61    request_context_getter_ = new net::TestURLRequestContextGetter(
62        message_loop_.message_loop_proxy());
63
64    sender_.reset(new RequestSender(new DummyAuthService,
65                                    request_context_getter_.get(),
66                                    message_loop_.message_loop_proxy(),
67                                    std::string() /* custom user agent */));
68
69    ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
70    test_server_.RegisterRequestHandler(
71        base::Bind(&BaseRequestsTest::HandleRequest, base::Unretained(this)));
72  }
73
74  scoped_ptr<net::test_server::HttpResponse> HandleRequest(
75      const net::test_server::HttpRequest& request) {
76    scoped_ptr<net::test_server::BasicHttpResponse> response(
77        new net::test_server::BasicHttpResponse);
78    response->set_code(response_code_);
79    response->set_content(response_body_);
80    response->set_content_type("application/json");
81    return response.PassAs<net::test_server::HttpResponse>();
82  }
83
84  base::MessageLoopForIO message_loop_;
85  scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
86  scoped_ptr<RequestSender> sender_;
87  net::test_server::EmbeddedTestServer test_server_;
88
89  net::HttpStatusCode response_code_;
90  std::string response_body_;
91};
92
93TEST_F(BaseRequestsTest, ParseValidJson) {
94  scoped_ptr<base::Value> json(ParseJson(kValidJsonString));
95
96  base::DictionaryValue* root_dict = NULL;
97  ASSERT_TRUE(json);
98  ASSERT_TRUE(json->GetAsDictionary(&root_dict));
99
100  int int_value = 0;
101  ASSERT_TRUE(root_dict->GetInteger("test", &int_value));
102  EXPECT_EQ(123, int_value);
103}
104
105TEST_F(BaseRequestsTest, ParseInvalidJson) {
106  EXPECT_FALSE(ParseJson(kInvalidJsonString));
107}
108
109TEST_F(BaseRequestsTest, UrlFetchRequestBaseResponseCodeOverride) {
110  response_code_ = net::HTTP_FORBIDDEN;
111  response_body_ =
112      "{\"error\": {\n"
113      "  \"errors\": [\n"
114      "   {\n"
115      "    \"domain\": \"usageLimits\",\n"
116      "    \"reason\": \"rateLimitExceeded\",\n"
117      "    \"message\": \"Rate Limit Exceeded\"\n"
118      "   }\n"
119      "  ],\n"
120      "  \"code\": 403,\n"
121      "  \"message\": \"Rate Limit Exceeded\"\n"
122      " }\n"
123      "}\n";
124
125  GDataErrorCode error = GDATA_OTHER_ERROR;
126  base::RunLoop run_loop;
127  sender_->StartRequestWithRetry(
128      new FakeUrlFetchRequest(
129          sender_.get(),
130          test_util::CreateQuitCallback(
131              &run_loop, test_util::CreateCopyResultCallback(&error)),
132          test_server_.base_url()));
133  run_loop.Run();
134
135  // HTTP_FORBIDDEN (403) is overridden by the error reason.
136  EXPECT_EQ(HTTP_SERVICE_UNAVAILABLE, error);
137}
138
139}  // namespace google_apis
140