blob: 5f5d8cae5a1fb25fcbb48f227789a296f3bd5149 [file] [log] [blame]
Alex Vakulenko8e34d392014-04-29 11:02:56 -07001// Copyright 2014 The Chromium OS 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 <base/json/json_reader.h>
6#include <base/values.h>
7#include <gtest/gtest.h>
8
9#include "buffet/bind_lambda.h"
Alex Vakulenko1f30a622014-07-23 11:13:15 -070010#include "buffet/commands/command_manager.h"
Alex Vakulenko45109442014-07-29 11:07:10 -070011#include "buffet/commands/unittest_utils.h"
Alex Vakulenko8e34d392014-04-29 11:02:56 -070012#include "buffet/device_registration_info.h"
13#include "buffet/device_registration_storage_keys.h"
14#include "buffet/http_request.h"
15#include "buffet/http_transport_fake.h"
16#include "buffet/mime_utils.h"
Christopher Wiley006e94e2014-05-02 13:44:48 -070017#include "buffet/storage_impls.h"
Alex Vakulenko8e34d392014-04-29 11:02:56 -070018
Alex Vakulenkob3aac252014-05-07 17:35:24 -070019using namespace buffet; // NOLINT(build/namespaces)
Alex Vakulenkoaf23b322014-05-08 16:25:45 -070020using namespace buffet::http; // NOLINT(build/namespaces)
Alex Vakulenko8e34d392014-04-29 11:02:56 -070021
22namespace {
Alex Vakulenko8e34d392014-04-29 11:02:56 -070023
24namespace test_data {
25
26const char kServiceURL[] = "http://gcd.server.com/";
27const char kOAuthURL[] = "http://oauth.server.com/";
28const char kApiKey[] = "GOadRdTf9FERf0k4w6EFOof56fUJ3kFDdFL3d7f";
29const char kClientId[] = "123543821385-sfjkjshdkjhfk234sdfsdfkskd"
30 "fkjh7f.apps.googleusercontent.com";
31const char kClientSecret[] = "5sdGdGlfolGlrFKfdFlgP6FG";
32const char kDeviceId[] = "4a7ea2d1-b331-1e1f-b206-e863c7635196";
33const char kClaimTicketId[] = "RTcUE";
34const char kAccessToken[] = "ya29.1.AADtN_V-dLUM-sVZ0qVjG9Dxm5NgdS9J"
35 "Mx_JLUqhC9bED_YFjzHZtYt65ZzXCS35NMAeaVZ"
36 "Dei530-w0yE2urpQ";
37const char kRefreshToken[] = "1/zQmxR6PKNvhcxf9SjXUrCjcmCrcqRKXctc6cp"
38 "1nI-GQ";
39const char kRobotAccountAuthCode[] = "4/Mf_ujEhPejVhOq-OxW9F5cSOnWzx."
40 "YgciVjTYGscRshQV0ieZDAqiTIjMigI";
41const char kRobotAccountEmail[] = "6ed0b3f54f9bd619b942f4ad2441c252@"
42 "clouddevices.gserviceaccount.com";
43const char kUserAccountAuthCode[] = "2/sd_GD1TGFKpJOLJ34-0g5fK0fflp.GlT"
44 "I0F5g7hNtFgj5HFGOf8FlGK9eflO";
45const char kUserAccessToken[] = "sd56.4.FGDjG_F-gFGF-dFG6gGOG9Dxm5NgdS9"
46 "JMx_JLUqhC9bED_YFjLKjlkjLKJlkjLKjlKJea"
47 "VZDei530-w0yE2urpQ";
48const char kUserRefreshToken[] = "1/zQLKjlKJlkLkLKjLkjLKjLkjLjLkjl0ftc6"
49 "cp1nI-GQ";
50
51} // namespace test_data
52
53// Fill in the storage with default environment information (URLs, etc).
54void InitDefaultStorage(base::DictionaryValue* data) {
55 data->SetString(storage_keys::kClientId, test_data::kClientId);
56 data->SetString(storage_keys::kClientSecret, test_data::kClientSecret);
57 data->SetString(storage_keys::kApiKey, test_data::kApiKey);
58 data->SetString(storage_keys::kRefreshToken, "");
59 data->SetString(storage_keys::kDeviceId, "");
60 data->SetString(storage_keys::kOAuthURL, test_data::kOAuthURL);
61 data->SetString(storage_keys::kServiceURL, test_data::kServiceURL);
62 data->SetString(storage_keys::kRobotAccount, "");
63}
64
65// Add the test device registration information.
66void SetDefaultDeviceRegistration(base::DictionaryValue* data) {
67 data->SetString(storage_keys::kRefreshToken, test_data::kRefreshToken);
68 data->SetString(storage_keys::kDeviceId, test_data::kDeviceId);
69 data->SetString(storage_keys::kRobotAccount, test_data::kRobotAccountEmail);
70}
71
72void OAuth2Handler(const fake::ServerRequest& request,
73 fake::ServerResponse* response) {
74 base::DictionaryValue json;
75 if (request.GetFormField("grant_type") == "refresh_token") {
76 // Refresh device access token.
77 EXPECT_EQ(test_data::kRefreshToken, request.GetFormField("refresh_token"));
78 EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
79 EXPECT_EQ(test_data::kClientSecret, request.GetFormField("client_secret"));
80 json.SetString("access_token", test_data::kAccessToken);
81 } else if (request.GetFormField("grant_type") == "authorization_code") {
82 // Obtain access token.
83 std::string code = request.GetFormField("code");
84 if (code == test_data::kUserAccountAuthCode) {
85 // Get user access token.
86 EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
87 EXPECT_EQ(test_data::kClientSecret,
88 request.GetFormField("client_secret"));
89 EXPECT_EQ("urn:ietf:wg:oauth:2.0:oob",
90 request.GetFormField("redirect_uri"));
91 json.SetString("access_token", test_data::kUserAccessToken);
92 json.SetString("token_type", "Bearer");
93 json.SetString("refresh_token", test_data::kUserRefreshToken);
94 } else if (code == test_data::kRobotAccountAuthCode) {
95 // Get device access token.
96 EXPECT_EQ(test_data::kClientId, request.GetFormField("client_id"));
97 EXPECT_EQ(test_data::kClientSecret,
98 request.GetFormField("client_secret"));
99 EXPECT_EQ("oob", request.GetFormField("redirect_uri"));
100 EXPECT_EQ("https://www.googleapis.com/auth/clouddevices",
101 request.GetFormField("scope"));
102 json.SetString("access_token", test_data::kAccessToken);
103 json.SetString("token_type", "Bearer");
104 json.SetString("refresh_token", test_data::kRefreshToken);
105 } else {
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700106 FAIL() << "Unexpected authorization code";
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700107 }
108 } else {
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700109 FAIL() << "Unexpected grant type";
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700110 }
111 json.SetInteger("expires_in", 3600);
112 response->ReplyJson(status_code::Ok, &json);
113}
114
115void DeviceInfoHandler(const fake::ServerRequest& request,
116 fake::ServerResponse* response) {
117 std::string auth = "Bearer ";
118 auth += test_data::kAccessToken;
119 EXPECT_EQ(auth, request.GetHeader(http::request_header::kAuthorization));
120 response->ReplyJson(status_code::Ok, {
121 {"channel.supportedType", "xmpp"},
122 {"deviceKind", "vendor"},
123 {"id", test_data::kDeviceId},
124 {"kind", "clouddevices#device"},
125 });
126}
127
128void FinalizeTicketHandler(const fake::ServerRequest& request,
129 fake::ServerResponse* response) {
130 EXPECT_EQ(test_data::kApiKey, request.GetFormField("key"));
131 EXPECT_TRUE(request.GetData().empty());
132
133 response->ReplyJson(status_code::Ok, {
134 {"id", test_data::kClaimTicketId},
135 {"kind", "clouddevices#registrationTicket"},
136 {"oauthClientId", test_data::kClientId},
137 {"userEmail", "user@email.com"},
138 {"deviceDraft.id", test_data::kDeviceId},
139 {"deviceDraft.kind", "clouddevices#device"},
140 {"deviceDraft.channel.supportedType", "xmpp"},
141 {"robotAccountEmail", test_data::kRobotAccountEmail},
142 {"robotAccountAuthorizationCode", test_data::kRobotAccountAuthCode},
143 });
144}
145
146} // anonymous namespace
147
148// This is a helper class that allows the unit tests to set the private
149// member DeviceRegistrationInfo::ticket_id_, since TestHelper is declared
150// as a friend to DeviceRegistrationInfo.
151class DeviceRegistrationInfo::TestHelper {
152 public:
153 static void SetTestTicketId(DeviceRegistrationInfo* info) {
154 info->ticket_id_ = test_data::kClaimTicketId;
155 }
156};
157
158class DeviceRegistrationInfoTest : public ::testing::Test {
159 protected:
160 virtual void SetUp() override {
Alex Vakulenko45109442014-07-29 11:07:10 -0700161 InitDefaultStorage(&data_);
162 storage_ = std::make_shared<MemStorage>();
163 storage_->Save(&data_);
164 transport_ = std::make_shared<fake::Transport>();
165 command_manager_ = std::make_shared<CommandManager>();
166 dev_reg_ = std::unique_ptr<DeviceRegistrationInfo>(
167 new DeviceRegistrationInfo(command_manager_, transport_, storage_));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700168 }
169
Alex Vakulenko45109442014-07-29 11:07:10 -0700170 base::DictionaryValue data_;
171 std::shared_ptr<MemStorage> storage_;
172 std::shared_ptr<fake::Transport> transport_;
173 std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
174 std::shared_ptr<CommandManager> command_manager_;
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700175};
176
177////////////////////////////////////////////////////////////////////////////////
178TEST_F(DeviceRegistrationInfoTest, GetServiceURL) {
Alex Vakulenko45109442014-07-29 11:07:10 -0700179 EXPECT_TRUE(dev_reg_->Load());
180 EXPECT_EQ(test_data::kServiceURL, dev_reg_->GetServiceURL());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700181 std::string url = test_data::kServiceURL;
182 url += "registrationTickets";
Alex Vakulenko45109442014-07-29 11:07:10 -0700183 EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets"));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700184 url += "?key=";
185 url += test_data::kApiKey;
Alex Vakulenko45109442014-07-29 11:07:10 -0700186 EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets", {
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700187 {"key", test_data::kApiKey}
188 }));
189 url += "&restart=true";
Alex Vakulenko45109442014-07-29 11:07:10 -0700190 EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets", {
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700191 {"key", test_data::kApiKey},
192 {"restart", "true"},
193 }));
194}
195
196TEST_F(DeviceRegistrationInfoTest, GetOAuthURL) {
Alex Vakulenko45109442014-07-29 11:07:10 -0700197 EXPECT_TRUE(dev_reg_->Load());
198 EXPECT_EQ(test_data::kOAuthURL, dev_reg_->GetOAuthURL());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700199 std::string url = test_data::kOAuthURL;
200 url += "auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fclouddevices&";
201 url += "redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&";
202 url += "response_type=code&";
203 url += "client_id=";
204 url += test_data::kClientId;
Alex Vakulenko45109442014-07-29 11:07:10 -0700205 EXPECT_EQ(url, dev_reg_->GetOAuthURL("auth", {
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700206 {"scope", "https://www.googleapis.com/auth/clouddevices"},
207 {"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"},
208 {"response_type", "code"},
209 {"client_id", test_data::kClientId}
210 }));
211}
212
213TEST_F(DeviceRegistrationInfoTest, CheckRegistration) {
Alex Vakulenko45109442014-07-29 11:07:10 -0700214 EXPECT_TRUE(dev_reg_->Load());
215 EXPECT_FALSE(dev_reg_->CheckRegistration(nullptr));
216 EXPECT_EQ(0, transport_->GetRequestCount());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700217
Alex Vakulenko45109442014-07-29 11:07:10 -0700218 SetDefaultDeviceRegistration(&data_);
219 storage_->Save(&data_);
220 EXPECT_TRUE(dev_reg_->Load());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700221
Alex Vakulenko45109442014-07-29 11:07:10 -0700222 transport_->AddHandler(dev_reg_->GetOAuthURL("token"), request_type::kPost,
223 base::Bind(OAuth2Handler));
224 transport_->ResetRequestCount();
225 EXPECT_TRUE(dev_reg_->CheckRegistration(nullptr));
226 EXPECT_EQ(1, transport_->GetRequestCount());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700227}
228
229TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) {
Alex Vakulenko45109442014-07-29 11:07:10 -0700230 SetDefaultDeviceRegistration(&data_);
231 storage_->Save(&data_);
232 EXPECT_TRUE(dev_reg_->Load());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700233
Alex Vakulenko45109442014-07-29 11:07:10 -0700234 transport_->AddHandler(dev_reg_->GetOAuthURL("token"), request_type::kPost,
235 base::Bind(OAuth2Handler));
236 transport_->AddHandler(dev_reg_->GetDeviceURL(), request_type::kGet,
237 base::Bind(DeviceInfoHandler));
238 transport_->ResetRequestCount();
239 auto device_info = dev_reg_->GetDeviceInfo(nullptr);
240 EXPECT_EQ(2, transport_->GetRequestCount());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700241 EXPECT_NE(nullptr, device_info.get());
242 base::DictionaryValue* dict = nullptr;
243 EXPECT_TRUE(device_info->GetAsDictionary(&dict));
244 std::string id;
245 EXPECT_TRUE(dict->GetString("id", &id));
246 EXPECT_EQ(test_data::kDeviceId, id);
247}
248
249TEST_F(DeviceRegistrationInfoTest, GetDeviceId) {
Alex Vakulenko45109442014-07-29 11:07:10 -0700250 SetDefaultDeviceRegistration(&data_);
251 storage_->Save(&data_);
252 EXPECT_TRUE(dev_reg_->Load());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700253
Alex Vakulenko45109442014-07-29 11:07:10 -0700254 transport_->AddHandler(dev_reg_->GetOAuthURL("token"), request_type::kPost,
255 base::Bind(OAuth2Handler));
256 transport_->AddHandler(dev_reg_->GetDeviceURL(), request_type::kGet,
257 base::Bind(DeviceInfoHandler));
258 std::string id = dev_reg_->GetDeviceId(nullptr);
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700259 EXPECT_EQ(test_data::kDeviceId, id);
260}
261
262TEST_F(DeviceRegistrationInfoTest, StartRegistration) {
Alex Vakulenko45109442014-07-29 11:07:10 -0700263 EXPECT_TRUE(dev_reg_->Load());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700264
265 auto create_ticket = [](const fake::ServerRequest& request,
266 fake::ServerResponse* response) {
267 EXPECT_EQ(test_data::kApiKey, request.GetFormField("key"));
268 auto json = request.GetDataAsJson();
269 EXPECT_NE(nullptr, json.get());
270 std::string value;
271 EXPECT_TRUE(json->GetString("deviceDraft.channel.supportedType", &value));
272 EXPECT_EQ("xmpp", value);
273 EXPECT_TRUE(json->GetString("oauthClientId", &value));
274 EXPECT_EQ(test_data::kClientId, value);
275 EXPECT_TRUE(json->GetString("deviceDraft.deviceKind", &value));
276 EXPECT_EQ("vendor", value);
Alex Vakulenko45109442014-07-29 11:07:10 -0700277 base::DictionaryValue* commandDefs = nullptr;
278 EXPECT_TRUE(json->GetDictionary("deviceDraft.commandDefs", &commandDefs));
279 EXPECT_FALSE(commandDefs->empty());
280 EXPECT_EQ("{'base':{'reboot':{'parameters':{"
281 "'delay':{'minimum':10,'type':'integer'}}}},"
282 "'robot':{'_jump':{'parameters':{"
283 "'_height':{'type':'integer'}}}}}",
284 buffet::unittests::ValueToString(commandDefs));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700285
286 base::DictionaryValue json_resp;
287 json_resp.SetString("id", test_data::kClaimTicketId);
288 json_resp.SetString("kind", "clouddevices#registrationTicket");
289 json_resp.SetString("oauthClientId", test_data::kClientId);
290 base::DictionaryValue* device_draft = nullptr;
291 EXPECT_TRUE(json->GetDictionary("deviceDraft", &device_draft));
292 device_draft = device_draft->DeepCopy();
293 device_draft->SetString("id", test_data::kDeviceId);
294 device_draft->SetString("kind", "clouddevices#device");
295 json_resp.Set("deviceDraft", device_draft);
296
297 response->ReplyJson(status_code::Ok, &json_resp);
298 };
299
Alex Vakulenko45109442014-07-29 11:07:10 -0700300 auto json_base = buffet::unittests::CreateDictionaryValue(R"({
301 'base': {
302 'reboot': {
303 'parameters': {'delay': 'integer'}
304 },
305 'shutdown': {
306 'parameters': {}
307 }
308 }
309 })");
310 EXPECT_TRUE(command_manager_->LoadBaseCommands(*json_base, nullptr));
311 auto json_cmds = buffet::unittests::CreateDictionaryValue(R"({
312 'base': {
313 'reboot': {
314 'parameters': {'delay': {'minimum': 10}}
315 }
316 },
317 'robot': {
318 '_jump': {
319 'parameters': {'_height': 'integer'}
320 }
321 }
322 })");
323 EXPECT_TRUE(command_manager_->LoadCommands(*json_cmds, "", nullptr));
324
325 transport_->AddHandler(dev_reg_->GetServiceURL("registrationTickets"),
326 request_type::kPost,
327 base::Bind(create_ticket));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700328 std::map<std::string, std::shared_ptr<base::Value>> params;
Alex Vakulenko45109442014-07-29 11:07:10 -0700329 std::string json_resp = dev_reg_->StartRegistration(params, nullptr);
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700330 auto json = std::unique_ptr<base::Value>(base::JSONReader::Read(json_resp));
331 EXPECT_NE(nullptr, json.get());
332 base::DictionaryValue* dict = nullptr;
333 EXPECT_TRUE(json->GetAsDictionary(&dict));
334 std::string value;
335 EXPECT_TRUE(dict->GetString("ticket_id", &value));
336 EXPECT_EQ(test_data::kClaimTicketId, value);
337}
338
339TEST_F(DeviceRegistrationInfoTest, FinishRegistration_NoAuth) {
340 // Test finalizing ticket with no user authorization token.
341 // This assumes that a client would patch in their email separately.
Alex Vakulenko45109442014-07-29 11:07:10 -0700342 EXPECT_TRUE(dev_reg_->Load());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700343
344 // General ticket finalization handler.
345 std::string ticket_url =
Alex Vakulenko45109442014-07-29 11:07:10 -0700346 dev_reg_->GetServiceURL("registrationTickets/" +
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700347 std::string(test_data::kClaimTicketId));
Alex Vakulenko45109442014-07-29 11:07:10 -0700348 transport_->AddHandler(ticket_url + "/finalize", request_type::kPost,
349 base::Bind(FinalizeTicketHandler));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700350
Alex Vakulenko45109442014-07-29 11:07:10 -0700351 transport_->AddHandler(dev_reg_->GetOAuthURL("token"), request_type::kPost,
352 base::Bind(OAuth2Handler));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700353
Alex Vakulenko45109442014-07-29 11:07:10 -0700354 storage_->reset_save_count();
355 DeviceRegistrationInfo::TestHelper::SetTestTicketId(dev_reg_.get());
356 EXPECT_TRUE(dev_reg_->FinishRegistration("", nullptr));
357 EXPECT_EQ(1,
358 storage_->save_count()); // The device info must have been saved.
359 EXPECT_EQ(2, transport_->GetRequestCount());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700360
361 // Validate the device info saved to storage...
Alex Vakulenko45109442014-07-29 11:07:10 -0700362 auto storage_data = storage_->Load();
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700363 base::DictionaryValue* dict = nullptr;
364 EXPECT_TRUE(storage_data->GetAsDictionary(&dict));
365 std::string value;
366 EXPECT_TRUE(dict->GetString(storage_keys::kApiKey, &value));
367 EXPECT_EQ(test_data::kApiKey, value);
368 EXPECT_TRUE(dict->GetString(storage_keys::kClientId, &value));
369 EXPECT_EQ(test_data::kClientId, value);
370 EXPECT_TRUE(dict->GetString(storage_keys::kClientSecret, &value));
371 EXPECT_EQ(test_data::kClientSecret, value);
372 EXPECT_TRUE(dict->GetString(storage_keys::kDeviceId, &value));
373 EXPECT_EQ(test_data::kDeviceId, value);
374 EXPECT_TRUE(dict->GetString(storage_keys::kOAuthURL, &value));
375 EXPECT_EQ(test_data::kOAuthURL, value);
376 EXPECT_TRUE(dict->GetString(storage_keys::kRefreshToken, &value));
377 EXPECT_EQ(test_data::kRefreshToken, value);
378 EXPECT_TRUE(dict->GetString(storage_keys::kRobotAccount, &value));
379 EXPECT_EQ(test_data::kRobotAccountEmail, value);
380 EXPECT_TRUE(dict->GetString(storage_keys::kServiceURL, &value));
381 EXPECT_EQ(test_data::kServiceURL, value);
382}
383
384TEST_F(DeviceRegistrationInfoTest, FinishRegistration_Auth) {
385 // Test finalizing ticket with user authorization token.
Alex Vakulenko45109442014-07-29 11:07:10 -0700386 EXPECT_TRUE(dev_reg_->Load());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700387
388 // General ticket finalization handler.
389 std::string ticket_url =
Alex Vakulenko45109442014-07-29 11:07:10 -0700390 dev_reg_->GetServiceURL("registrationTickets/" +
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700391 std::string(test_data::kClaimTicketId));
Alex Vakulenko45109442014-07-29 11:07:10 -0700392 transport_->AddHandler(ticket_url + "/finalize", request_type::kPost,
393 base::Bind(FinalizeTicketHandler));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700394
Alex Vakulenko45109442014-07-29 11:07:10 -0700395 transport_->AddHandler(dev_reg_->GetOAuthURL("token"), request_type::kPost,
396 base::Bind(OAuth2Handler));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700397
398 // Handle patching in the user email onto the device record.
399 auto email_patch_handler = [](const fake::ServerRequest& request,
400 fake::ServerResponse* response) {
401 std::string auth_header = "Bearer ";
402 auth_header += test_data::kUserAccessToken;
403 EXPECT_EQ(auth_header,
404 request.GetHeader(http::request_header::kAuthorization));
405 auto json = request.GetDataAsJson();
406 EXPECT_NE(nullptr, json.get());
407 std::string value;
408 EXPECT_TRUE(json->GetString("userEmail", &value));
409 EXPECT_EQ("me", value);
410
411 response->ReplyJson(status_code::Ok, {
412 {"id", test_data::kClaimTicketId},
413 {"kind", "clouddevices#registrationTicket"},
414 {"oauthClientId", test_data::kClientId},
415 {"userEmail", "user@email.com"},
416 {"deviceDraft.id", test_data::kDeviceId},
417 {"deviceDraft.kind", "clouddevices#device"},
418 {"deviceDraft.channel.supportedType", "xmpp"},
419 });
420 };
Alex Vakulenko45109442014-07-29 11:07:10 -0700421 transport_->AddHandler(ticket_url, request_type::kPatch,
422 base::Bind(email_patch_handler));
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700423
Alex Vakulenko45109442014-07-29 11:07:10 -0700424 storage_->reset_save_count();
425 DeviceRegistrationInfo::TestHelper::SetTestTicketId(dev_reg_.get());
426 EXPECT_TRUE(dev_reg_->FinishRegistration(test_data::kUserAccountAuthCode,
Alex Vakulenkob3aac252014-05-07 17:35:24 -0700427 nullptr));
Alex Vakulenko45109442014-07-29 11:07:10 -0700428 EXPECT_EQ(1,
429 storage_->save_count()); // The device info must have been saved.
430 EXPECT_EQ(4, transport_->GetRequestCount());
Alex Vakulenko8e34d392014-04-29 11:02:56 -0700431}