1// Copyright 2013 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 "components/autofill/content/browser/wallet/wallet_signin_helper.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/message_loop/message_loop.h"
10#include "base/run_loop.h"
11#include "base/strings/stringprintf.h"
12#include "components/autofill/content/browser/wallet/wallet_service_url.h"
13#include "components/autofill/content/browser/wallet/wallet_signin_helper_delegate.h"
14#include "content/public/browser/cookie_store_factory.h"
15#include "content/public/test/test_browser_thread_bundle.h"
16#include "google_apis/gaia/gaia_constants.h"
17#include "google_apis/gaia/gaia_urls.h"
18#include "google_apis/gaia/google_service_auth_error.h"
19#include "net/cookies/canonical_cookie.h"
20#include "net/cookies/cookie_monster.h"
21#include "net/cookies/cookie_options.h"
22#include "net/http/http_status_code.h"
23#include "net/url_request/test_url_fetcher_factory.h"
24#include "net/url_request/url_request.h"
25#include "net/url_request/url_request_context.h"
26#include "net/url_request/url_request_context_getter.h"
27#include "net/url_request/url_request_status.h"
28#include "net/url_request/url_request_test_util.h"
29#include "testing/gmock/include/gmock/gmock.h"
30#include "testing/gtest/include/gtest/gtest.h"
31
32using testing::_;
33
34namespace autofill {
35namespace wallet {
36
37namespace {
38
39class MockWalletSigninHelperDelegate : public WalletSigninHelperDelegate {
40 public:
41  MOCK_METHOD0(OnPassiveSigninSuccess, void());
42  MOCK_METHOD1(OnPassiveSigninFailure,
43               void(const GoogleServiceAuthError& error));
44  MOCK_METHOD1(OnDidFetchWalletCookieValue,
45               void(const std::string& cookie_value));
46};
47
48}  // namespace
49
50class WalletSigninHelperTest : public testing::Test {
51 protected:
52  WalletSigninHelperTest()
53      : request_context_(new net::TestURLRequestContextGetter(
54            base::MessageLoopProxy::current())) {}
55  virtual ~WalletSigninHelperTest() {}
56
57  virtual void SetUp() OVERRIDE {
58    signin_helper_.reset(
59        new WalletSigninHelper(&mock_delegate_, request_context_.get()));
60  }
61
62  virtual void TearDown() OVERRIDE {
63    signin_helper_.reset();
64  }
65
66  // Sets up a response for the mock URLFetcher and completes the request.
67  void SetUpFetcherResponseAndCompleteRequest(
68      const std::string& url,
69      int response_code,
70      const net::ResponseCookies& cookies,
71      const std::string& response_string) {
72    net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
73    ASSERT_TRUE(fetcher);
74    ASSERT_TRUE(fetcher->delegate());
75
76    fetcher->set_url(GURL(url));
77    fetcher->set_status(net::URLRequestStatus());
78    fetcher->set_response_code(response_code);
79    fetcher->SetResponseString(response_string);
80    fetcher->set_cookies(cookies);
81    fetcher->delegate()->OnURLFetchComplete(fetcher);
82  }
83
84  void MockSuccessfulPassiveSignInResponse() {
85    SetUpFetcherResponseAndCompleteRequest(wallet::GetPassiveAuthUrl(0).spec(),
86                                           net::HTTP_OK,
87                                           net::ResponseCookies(),
88                                           "YES");
89  }
90
91  void MockFailedPassiveSignInResponseNo() {
92    SetUpFetcherResponseAndCompleteRequest(wallet::GetPassiveAuthUrl(0).spec(),
93                                           net::HTTP_OK,
94                                           net::ResponseCookies(),
95                                           "NOOOOOOOOOOOOOOO");
96  }
97
98  void MockFailedPassiveSignInResponse404() {
99    SetUpFetcherResponseAndCompleteRequest(wallet::GetPassiveAuthUrl(0).spec(),
100                                           net::HTTP_NOT_FOUND,
101                                           net::ResponseCookies(),
102                                           std::string());
103  }
104
105  content::TestBrowserThreadBundle thread_bundle_;
106  scoped_ptr<WalletSigninHelper> signin_helper_;
107  MockWalletSigninHelperDelegate mock_delegate_;
108  scoped_refptr<net::TestURLRequestContextGetter> request_context_;
109
110 private:
111  net::TestURLFetcherFactory factory_;
112};
113
114TEST_F(WalletSigninHelperTest, PassiveSigninSuccessful) {
115  EXPECT_CALL(mock_delegate_, OnPassiveSigninSuccess());
116  signin_helper_->StartPassiveSignin(0);
117  MockSuccessfulPassiveSignInResponse();
118}
119
120TEST_F(WalletSigninHelperTest, PassiveSigninFailedSignin404) {
121  EXPECT_CALL(mock_delegate_, OnPassiveSigninFailure(_));
122  signin_helper_->StartPassiveSignin(0);
123  MockFailedPassiveSignInResponse404();
124}
125
126TEST_F(WalletSigninHelperTest, PassiveSigninFailedSigninNo) {
127  EXPECT_CALL(mock_delegate_, OnPassiveSigninFailure(_));
128  signin_helper_->StartPassiveSignin(0);
129  MockFailedPassiveSignInResponseNo();
130}
131
132TEST_F(WalletSigninHelperTest, GetWalletCookieValueWhenPresent) {
133  EXPECT_CALL(mock_delegate_, OnDidFetchWalletCookieValue("gdToken"));
134  net::CookieMonster* cookie_monster =
135      content::CreateCookieStore(content::CookieStoreConfig())->
136          GetCookieMonster();
137  net::CookieOptions httponly_options;
138  httponly_options.set_include_httponly();
139  scoped_ptr<net::CanonicalCookie> cookie(
140      net::CanonicalCookie::Create(GetPassiveAuthUrl(0).GetWithEmptyPath(),
141                                   "gdToken=gdToken; HttpOnly",
142                                   base::Time::Now(),
143                                   httponly_options));
144
145  net::CookieList cookie_list;
146  cookie_list.push_back(*cookie);
147  cookie_monster->ImportCookies(cookie_list);
148  request_context_->GetURLRequestContext()
149      ->set_cookie_store(cookie_monster);
150  signin_helper_->StartWalletCookieValueFetch();
151  base::RunLoop().RunUntilIdle();
152}
153
154TEST_F(WalletSigninHelperTest, GetWalletCookieValueWhenMissing) {
155  EXPECT_CALL(mock_delegate_, OnDidFetchWalletCookieValue(std::string()));
156  net::CookieMonster* cookie_monster =
157      content::CreateCookieStore(content::CookieStoreConfig())->
158          GetCookieMonster();
159  net::CookieOptions httponly_options;
160  httponly_options.set_include_httponly();
161  scoped_ptr<net::CanonicalCookie> cookie(
162      net::CanonicalCookie::Create(GetPassiveAuthUrl(0).GetWithEmptyPath(),
163                                   "fake_cookie=monkeys; HttpOnly",
164                                   base::Time::Now(),
165                                   httponly_options));
166
167  net::CookieList cookie_list;
168  cookie_list.push_back(*cookie);
169  cookie_monster->ImportCookies(cookie_list);
170  request_context_->GetURLRequestContext()
171      ->set_cookie_store(cookie_monster);
172  signin_helper_->StartWalletCookieValueFetch();
173  base::RunLoop().RunUntilIdle();
174}
175
176// TODO(aruslan): http://crbug.com/188317 Need more tests.
177
178}  // namespace wallet
179}  // namespace autofill
180