privetv3_setup_flow_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1// Copyright 2014 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 "chrome/browser/local_discovery/privetv3_setup_flow.h"
6
7#include "base/json/json_reader.h"
8#include "base/run_loop.h"
9#include "chrome/browser/local_discovery/gcd_api_flow.h"
10#include "net/http/http_response_headers.h"
11#include "net/url_request/test_url_fetcher_factory.h"
12#include "net/url_request/url_request_test_util.h"
13#include "testing/gmock/include/gmock/gmock.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16namespace local_discovery {
17
18namespace {
19
20using testing::HasSubstr;
21using testing::Invoke;
22using testing::Return;
23using testing::SaveArg;
24using testing::StrictMock;
25using testing::WithArgs;
26using testing::_;
27
28const char kServiceName[] = "test_service";
29
30const char kRegistrationTicketResponse[] =
31    "{"
32    "\"kind\": \"clouddevices#registrationTicket\","
33    "\"id\": \"test_ticket\","
34    "\"deviceId\": \"test_id\""
35    "}";
36
37class MockPrivetHTTPClient : public PrivetHTTPClient {
38 public:
39  MockPrivetHTTPClient() {
40    request_context_ =
41        new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
42  }
43
44  MOCK_METHOD0(GetName, const std::string&());
45  MOCK_METHOD1(
46      CreateInfoOperationPtr,
47      PrivetJSONOperation*(const PrivetJSONOperation::ResultCallback&));
48
49  virtual void RefreshPrivetToken(
50      const PrivetURLFetcher::TokenCallback& callback) OVERRIDE {
51    callback.Run("x-privet-token");
52  }
53
54  virtual scoped_ptr<PrivetJSONOperation> CreateInfoOperation(
55      const PrivetJSONOperation::ResultCallback& callback) OVERRIDE {
56    return make_scoped_ptr(CreateInfoOperationPtr(callback));
57  }
58
59  virtual scoped_ptr<PrivetURLFetcher> CreateURLFetcher(
60      const GURL& url,
61      net::URLFetcher::RequestType request_type,
62      PrivetURLFetcher::Delegate* delegate) OVERRIDE {
63    return make_scoped_ptr(
64        new PrivetURLFetcher(url, request_type, request_context_, delegate));
65  }
66
67  scoped_refptr<net::TestURLRequestContextGetter> request_context_;
68};
69
70class MockDelegate : public PrivetV3SetupFlow::Delegate {
71 public:
72  MockDelegate() : privet_client_ptr_(NULL) {}
73
74  class MockGCDApiFlow : public GCDApiFlow {
75   public:
76    explicit MockGCDApiFlow(MockDelegate* delegate) : delegate_(delegate) {}
77
78    virtual void Start(scoped_ptr<Request> request) OVERRIDE {
79      ASSERT_FALSE(delegate_->gcd_request_);
80      delegate_->gcd_request_ = request.Pass();
81      delegate_->ReplyWithToken();
82    }
83
84   private:
85    MockDelegate* delegate_;
86  };
87
88  MOCK_METHOD1(GetWiFiCredentials, void(const CredentialsCallback&));
89  MOCK_METHOD1(SwitchToSetupWiFi, void(const ResultCallback&));
90  virtual void CreatePrivetV3Client(
91      const std::string& service_name,
92      const PrivetClientCallback& callback) OVERRIDE {
93    scoped_ptr<MockPrivetHTTPClient> privet_client(new MockPrivetHTTPClient());
94    privet_client_ptr_ = privet_client.get();
95    callback.Run(privet_client.PassAs<PrivetHTTPClient>());
96  }
97  MOCK_METHOD2(ConfirmSecurityCode,
98               void(const std::string&, const ResultCallback&));
99  MOCK_METHOD1(RestoreWifi, void(const ResultCallback&));
100  MOCK_METHOD0(OnSetupDone, void());
101  MOCK_METHOD0(OnSetupError, void());
102
103  virtual scoped_ptr<GCDApiFlow> CreateApiFlow() OVERRIDE {
104    scoped_ptr<MockGCDApiFlow> mock_gcd(new MockGCDApiFlow(this));
105    return mock_gcd.PassAs<GCDApiFlow>();
106  }
107
108  void ReplyWithToken() {
109    scoped_ptr<base::Value> value(base::JSONReader::Read(gcd_server_response_));
110    const base::DictionaryValue* dictionary = NULL;
111    value->GetAsDictionary(&dictionary);
112    gcd_request_->OnGCDAPIFlowComplete(*dictionary);
113  }
114
115  std::string gcd_server_response_;
116  scoped_ptr<GCDApiFlow::Request> gcd_request_;
117  MockPrivetHTTPClient* privet_client_ptr_;
118  base::Closure quit_closure_;
119};
120
121class PrivetV3SetupFlowTest : public testing::Test {
122 public:
123  PrivetV3SetupFlowTest() : setup_(&delegate_) {}
124
125  virtual ~PrivetV3SetupFlowTest() {}
126
127  void ConfirmCode(const MockDelegate::ResultCallback& confirm_callback) {
128    base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
129    confirm_callback.Run(true);
130  }
131
132 protected:
133  virtual void SetUp() OVERRIDE {
134    quit_closure_ = run_loop_.QuitClosure();
135    EXPECT_CALL(delegate_, GetWiFiCredentials(_)).Times(0);
136    EXPECT_CALL(delegate_, SwitchToSetupWiFi(_)).Times(0);
137    EXPECT_CALL(delegate_, ConfirmSecurityCode(_, _)).Times(0);
138    EXPECT_CALL(delegate_, RestoreWifi(_)).Times(0);
139    EXPECT_CALL(delegate_, OnSetupDone()).Times(0);
140    EXPECT_CALL(delegate_, OnSetupError()).Times(0);
141  }
142
143  void SimulateFetch(int response_code, const std::string& response) {
144    net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
145    ASSERT_TRUE(fetcher);
146    EXPECT_THAT(fetcher->GetOriginalURL().spec(),
147                testing::HasSubstr("/privet/v3/setup/start"));
148    fetcher->set_response_code(response_code);
149    scoped_refptr<net::HttpResponseHeaders> response_headers(
150        new net::HttpResponseHeaders(""));
151    response_headers->AddHeader("Content-Type: application/json");
152    fetcher->set_response_headers(response_headers);
153    fetcher->SetResponseString(response);
154    fetcher->delegate()->OnURLFetchComplete(fetcher);
155  }
156
157  net::TestURLFetcherFactory url_fetcher_factory_;
158  StrictMock<MockDelegate> delegate_;
159  PrivetV3SetupFlow setup_;
160  base::MessageLoop loop_;
161  base::RunLoop run_loop_;
162  base::Closure quit_closure_;
163};
164
165TEST_F(PrivetV3SetupFlowTest, InvalidTicket) {
166  EXPECT_CALL(delegate_, OnSetupError()).Times(1);
167  delegate_.gcd_server_response_ = "{}";
168  setup_.Register(kServiceName);
169}
170
171TEST_F(PrivetV3SetupFlowTest, InvalidDeviceResponce) {
172  EXPECT_CALL(delegate_, OnSetupError()).Times(1);
173  EXPECT_CALL(delegate_, ConfirmSecurityCode(_, _)).Times(1).WillOnce(
174      WithArgs<1>(Invoke(this, &PrivetV3SetupFlowTest::ConfirmCode)));
175  delegate_.gcd_server_response_ = kRegistrationTicketResponse;
176  setup_.Register(kServiceName);
177  run_loop_.Run();
178  SimulateFetch(0, "{}");
179}
180
181TEST_F(PrivetV3SetupFlowTest, Success) {
182  EXPECT_CALL(delegate_, OnSetupDone()).Times(1);
183  EXPECT_CALL(delegate_, ConfirmSecurityCode(_, _)).Times(1).WillOnce(
184      WithArgs<1>(Invoke(this, &PrivetV3SetupFlowTest::ConfirmCode)));
185  delegate_.gcd_server_response_ = kRegistrationTicketResponse;
186  setup_.Register(kServiceName);
187  run_loop_.Run();
188  SimulateFetch(200, "{}");
189}
190
191}  // namespace
192
193}  // namespace local_discovery
194