blob: ecf479717c4c3115dc2bbbcea2bad21b5b2c241d [file] [log] [blame]
Vitaly Buka4615e0d2015-10-14 15:35:12 -07001// Copyright 2015 The Weave Authors. All rights reserved.
Vitaly Buka7ce499f2015-06-09 08:04:11 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Stefan Sauer2d16dfa2015-09-25 17:08:35 +02005#include "src/privet/privet_handler.h"
Vitaly Buka7ce499f2015-06-09 08:04:11 -07006
7#include <set>
8#include <string>
9#include <utility>
10
11#include <base/bind.h>
12#include <base/json/json_reader.h>
13#include <base/json/json_writer.h>
Vitaly Buka7ce499f2015-06-09 08:04:11 -070014#include <base/strings/string_util.h>
15#include <base/values.h>
Vitaly Buka7ce499f2015-06-09 08:04:11 -070016#include <gmock/gmock.h>
17#include <gtest/gtest.h>
Vitaly Buka03ee8ac2016-02-05 11:40:33 -080018#include <weave/device.h>
Alex Vakulenko29a11ca2015-12-07 14:43:04 -080019#include <weave/test/unittest_utils.h>
Vitaly Buka7ce499f2015-06-09 08:04:11 -070020
Stefan Sauer2d16dfa2015-09-25 17:08:35 +020021#include "src/privet/constants.h"
22#include "src/privet/mock_delegates.h"
Alex Vakulenko532140d2015-12-11 17:18:21 -080023#include "src/test/mock_clock.h"
Vitaly Buka7ce499f2015-06-09 08:04:11 -070024
25using testing::_;
26using testing::DoAll;
27using testing::Invoke;
28using testing::Return;
29using testing::SetArgPointee;
Alex Vakulenkoefee3a22015-11-17 15:08:38 -080030using testing::SaveArg;
Vitaly Bukaf7f52d42015-10-10 22:43:55 -070031using testing::WithArgs;
Vitaly Buka7ce499f2015-06-09 08:04:11 -070032
Vitaly Bukab6f015a2015-07-09 14:59:23 -070033namespace weave {
34namespace privet {
Vitaly Buka7ce499f2015-06-09 08:04:11 -070035
36namespace {
37
38void LoadTestJson(const std::string& test_json,
39 base::DictionaryValue* dictionary) {
Vitaly Buka7ce499f2015-06-09 08:04:11 -070040 int error = 0;
41 std::string message;
Alex Vakulenkoae1ffbc2015-06-15 12:53:22 -070042 std::unique_ptr<base::Value> value(
Vitaly Buka3e860992016-02-10 14:01:46 -080043 base::JSONReader::ReadAndReturnError(test_json, base::JSON_PARSE_RFC,
44 &error, &message)
Alex Vakulenkoae1ffbc2015-06-15 12:53:22 -070045 .release());
Vitaly Buka3e860992016-02-10 14:01:46 -080046 EXPECT_TRUE(value.get()) << "\nError: " << message << "\n" << test_json;
Vitaly Buka7ce499f2015-06-09 08:04:11 -070047 base::DictionaryValue* dictionary_ptr = nullptr;
48 if (value->GetAsDictionary(&dictionary_ptr))
49 dictionary->MergeDictionary(dictionary_ptr);
50}
51
Vitaly Buka7ce499f2015-06-09 08:04:11 -070052struct CodeWithReason {
53 CodeWithReason(int code_in, const std::string& reason_in)
54 : code(code_in), reason(reason_in) {}
55 int code;
56 std::string reason;
57};
58
59std::ostream& operator<<(std::ostream& stream, const CodeWithReason& error) {
Vitaly Buka3e860992016-02-10 14:01:46 -080060 return stream << R"({" << error.code << ", " << error.reason << "})";
Vitaly Buka7ce499f2015-06-09 08:04:11 -070061}
62
63bool IsEqualError(const CodeWithReason& expected,
64 const base::DictionaryValue& dictionary) {
65 std::string reason;
66 int code = 0;
67 return dictionary.GetInteger("error.http_status", &code) &&
68 code == expected.code && dictionary.GetString("error.code", &reason) &&
69 reason == expected.reason;
70}
71
Alex Vakulenko29a11ca2015-12-07 14:43:04 -080072// Some error sections in response JSON objects contained debugging information
Vitaly Buka34668e72015-12-15 14:46:47 -080073// which is of no interest for this test. So, remove the debug info from the
74// JSON before running validation logic on it.
Alex Vakulenko29a11ca2015-12-07 14:43:04 -080075std::unique_ptr<base::DictionaryValue> StripDebugErrorDetails(
76 const std::string& path_to_error_object,
77 const base::DictionaryValue& value) {
78 std::unique_ptr<base::DictionaryValue> result{value.DeepCopy()};
79 base::DictionaryValue* error_dict = nullptr;
80 EXPECT_TRUE(result->GetDictionary(path_to_error_object, &error_dict));
81 scoped_ptr<base::Value> dummy;
82 error_dict->RemovePath("error.debugInfo", &dummy);
83 error_dict->RemovePath("error.message", &dummy);
84 return result;
Vitaly Buka7ce499f2015-06-09 08:04:11 -070085}
86
87} // namespace
88
89class PrivetHandlerTest : public testing::Test {
90 public:
91 PrivetHandlerTest() {}
92
93 protected:
94 void SetUp() override {
Alex Vakulenko532140d2015-12-11 17:18:21 -080095 EXPECT_CALL(clock_, Now())
Vitaly Buka1884cf62015-12-12 15:47:42 -080096 .WillRepeatedly(Return(base::Time::FromTimeT(1410000001)));
Alex Vakulenko532140d2015-12-11 17:18:21 -080097
Vitaly Buka7ce499f2015-06-09 08:04:11 -070098 auth_header_ = "Privet anonymous";
Vitaly Buka34668e72015-12-15 14:46:47 -080099 handler_.reset(
100 new PrivetHandler(&cloud_, &device_, &security_, &wifi_, &clock_));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700101 }
102
103 const base::DictionaryValue& HandleRequest(
104 const std::string& api,
105 const base::DictionaryValue* input) {
106 output_.Clear();
107 handler_->HandleRequest(api, auth_header_, input,
108 base::Bind(&PrivetHandlerTest::HandlerCallback,
109 base::Unretained(this)));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700110 return output_;
111 }
112
113 const base::DictionaryValue& HandleRequest(const std::string& api,
114 const std::string& json_input) {
115 base::DictionaryValue dictionary;
116 LoadTestJson(json_input, &dictionary);
117 return HandleRequest(api, &dictionary);
118 }
119
120 void HandleUnknownRequest(const std::string& api) {
121 output_.Clear();
122 base::DictionaryValue dictionary;
123 handler_->HandleRequest(api, auth_header_, &dictionary,
124 base::Bind(&PrivetHandlerTest::HandlerNoFound));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700125 }
126
Alex Vakulenkoefee3a22015-11-17 15:08:38 -0800127 const base::DictionaryValue& GetResponse() const { return output_; }
128 int GetResponseCount() const { return response_count_; }
129
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700130 void SetNoWifiAndGcd() {
Vitaly Buka34668e72015-12-15 14:46:47 -0800131 handler_.reset(
132 new PrivetHandler(&cloud_, &device_, &security_, nullptr, &clock_));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700133 EXPECT_CALL(cloud_, GetCloudId()).WillRepeatedly(Return(""));
134 EXPECT_CALL(cloud_, GetConnectionState())
135 .WillRepeatedly(ReturnRef(gcd_disabled_state_));
Vitaly Buka03ee8ac2016-02-05 11:40:33 -0800136 auto set_error = [](ErrorPtr* error) {
Vitaly Buka48a86692016-01-21 17:15:58 -0800137 Error::AddTo(error, FROM_HERE, "setupUnavailable", "");
Vitaly Buka075b3d42015-06-09 08:34:25 -0700138 };
Vitaly Buka03ee8ac2016-02-05 11:40:33 -0800139 EXPECT_CALL(cloud_, Setup(_, _))
140 .WillRepeatedly(DoAll(WithArgs<1>(Invoke(set_error)), Return(false)));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700141 }
142
Alex Vakulenko532140d2015-12-11 17:18:21 -0800143 test::MockClock clock_;
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700144 testing::StrictMock<MockCloudDelegate> cloud_;
145 testing::StrictMock<MockDeviceDelegate> device_;
146 testing::StrictMock<MockSecurityDelegate> security_;
147 testing::StrictMock<MockWifiDelegate> wifi_;
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700148 std::string auth_header_;
149
150 private:
151 void HandlerCallback(int status, const base::DictionaryValue& output) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -0800152 output_.Clear();
153 ++response_count_;
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700154 output_.MergeDictionary(&output);
155 if (!output_.HasKey("error")) {
Vitaly Buka1da65992015-08-06 01:38:57 -0700156 EXPECT_EQ(200, status);
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700157 return;
158 }
Vitaly Buka1da65992015-08-06 01:38:57 -0700159 EXPECT_NE(200, status);
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700160 output_.SetInteger("error.http_status", status);
161 }
162
163 static void HandlerNoFound(int status, const base::DictionaryValue&) {
Vitaly Buka1da65992015-08-06 01:38:57 -0700164 EXPECT_EQ(404, status);
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700165 }
166
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700167 std::unique_ptr<PrivetHandler> handler_;
168 base::DictionaryValue output_;
Alex Vakulenkoefee3a22015-11-17 15:08:38 -0800169 int response_count_{0};
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700170 ConnectionState gcd_disabled_state_{ConnectionState::kDisabled};
171};
172
173TEST_F(PrivetHandlerTest, UnknownApi) {
174 HandleUnknownRequest("/privet/foo");
175}
176
177TEST_F(PrivetHandlerTest, InvalidFormat) {
178 auth_header_ = "";
179 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidFormat"),
180 HandleRequest("/privet/info", nullptr));
181}
182
183TEST_F(PrivetHandlerTest, MissingAuth) {
184 auth_header_ = "";
185 EXPECT_PRED2(IsEqualError, CodeWithReason(401, "missingAuthorization"),
186 HandleRequest("/privet/info", "{}"));
187}
188
189TEST_F(PrivetHandlerTest, InvalidAuth) {
190 auth_header_ = "foo";
191 EXPECT_PRED2(IsEqualError, CodeWithReason(401, "invalidAuthorization"),
192 HandleRequest("/privet/info", "{}"));
193}
194
195TEST_F(PrivetHandlerTest, ExpiredAuth) {
196 auth_header_ = "Privet 123";
Vitaly Bukaa0a81342015-12-17 13:42:13 -0800197 EXPECT_CALL(security_, ParseAccessToken(_, _, _))
Vitaly Buka0dbbf602016-01-22 11:38:37 -0800198 .WillRepeatedly(WithArgs<2>(Invoke([](ErrorPtr* error) {
199 return Error::AddTo(error, FROM_HERE, "authorizationExpired", "");
200 })));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700201 EXPECT_PRED2(IsEqualError, CodeWithReason(403, "authorizationExpired"),
202 HandleRequest("/privet/info", "{}"));
203}
204
205TEST_F(PrivetHandlerTest, InvalidAuthScope) {
206 EXPECT_PRED2(IsEqualError, CodeWithReason(403, "invalidAuthorizationScope"),
207 HandleRequest("/privet/v3/setup/start", "{}"));
208}
209
210TEST_F(PrivetHandlerTest, InfoMinimal) {
211 SetNoWifiAndGcd();
212 EXPECT_CALL(security_, GetPairingTypes())
213 .WillRepeatedly(Return(std::set<PairingType>{}));
214 EXPECT_CALL(security_, GetCryptoTypes())
215 .WillRepeatedly(Return(std::set<CryptoType>{}));
Vitaly Bukaee7322f2015-12-18 16:54:05 -0800216 EXPECT_CALL(security_, GetAuthTypes())
217 .WillRepeatedly(Return(std::set<AuthType>{}));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700218
219 const char kExpected[] = R"({
Vitaly Buka8b005972016-02-10 11:24:42 -0800220 "version": "3.0",
221 "id": "TestId",
222 "name": "TestDevice",
223 "services": [ "developmentBoard" ],
224 "modelManifestId": "ABMID",
225 "basicModelManifest": {
226 "uiDeviceKind": "developmentBoard",
227 "oemName": "Chromium",
228 "modelName": "Brillo"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700229 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800230 "endpoints": {
231 "httpPort": 0,
232 "httpUpdatesPort": 0,
233 "httpsPort": 0,
234 "httpsUpdatesPort": 0
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700235 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800236 "authentication": {
237 "anonymousMaxScope": "user",
238 "mode": [
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700239 ],
Vitaly Buka8b005972016-02-10 11:24:42 -0800240 "pairing": [
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700241 ],
Vitaly Buka8b005972016-02-10 11:24:42 -0800242 "crypto": [
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700243 ]
244 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800245 "gcd": {
246 "id": "",
247 "oauth_url": "https://oauths/",
248 "service_url": "https://service/",
249 "status": "disabled",
250 "xmpp_endpoint": "xmpp:678"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700251 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800252 "time": 1410000001000.0,
253 "sessionId": "SessionId"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700254 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800255 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/info", "{}"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700256}
257
258TEST_F(PrivetHandlerTest, Info) {
259 EXPECT_CALL(cloud_, GetDescription())
260 .WillRepeatedly(Return("TestDescription"));
261 EXPECT_CALL(cloud_, GetLocation()).WillRepeatedly(Return("TestLocation"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700262 EXPECT_CALL(device_, GetHttpEnpoint())
263 .WillRepeatedly(Return(std::make_pair(80, 10080)));
264 EXPECT_CALL(device_, GetHttpsEnpoint())
265 .WillRepeatedly(Return(std::make_pair(443, 10443)));
266 EXPECT_CALL(wifi_, GetHostedSsid())
267 .WillRepeatedly(Return("Test_device.BBABCLAprv"));
268
269 const char kExpected[] = R"({
Vitaly Buka8b005972016-02-10 11:24:42 -0800270 "version": "3.0",
271 "id": "TestId",
272 "name": "TestDevice",
273 "description": "TestDescription",
274 "location": "TestLocation",
275 "services": [ "developmentBoard" ],
276 "modelManifestId": "ABMID",
277 "basicModelManifest": {
278 "uiDeviceKind": "developmentBoard",
279 "oemName": "Chromium",
280 "modelName": "Brillo"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700281 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800282 "endpoints": {
283 "httpPort": 80,
284 "httpUpdatesPort": 10080,
285 "httpsPort": 443,
286 "httpsUpdatesPort": 10443
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700287 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800288 "authentication": {
289 "anonymousMaxScope": "none",
290 "mode": [
291 "anonymous",
292 "pairing",
293 "local"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700294 ],
Vitaly Buka8b005972016-02-10 11:24:42 -0800295 "pairing": [
296 "pinCode",
297 "embeddedCode"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700298 ],
Vitaly Buka8b005972016-02-10 11:24:42 -0800299 "crypto": [
300 "p224_spake2"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700301 ]
302 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800303 "wifi": {
304 "capabilities": [
305 "2.4GHz"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700306 ],
Vitaly Buka8b005972016-02-10 11:24:42 -0800307 "ssid": "TestSsid",
308 "hostedSsid": "Test_device.BBABCLAprv",
309 "status": "offline"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700310 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800311 "gcd": {
312 "id": "TestCloudId",
313 "oauth_url": "https://oauths/",
314 "service_url": "https://service/",
315 "status": "online",
316 "xmpp_endpoint": "xmpp:678"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700317 },
Vitaly Buka8b005972016-02-10 11:24:42 -0800318 "time": 1410000001000.0,
319 "sessionId": "SessionId"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700320 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800321 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/info", "{}"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700322}
323
324TEST_F(PrivetHandlerTest, PairingStartInvalidParams) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800325 EXPECT_PRED2(
326 IsEqualError, CodeWithReason(400, "invalidParams"),
327 HandleRequest("/privet/v3/pairing/start",
328 R"({"pairing":"embeddedCode","crypto":"crypto"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700329
330 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"),
331 HandleRequest("/privet/v3/pairing/start",
Vitaly Buka3e860992016-02-10 14:01:46 -0800332 R"({"pairing":"code","crypto":"p224_spake2"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700333}
334
335TEST_F(PrivetHandlerTest, PairingStart) {
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800336 EXPECT_JSON_EQ(
Vitaly Buka3e860992016-02-10 14:01:46 -0800337 R"({"deviceCommitment": "testCommitment", "sessionId": "testSession"})",
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700338 HandleRequest("/privet/v3/pairing/start",
Vitaly Buka3e860992016-02-10 14:01:46 -0800339 R"({"pairing": "embeddedCode", "crypto": "p224_spake2"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700340}
341
342TEST_F(PrivetHandlerTest, PairingConfirm) {
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800343 EXPECT_JSON_EQ(
Vitaly Buka3e860992016-02-10 14:01:46 -0800344 R"({"certFingerprint":"testFingerprint","certSignature":"testSignature"})",
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700345 HandleRequest(
346 "/privet/v3/pairing/confirm",
Vitaly Buka3e860992016-02-10 14:01:46 -0800347 R"({"sessionId":"testSession","clientCommitment":"testCommitment"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700348}
349
350TEST_F(PrivetHandlerTest, PairingCancel) {
Vitaly Buka34668e72015-12-15 14:46:47 -0800351 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/pairing/cancel",
Vitaly Buka3e860992016-02-10 14:01:46 -0800352 R"({"sessionId": "testSession"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700353}
354
355TEST_F(PrivetHandlerTest, AuthErrorNoType) {
356 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidAuthMode"),
357 HandleRequest("/privet/v3/auth", "{}"));
358}
359
360TEST_F(PrivetHandlerTest, AuthErrorInvalidType) {
361 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidAuthMode"),
Vitaly Buka3e860992016-02-10 14:01:46 -0800362 HandleRequest("/privet/v3/auth", R"({"mode":"unknown"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700363}
364
365TEST_F(PrivetHandlerTest, AuthErrorNoScope) {
366 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidRequestedScope"),
Vitaly Buka3e860992016-02-10 14:01:46 -0800367 HandleRequest("/privet/v3/auth", R"({"mode":"anonymous"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700368}
369
370TEST_F(PrivetHandlerTest, AuthErrorInvalidScope) {
371 EXPECT_PRED2(
372 IsEqualError, CodeWithReason(400, "invalidRequestedScope"),
373 HandleRequest("/privet/v3/auth",
Vitaly Buka3e860992016-02-10 14:01:46 -0800374 R"({"mode":"anonymous","requestedScope":"unknown"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700375}
376
377TEST_F(PrivetHandlerTest, AuthErrorAccessDenied) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800378 EXPECT_PRED2(
379 IsEqualError, CodeWithReason(403, "accessDenied"),
380 HandleRequest("/privet/v3/auth",
381 R"({"mode":"anonymous","requestedScope":"owner"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700382}
383
384TEST_F(PrivetHandlerTest, AuthErrorInvalidAuthCode) {
Vitaly Bukafd2ef682015-12-17 20:57:01 -0800385 auto set_error = [](ErrorPtr* error) {
Vitaly Buka0dbbf602016-01-22 11:38:37 -0800386 return Error::AddTo(error, FROM_HERE, "invalidAuthCode", "");
Vitaly Bukafd2ef682015-12-17 20:57:01 -0800387 };
388 EXPECT_CALL(security_, CreateAccessToken(_, "testToken", _, _, _, _, _))
Vitaly Buka0dbbf602016-01-22 11:38:37 -0800389 .WillRepeatedly(WithArgs<6>(Invoke(set_error)));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700390 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800391 "mode": "pairing",
392 "requestedScope": "user",
393 "authCode": "testToken"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700394 })";
395 EXPECT_PRED2(IsEqualError, CodeWithReason(403, "invalidAuthCode"),
396 HandleRequest("/privet/v3/auth", kInput));
397}
398
399TEST_F(PrivetHandlerTest, AuthAnonymous) {
400 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800401 "accessToken": "GuestAccessToken",
402 "expiresIn": 15,
403 "scope": "viewer",
404 "tokenType": "Privet"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700405 })";
Vitaly Buka3e860992016-02-10 14:01:46 -0800406 EXPECT_JSON_EQ(
407 kExpected,
408 HandleRequest("/privet/v3/auth",
409 R"({"mode":"anonymous","requestedScope":"auto"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700410}
411
412TEST_F(PrivetHandlerTest, AuthPairing) {
Vitaly Bukafd2ef682015-12-17 20:57:01 -0800413 EXPECT_CALL(security_, CreateAccessToken(_, _, _, _, _, _, _))
414 .WillRepeatedly(DoAll(SetArgPointee<3>("OwnerAccessToken"),
415 SetArgPointee<4>(AuthScope::kOwner),
416 SetArgPointee<5>(base::TimeDelta::FromSeconds(15)),
417 Return(true)));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700418 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800419 "mode": "pairing",
420 "requestedScope": "owner",
421 "authCode": "testToken"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700422 })";
423 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800424 "accessToken": "OwnerAccessToken",
425 "expiresIn": 15,
426 "scope": "owner",
427 "tokenType": "Privet"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700428 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800429 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/auth", kInput));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700430}
431
Vitaly Buka4957afb2015-12-17 22:50:24 -0800432TEST_F(PrivetHandlerTest, AuthLocalAuto) {
Vitaly Buka4957afb2015-12-17 22:50:24 -0800433 EXPECT_CALL(security_, CreateAccessToken(_, _, _, _, _, _, _))
434 .WillRepeatedly(DoAll(SetArgPointee<3>("UserAccessToken"),
435 SetArgPointee<4>(AuthScope::kUser),
436 SetArgPointee<5>(base::TimeDelta::FromSeconds(15)),
437 Return(true)));
438 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800439 "mode": "local",
440 "requestedScope": "auto",
441 "authCode": "localAuthToken"
Vitaly Buka4957afb2015-12-17 22:50:24 -0800442 })";
443 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800444 "accessToken": "UserAccessToken",
445 "expiresIn": 15,
446 "scope": "user",
447 "tokenType": "Privet"
Vitaly Buka4957afb2015-12-17 22:50:24 -0800448 })";
449 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/auth", kInput));
450}
451
452TEST_F(PrivetHandlerTest, AuthLocal) {
Vitaly Buka4957afb2015-12-17 22:50:24 -0800453 EXPECT_CALL(security_, CreateAccessToken(_, _, _, _, _, _, _))
454 .WillRepeatedly(DoAll(SetArgPointee<3>("ManagerAccessToken"),
455 SetArgPointee<4>(AuthScope::kManager),
456 SetArgPointee<5>(base::TimeDelta::FromSeconds(15)),
457 Return(true)));
458 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800459 "mode": "local",
460 "requestedScope": "manager",
461 "authCode": "localAuthToken"
Vitaly Buka4957afb2015-12-17 22:50:24 -0800462 })";
463 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800464 "accessToken": "ManagerAccessToken",
465 "expiresIn": 15,
466 "scope": "manager",
467 "tokenType": "Privet"
Vitaly Buka4957afb2015-12-17 22:50:24 -0800468 })";
469 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/auth", kInput));
470}
471
472TEST_F(PrivetHandlerTest, AuthLocalHighScope) {
Vitaly Buka4957afb2015-12-17 22:50:24 -0800473 EXPECT_CALL(security_, CreateAccessToken(_, _, _, _, _, _, _))
474 .WillRepeatedly(DoAll(SetArgPointee<3>("UserAccessToken"),
475 SetArgPointee<4>(AuthScope::kUser),
476 SetArgPointee<5>(base::TimeDelta::FromSeconds(1)),
477 Return(true)));
478 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800479 "mode": "local",
480 "requestedScope": "manager",
481 "authCode": "localAuthToken"
Vitaly Buka4957afb2015-12-17 22:50:24 -0800482 })";
483 EXPECT_PRED2(IsEqualError, CodeWithReason(403, "accessDenied"),
484 HandleRequest("/privet/v3/auth", kInput));
485}
486
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -0800487class PrivetHandlerTestWithAuth : public PrivetHandlerTest {
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700488 public:
489 void SetUp() override {
490 PrivetHandlerTest::SetUp();
491 auth_header_ = "Privet 123";
Vitaly Bukaa0a81342015-12-17 13:42:13 -0800492 EXPECT_CALL(security_, ParseAccessToken(_, _, _))
Vitaly Buka66f46b82015-12-18 15:36:01 -0800493 .WillRepeatedly(DoAll(
Vitaly Buka4fe71e32016-01-29 11:50:53 -0800494 SetArgPointee<1>(UserInfo{AuthScope::kOwner, TestUserId{"1"}}),
495 Return(true)));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700496 }
497};
498
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -0800499class PrivetHandlerSetupTest : public PrivetHandlerTestWithAuth {};
500
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700501TEST_F(PrivetHandlerSetupTest, StatusEmpty) {
502 SetNoWifiAndGcd();
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800503 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/setup/status", "{}"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700504}
505
506TEST_F(PrivetHandlerSetupTest, StatusWifi) {
507 wifi_.setup_state_ = SetupState{SetupState::kSuccess};
508
509 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800510 "wifi": {
511 "ssid": "TestSsid",
512 "status": "success"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700513 }
514 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800515 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/status", "{}"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700516}
517
518TEST_F(PrivetHandlerSetupTest, StatusWifiError) {
Vitaly Buka0801a1f2015-08-14 10:03:46 -0700519 ErrorPtr error;
Vitaly Buka48a86692016-01-21 17:15:58 -0800520 Error::AddTo(&error, FROM_HERE, "invalidPassphrase", "");
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700521 wifi_.setup_state_ = SetupState{std::move(error)};
522
523 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800524 "wifi": {
525 "status": "error",
526 "error": {
527 "code": "invalidPassphrase"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700528 }
529 }
530 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800531 EXPECT_JSON_EQ(kExpected,
Vitaly Buka34668e72015-12-15 14:46:47 -0800532 *StripDebugErrorDetails(
533 "wifi", HandleRequest("/privet/v3/setup/status", "{}")));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700534}
535
536TEST_F(PrivetHandlerSetupTest, StatusGcd) {
537 cloud_.setup_state_ = SetupState{SetupState::kSuccess};
538
539 const char kExpected[] = R"({
Vitaly Buka8b005972016-02-10 11:24:42 -0800540 "gcd": {
541 "id": "TestCloudId",
542 "oauth_url": "https://oauths/",
543 "service_url": "https://service/",
544 "status": "success",
545 "xmpp_endpoint": "xmpp:678"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700546 }
547 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800548 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/status", "{}"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700549}
550
551TEST_F(PrivetHandlerSetupTest, StatusGcdError) {
Vitaly Buka0801a1f2015-08-14 10:03:46 -0700552 ErrorPtr error;
Vitaly Buka48a86692016-01-21 17:15:58 -0800553 Error::AddTo(&error, FROM_HERE, "invalidTicket", "");
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700554 cloud_.setup_state_ = SetupState{std::move(error)};
555
556 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800557 "gcd": {
558 "status": "error",
559 "error": {
560 "code": "invalidTicket"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700561 }
562 }
563 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800564 EXPECT_JSON_EQ(kExpected,
Vitaly Buka34668e72015-12-15 14:46:47 -0800565 *StripDebugErrorDetails(
566 "gcd", HandleRequest("/privet/v3/setup/status", "{}")));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700567}
568
569TEST_F(PrivetHandlerSetupTest, SetupNameDescriptionLocation) {
Vitaly Bukab624bc42015-09-29 19:13:55 -0700570 EXPECT_CALL(cloud_,
571 UpdateDeviceInfo("testName", "testDescription", "testLocation"))
Vitaly Bukaa647c852015-07-06 14:51:01 -0700572 .Times(1);
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700573 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800574 "name": "testName",
575 "description": "testDescription",
576 "location": "testLocation"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700577 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800578 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/setup/start", kInput));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700579}
580
581TEST_F(PrivetHandlerSetupTest, InvalidParams) {
582 const char kInputWifi[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800583 "wifi": {
584 "ssid": ""
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700585 }
586 })";
587 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"),
588 HandleRequest("/privet/v3/setup/start", kInputWifi));
589
590 const char kInputRegistration[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800591 "gcd": {
592 "ticketId": ""
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700593 }
594 })";
595 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"),
596 HandleRequest("/privet/v3/setup/start", kInputRegistration));
597}
598
599TEST_F(PrivetHandlerSetupTest, WifiSetupUnavailable) {
600 SetNoWifiAndGcd();
601 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "setupUnavailable"),
Vitaly Buka3e860992016-02-10 14:01:46 -0800602 HandleRequest("/privet/v3/setup/start", R"({"wifi": {}})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700603}
604
605TEST_F(PrivetHandlerSetupTest, WifiSetup) {
606 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800607 "wifi": {
608 "ssid": "testSsid",
609 "passphrase": "testPass"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700610 }
611 })";
Vitaly Buka0801a1f2015-08-14 10:03:46 -0700612 auto set_error = [](const std::string&, const std::string&, ErrorPtr* error) {
Vitaly Buka0dbbf602016-01-22 11:38:37 -0800613 return Error::AddTo(error, FROM_HERE, "deviceBusy", "");
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700614 };
Vitaly Buka0dbbf602016-01-22 11:38:37 -0800615 EXPECT_CALL(wifi_, ConfigureCredentials(_, _, _)).WillOnce(Invoke(set_error));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700616 EXPECT_PRED2(IsEqualError, CodeWithReason(503, "deviceBusy"),
617 HandleRequest("/privet/v3/setup/start", kInput));
618
619 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800620 "wifi": {
621 "status": "inProgress"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700622 }
623 })";
624 wifi_.setup_state_ = SetupState{SetupState::kInProgress};
625 EXPECT_CALL(wifi_, ConfigureCredentials("testSsid", "testPass", _))
626 .WillOnce(Return(true));
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800627 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/start", kInput));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700628}
629
630TEST_F(PrivetHandlerSetupTest, GcdSetupUnavailable) {
631 SetNoWifiAndGcd();
632 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800633 "gcd": {
634 "ticketId": "testTicket",
635 "user": "testUser"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700636 }
637 })";
638
639 EXPECT_PRED2(IsEqualError, CodeWithReason(400, "setupUnavailable"),
640 HandleRequest("/privet/v3/setup/start", kInput));
641}
642
643TEST_F(PrivetHandlerSetupTest, GcdSetup) {
644 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800645 "gcd": {
646 "ticketId": "testTicket",
647 "user": "testUser"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700648 }
649 })";
650
Vitaly Buka03ee8ac2016-02-05 11:40:33 -0800651 auto set_error = [](ErrorPtr* error) {
Vitaly Buka0dbbf602016-01-22 11:38:37 -0800652 return Error::AddTo(error, FROM_HERE, "deviceBusy", "");
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700653 };
Vitaly Buka03ee8ac2016-02-05 11:40:33 -0800654 EXPECT_CALL(cloud_, Setup(_, _)).WillOnce(WithArgs<1>(Invoke(set_error)));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700655 EXPECT_PRED2(IsEqualError, CodeWithReason(503, "deviceBusy"),
656 HandleRequest("/privet/v3/setup/start", kInput));
657
658 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800659 "gcd": {
660 "status": "inProgress"
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700661 }
662 })";
663 cloud_.setup_state_ = SetupState{SetupState::kInProgress};
Vitaly Buka03ee8ac2016-02-05 11:40:33 -0800664 EXPECT_CALL(cloud_, Setup(RegistrationData{"testTicket"}, _))
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700665 .WillOnce(Return(true));
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800666 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/start", kInput));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700667}
668
Vitaly Buka8b005972016-02-10 11:24:42 -0800669TEST_F(PrivetHandlerSetupTest, GcdSetupWithEndpoints) {
670 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800671 "gcd": {
Vitaly Buka8b005972016-02-10 11:24:42 -0800672 "api_key": "test_api_key",
673 "client_id": "test_client_id",
674 "client_secret": "test_client_secret",
675 "oauth_url": "https://oauths/",
676 "service_url": "https://service/",
Vitaly Buka8b005972016-02-10 11:24:42 -0800677 "xmpp_endpoint": "xmpp:678",
678 "ticketId": "testTicket",
679 "user": "testUser"
680 }
681 })";
682
683 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800684 "gcd": {
685 "status": "inProgress"
Vitaly Buka8b005972016-02-10 11:24:42 -0800686 }
687 })";
688 cloud_.setup_state_ = SetupState{SetupState::kInProgress};
689
690 RegistrationData expected_reg_data;
691 expected_reg_data.ticket_id = "testTicket";
692 expected_reg_data.oauth_url = "https://oauths/";
693 expected_reg_data.client_id = "test_client_id";
694 expected_reg_data.client_secret = "test_client_secret";
695 expected_reg_data.api_key = "test_api_key";
696 expected_reg_data.service_url = "https://service/";
697 expected_reg_data.xmpp_endpoint = "xmpp:678";
698
699 EXPECT_CALL(cloud_, Setup(expected_reg_data, _)).WillOnce(Return(true));
700 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/start", kInput));
701}
702
Vitaly Buka287346b2015-12-15 14:35:28 -0800703TEST_F(PrivetHandlerSetupTest, GcdSetupAsMaster) {
Vitaly Bukaa0a81342015-12-17 13:42:13 -0800704 EXPECT_CALL(security_, ParseAccessToken(_, _, _))
Vitaly Buka66f46b82015-12-18 15:36:01 -0800705 .WillRepeatedly(DoAll(
Vitaly Buka4fe71e32016-01-29 11:50:53 -0800706 SetArgPointee<1>(UserInfo{AuthScope::kManager, TestUserId{"1"}}),
707 Return(true)));
Vitaly Buka287346b2015-12-15 14:35:28 -0800708 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800709 "gcd": {
710 "ticketId": "testTicket",
711 "user": "testUser"
Vitaly Buka287346b2015-12-15 14:35:28 -0800712 }
713 })";
714
715 EXPECT_PRED2(IsEqualError, CodeWithReason(403, "invalidAuthorizationScope"),
716 HandleRequest("/privet/v3/setup/start", kInput));
717}
718
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800719TEST_F(PrivetHandlerTestWithAuth, ClaimAccessControl) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800720 EXPECT_JSON_EQ(R"({"clientToken": "RootClientAuthToken"})",
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800721 HandleRequest("/privet/v3/accessControl/claim", "{}"));
722}
723
724TEST_F(PrivetHandlerTestWithAuth, ConfirmAccessControl) {
725 EXPECT_JSON_EQ("{}",
726 HandleRequest("/privet/v3/accessControl/confirm",
Vitaly Buka3e860992016-02-10 14:01:46 -0800727 R"({"clientToken": "DerivedClientAuthToken"})"));
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800728}
729
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800730TEST_F(PrivetHandlerTestWithAuth, Traits) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800731 EXPECT_JSON_EQ(R"({"traits": {"test": {}}, "fingerprint": "1"})",
Alex Vakulenko551a82b2015-12-07 14:46:12 -0800732 HandleRequest("/privet/v3/traits", "{}"));
733
734 cloud_.NotifyOnTraitDefsChanged();
735
Vitaly Buka3e860992016-02-10 14:01:46 -0800736 EXPECT_JSON_EQ(R"({"traits": {"test": {}}, "fingerprint": "2"})",
Alex Vakulenko551a82b2015-12-07 14:46:12 -0800737 HandleRequest("/privet/v3/traits", "{}"));
738}
739
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800740TEST_F(PrivetHandlerTestWithAuth, Components) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800741 EXPECT_JSON_EQ(R"({"components": {"test": {}}, "fingerprint": "1"})",
Alex Vakulenko551a82b2015-12-07 14:46:12 -0800742 HandleRequest("/privet/v3/components", "{}"));
743
744 cloud_.NotifyOnComponentTreeChanged();
745
Vitaly Buka3e860992016-02-10 14:01:46 -0800746 EXPECT_JSON_EQ(R"({"components": {"test": {}}, "fingerprint": "2"})",
Alex Vakulenko551a82b2015-12-07 14:46:12 -0800747 HandleRequest("/privet/v3/components", "{}"));
748
749 // State change will also change the components fingerprint.
750 cloud_.NotifyOnStateChanged();
751
Vitaly Buka3e860992016-02-10 14:01:46 -0800752 EXPECT_JSON_EQ(R"({"components": {"test": {}}, "fingerprint": "3"})",
Alex Vakulenko551a82b2015-12-07 14:46:12 -0800753 HandleRequest("/privet/v3/components", "{}"));
754}
755
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800756TEST_F(PrivetHandlerTestWithAuth, ComponentsWithFiltersAndPaths) {
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800757 const char kComponents[] = R"({
758 "comp1": {
759 "traits": ["a", "b"],
760 "state": {
761 "a" : {
762 "prop": 1
763 }
764 },
765 "components": {
766 "comp2": {
767 "traits": ["c"],
768 "components": {
769 "comp4": {
770 "traits": ["d"]
771 }
772 }
773 },
774 "comp3": {
775 "traits": ["e"]
776 }
777 }
778 }
779 })";
780 base::DictionaryValue components;
781 LoadTestJson(kComponents, &components);
782 EXPECT_CALL(cloud_, FindComponent(_, _)).WillRepeatedly(Return(nullptr));
783 EXPECT_CALL(cloud_, GetComponents()).WillRepeatedly(ReturnRef(components));
784 const char kExpected1[] = R"({
785 "components": {
786 "comp1": {
787 "state": {
788 "a" : {
789 "prop": 1
790 }
791 }
792 }
793 },
794 "fingerprint": "1"
795 })";
796 EXPECT_JSON_EQ(kExpected1, HandleRequest("/privet/v3/components",
Vitaly Buka3e860992016-02-10 14:01:46 -0800797 R"({"filter":["state"]})"));
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800798
799 const char kExpected2[] = R"({
800 "components": {
801 "comp1": {
802 "traits": ["a", "b"]
803 }
804 },
805 "fingerprint": "1"
806 })";
807 EXPECT_JSON_EQ(kExpected2, HandleRequest("/privet/v3/components",
Vitaly Buka3e860992016-02-10 14:01:46 -0800808 R"({"filter":["traits"]})"));
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800809
810 const char kExpected3[] = R"({
811 "components": {
812 "comp1": {
813 "components": {
814 "comp2": {
815 "components": {
816 "comp4": {}
817 }
818 },
819 "comp3": {}
820 }
821 }
822 },
823 "fingerprint": "1"
824 })";
825 EXPECT_JSON_EQ(kExpected3, HandleRequest("/privet/v3/components",
Vitaly Buka3e860992016-02-10 14:01:46 -0800826 R"({"filter":["components"]})"));
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800827
828 const char kExpected4[] = R"({
829 "components": {
830 "comp1": {
831 "traits": ["a", "b"],
832 "state": {
833 "a" : {
834 "prop": 1
835 }
836 },
837 "components": {
838 "comp2": {
839 "traits": ["c"],
840 "components": {
841 "comp4": {
842 "traits": ["d"]
843 }
844 }
845 },
846 "comp3": {
847 "traits": ["e"]
848 }
849 }
850 }
851 },
852 "fingerprint": "1"
853 })";
Vitaly Buka3e860992016-02-10 14:01:46 -0800854 EXPECT_JSON_EQ(
855 kExpected4,
856 HandleRequest("/privet/v3/components",
857 R"({"filter":["traits", "components", "state"]})"));
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800858
859 const base::DictionaryValue* comp2 = nullptr;
860 ASSERT_TRUE(components.GetDictionary("comp1.components.comp2", &comp2));
Vitaly Buka34668e72015-12-15 14:46:47 -0800861 EXPECT_CALL(cloud_, FindComponent("comp1.comp2", _)).WillOnce(Return(comp2));
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800862
863 const char kExpected5[] = R"({
864 "components": {
865 "comp2": {
866 "traits": ["c"],
867 "components": {
868 "comp4": {
869 "traits": ["d"]
870 }
871 }
872 }
873 },
874 "fingerprint": "1"
875 })";
Vitaly Buka34668e72015-12-15 14:46:47 -0800876 EXPECT_JSON_EQ(
877 kExpected5,
878 HandleRequest(
879 "/privet/v3/components",
Vitaly Buka3e860992016-02-10 14:01:46 -0800880 R"({"path":"comp1.comp2", "filter":["traits", "components"]})"));
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800881
882 auto error_handler = [](ErrorPtr* error) -> const base::DictionaryValue* {
Vitaly Buka0dbbf602016-01-22 11:38:37 -0800883 return Error::AddTo(error, FROM_HERE, "componentNotFound", "");
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800884 };
885 EXPECT_CALL(cloud_, FindComponent("comp7", _))
886 .WillOnce(WithArgs<1>(Invoke(error_handler)));
887
888 EXPECT_PRED2(
Vitaly Buka34668e72015-12-15 14:46:47 -0800889 IsEqualError, CodeWithReason(500, "componentNotFound"),
890 HandleRequest("/privet/v3/components",
Vitaly Buka3e860992016-02-10 14:01:46 -0800891 R"({"path":"comp7", "filter":["traits", "components"]})"));
Alex Vakulenko3eb52e72015-12-14 15:34:08 -0800892}
893
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800894TEST_F(PrivetHandlerTestWithAuth, CommandsExecute) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800895 const char kInput[] = R"({"name": "test"})";
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700896 base::DictionaryValue command;
897 LoadTestJson(kInput, &command);
Vitaly Buka3e860992016-02-10 14:01:46 -0800898 LoadTestJson(R"({"id":"5"})", &command);
Vitaly Buka74763422015-10-11 00:39:52 -0700899 EXPECT_CALL(cloud_, AddCommand(_, _, _))
900 .WillOnce(WithArgs<2>(Invoke(
901 [&command](const CloudDelegate::CommandDoneCallback& callback) {
902 callback.Run(command, nullptr);
903 })));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700904
Vitaly Buka3e860992016-02-10 14:01:46 -0800905 EXPECT_JSON_EQ(R"({"name":"test", "id":"5"})",
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800906 HandleRequest("/privet/v3/commands/execute", kInput));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700907}
908
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800909TEST_F(PrivetHandlerTestWithAuth, CommandsStatus) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800910 const char kInput[] = R"({"id": "5"})";
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700911 base::DictionaryValue command;
912 LoadTestJson(kInput, &command);
Vitaly Buka3e860992016-02-10 14:01:46 -0800913 LoadTestJson(R"({"name":"test"})", &command);
Vitaly Buka74763422015-10-11 00:39:52 -0700914 EXPECT_CALL(cloud_, GetCommand(_, _, _))
915 .WillOnce(WithArgs<2>(Invoke(
916 [&command](const CloudDelegate::CommandDoneCallback& callback) {
917 callback.Run(command, nullptr);
918 })));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700919
Vitaly Buka3e860992016-02-10 14:01:46 -0800920 EXPECT_JSON_EQ(R"({"name":"test", "id":"5"})",
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800921 HandleRequest("/privet/v3/commands/status", kInput));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700922
Vitaly Buka0801a1f2015-08-14 10:03:46 -0700923 ErrorPtr error;
Vitaly Buka48a86692016-01-21 17:15:58 -0800924 Error::AddTo(&error, FROM_HERE, "notFound", "");
Vitaly Buka74763422015-10-11 00:39:52 -0700925 EXPECT_CALL(cloud_, GetCommand(_, _, _))
926 .WillOnce(WithArgs<2>(
927 Invoke([&error](const CloudDelegate::CommandDoneCallback& callback) {
928 callback.Run({}, std::move(error));
929 })));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700930
931 EXPECT_PRED2(IsEqualError, CodeWithReason(404, "notFound"),
Vitaly Buka3e860992016-02-10 14:01:46 -0800932 HandleRequest("/privet/v3/commands/status", R"({"id": "15"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700933}
934
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800935TEST_F(PrivetHandlerTestWithAuth, CommandsCancel) {
Vitaly Buka3e860992016-02-10 14:01:46 -0800936 const char kExpected[] = R"({"id": "5", "name":"test", "state":"cancelled"})";
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700937 base::DictionaryValue command;
938 LoadTestJson(kExpected, &command);
Vitaly Buka74763422015-10-11 00:39:52 -0700939 EXPECT_CALL(cloud_, CancelCommand(_, _, _))
940 .WillOnce(WithArgs<2>(Invoke(
941 [&command](const CloudDelegate::CommandDoneCallback& callback) {
942 callback.Run(command, nullptr);
943 })));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700944
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800945 EXPECT_JSON_EQ(kExpected,
Vitaly Buka3e860992016-02-10 14:01:46 -0800946 HandleRequest("/privet/v3/commands/cancel", R"({"id": "8"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700947
Vitaly Buka0801a1f2015-08-14 10:03:46 -0700948 ErrorPtr error;
Vitaly Buka48a86692016-01-21 17:15:58 -0800949 Error::AddTo(&error, FROM_HERE, "notFound", "");
Vitaly Buka74763422015-10-11 00:39:52 -0700950 EXPECT_CALL(cloud_, CancelCommand(_, _, _))
951 .WillOnce(WithArgs<2>(
952 Invoke([&error](const CloudDelegate::CommandDoneCallback& callback) {
953 callback.Run({}, std::move(error));
954 })));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700955
956 EXPECT_PRED2(IsEqualError, CodeWithReason(404, "notFound"),
Vitaly Buka3e860992016-02-10 14:01:46 -0800957 HandleRequest("/privet/v3/commands/cancel", R"({"id": "11"})"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700958}
959
Vitaly Buka2d24e0e2015-12-10 14:56:37 -0800960TEST_F(PrivetHandlerTestWithAuth, CommandsList) {
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700961 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800962 "commands" : [
963 {"id":"5", "state":"cancelled"},
964 {"id":"15", "state":"inProgress"}
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700965 ]})";
966
967 base::DictionaryValue commands;
968 LoadTestJson(kExpected, &commands);
969
Vitaly Buka74763422015-10-11 00:39:52 -0700970 EXPECT_CALL(cloud_, ListCommands(_, _))
971 .WillOnce(WithArgs<1>(Invoke(
972 [&commands](const CloudDelegate::CommandDoneCallback& callback) {
973 callback.Run(commands, nullptr);
974 })));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700975
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800976 EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/commands/list", "{}"));
Vitaly Buka7ce499f2015-06-09 08:04:11 -0700977}
978
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -0800979class PrivetHandlerCheckForUpdatesTest : public PrivetHandlerTestWithAuth {};
980
981TEST_F(PrivetHandlerCheckForUpdatesTest, NoInput) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -0800982 EXPECT_CALL(device_, GetHttpRequestTimeout())
983 .WillOnce(Return(base::TimeDelta::Max()));
Alex Vakulenkod91d6252015-12-05 17:14:39 -0800984 cloud_.NotifyOnTraitDefsChanged();
985 cloud_.NotifyOnComponentTreeChanged();
Alex Vakulenko551a82b2015-12-07 14:46:12 -0800986 cloud_.NotifyOnStateChanged();
Alex Vakulenkoefee3a22015-11-17 15:08:38 -0800987 const char kInput[] = "{}";
988 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -0800989 "commandsFingerprint": "2",
990 "stateFingerprint": "2",
991 "traitsFingerprint": "2",
992 "componentsFingerprint": "3"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -0800993 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -0800994 EXPECT_JSON_EQ(kExpected,
995 HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -0800996 EXPECT_EQ(1, GetResponseCount());
997}
998
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -0800999TEST_F(PrivetHandlerCheckForUpdatesTest, AlreadyChanged) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001000 EXPECT_CALL(device_, GetHttpRequestTimeout())
1001 .WillOnce(Return(base::TimeDelta::Max()));
Alex Vakulenkod91d6252015-12-05 17:14:39 -08001002 cloud_.NotifyOnTraitDefsChanged();
1003 cloud_.NotifyOnComponentTreeChanged();
Alex Vakulenko551a82b2015-12-07 14:46:12 -08001004 cloud_.NotifyOnStateChanged();
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001005 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001006 "commandsFingerprint": "1",
1007 "stateFingerprint": "1",
1008 "traitsFingerprint": "1",
1009 "componentsFingerprint": "1"
Alex Vakulenkof9691322015-12-07 14:34:48 -08001010 })";
1011 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001012 "commandsFingerprint": "2",
1013 "stateFingerprint": "2",
1014 "traitsFingerprint": "2",
1015 "componentsFingerprint": "3"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001016 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001017 EXPECT_JSON_EQ(kExpected,
1018 HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001019 EXPECT_EQ(1, GetResponseCount());
1020}
1021
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001022TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollCommands) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001023 EXPECT_CALL(device_, GetHttpRequestTimeout())
1024 .WillOnce(Return(base::TimeDelta::Max()));
1025 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001026 "commandsFingerprint": "1",
1027 "stateFingerprint": "1",
1028 "traitsFingerprint": "1",
1029 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001030 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001031 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001032 EXPECT_EQ(0, GetResponseCount());
Alex Vakulenkod91d6252015-12-05 17:14:39 -08001033 cloud_.NotifyOnTraitDefsChanged();
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001034 EXPECT_EQ(1, GetResponseCount());
1035 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001036 "commandsFingerprint": "2",
1037 "stateFingerprint": "1",
1038 "traitsFingerprint": "2",
1039 "componentsFingerprint": "1"
Alex Vakulenko551a82b2015-12-07 14:46:12 -08001040 })";
1041 EXPECT_JSON_EQ(kExpected, GetResponse());
1042}
1043
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001044TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollTraits) {
Alex Vakulenko551a82b2015-12-07 14:46:12 -08001045 EXPECT_CALL(device_, GetHttpRequestTimeout())
1046 .WillOnce(Return(base::TimeDelta::Max()));
1047 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001048 "commandsFingerprint": "1",
1049 "stateFingerprint": "1",
1050 "traitsFingerprint": "1",
1051 "componentsFingerprint": "1"
Alex Vakulenko551a82b2015-12-07 14:46:12 -08001052 })";
1053 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
1054 EXPECT_EQ(0, GetResponseCount());
1055 cloud_.NotifyOnTraitDefsChanged();
1056 EXPECT_EQ(1, GetResponseCount());
1057 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001058 "commandsFingerprint": "2",
1059 "stateFingerprint": "1",
1060 "traitsFingerprint": "2",
1061 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001062 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001063 EXPECT_JSON_EQ(kExpected, GetResponse());
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001064}
1065
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001066TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollState) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001067 EXPECT_CALL(device_, GetHttpRequestTimeout())
1068 .WillOnce(Return(base::TimeDelta::Max()));
1069 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001070 "commandsFingerprint": "1",
1071 "stateFingerprint": "1",
1072 "traitsFingerprint": "1",
1073 "componentsFingerprint": "1"
Alex Vakulenko551a82b2015-12-07 14:46:12 -08001074 })";
1075 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
1076 EXPECT_EQ(0, GetResponseCount());
1077 cloud_.NotifyOnStateChanged();
1078 EXPECT_EQ(1, GetResponseCount());
1079 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001080 "commandsFingerprint": "1",
1081 "stateFingerprint": "2",
1082 "traitsFingerprint": "1",
1083 "componentsFingerprint": "2"
Alex Vakulenko551a82b2015-12-07 14:46:12 -08001084 })";
1085 EXPECT_JSON_EQ(kExpected, GetResponse());
1086}
1087
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001088TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollComponents) {
Alex Vakulenko551a82b2015-12-07 14:46:12 -08001089 EXPECT_CALL(device_, GetHttpRequestTimeout())
1090 .WillOnce(Return(base::TimeDelta::Max()));
1091 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001092 "commandsFingerprint": "1",
1093 "stateFingerprint": "1",
1094 "traitsFingerprint": "1",
1095 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001096 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001097 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001098 EXPECT_EQ(0, GetResponseCount());
Alex Vakulenkod91d6252015-12-05 17:14:39 -08001099 cloud_.NotifyOnComponentTreeChanged();
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001100 EXPECT_EQ(1, GetResponseCount());
1101 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001102 "commandsFingerprint": "1",
1103 "stateFingerprint": "1",
1104 "traitsFingerprint": "1",
1105 "componentsFingerprint": "2"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001106 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001107 EXPECT_JSON_EQ(kExpected, GetResponse());
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001108}
1109
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001110TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollIgnoreTraits) {
Alex Vakulenkof9691322015-12-07 14:34:48 -08001111 EXPECT_CALL(device_, GetHttpRequestTimeout())
1112 .WillOnce(Return(base::TimeDelta::Max()));
1113 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001114 "stateFingerprint": "1",
1115 "componentsFingerprint": "1"
Alex Vakulenkof9691322015-12-07 14:34:48 -08001116 })";
1117 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
1118 EXPECT_EQ(0, GetResponseCount());
1119 cloud_.NotifyOnTraitDefsChanged();
1120 EXPECT_EQ(0, GetResponseCount());
1121 cloud_.NotifyOnComponentTreeChanged();
1122 EXPECT_EQ(1, GetResponseCount());
1123 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001124 "commandsFingerprint": "2",
1125 "stateFingerprint": "1",
1126 "traitsFingerprint": "2",
1127 "componentsFingerprint": "2"
Alex Vakulenkof9691322015-12-07 14:34:48 -08001128 })";
1129 EXPECT_JSON_EQ(kExpected, GetResponse());
1130}
1131
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001132TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollIgnoreState) {
Alex Vakulenkof9691322015-12-07 14:34:48 -08001133 EXPECT_CALL(device_, GetHttpRequestTimeout())
1134 .WillOnce(Return(base::TimeDelta::Max()));
1135 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001136 "commandsFingerprint": "1",
1137 "traitsFingerprint": "1"
Alex Vakulenkof9691322015-12-07 14:34:48 -08001138 })";
1139 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
1140 EXPECT_EQ(0, GetResponseCount());
1141 cloud_.NotifyOnStateChanged();
1142 EXPECT_EQ(0, GetResponseCount());
1143 cloud_.NotifyOnComponentTreeChanged();
1144 EXPECT_EQ(0, GetResponseCount());
1145 cloud_.NotifyOnTraitDefsChanged();
1146 EXPECT_EQ(1, GetResponseCount());
1147 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001148 "commandsFingerprint": "2",
1149 "stateFingerprint": "2",
1150 "traitsFingerprint": "2",
1151 "componentsFingerprint": "3"
Alex Vakulenkof9691322015-12-07 14:34:48 -08001152 })";
1153 EXPECT_JSON_EQ(kExpected, GetResponse());
1154}
1155
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001156TEST_F(PrivetHandlerCheckForUpdatesTest, InstantTimeout) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001157 EXPECT_CALL(device_, GetHttpRequestTimeout())
1158 .WillOnce(Return(base::TimeDelta::Max()));
1159 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001160 "commandsFingerprint": "1",
1161 "stateFingerprint": "1",
1162 "traitsFingerprint": "1",
1163 "componentsFingerprint": "1",
1164 "waitTimeout": 0
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001165 })";
1166 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001167 "commandsFingerprint": "1",
1168 "stateFingerprint": "1",
1169 "traitsFingerprint": "1",
1170 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001171 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001172 EXPECT_JSON_EQ(kExpected,
1173 HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001174}
1175
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001176TEST_F(PrivetHandlerCheckForUpdatesTest, UserTimeout) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001177 EXPECT_CALL(device_, GetHttpRequestTimeout())
1178 .WillOnce(Return(base::TimeDelta::Max()));
1179 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001180 "commandsFingerprint": "1",
1181 "stateFingerprint": "1",
1182 "traitsFingerprint": "1",
1183 "componentsFingerprint": "1",
1184 "waitTimeout": 3
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001185 })";
1186 base::Closure callback;
1187 EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(3)))
1188 .WillOnce(SaveArg<1>(&callback));
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001189 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001190 EXPECT_EQ(0, GetResponseCount());
1191 callback.Run();
1192 EXPECT_EQ(1, GetResponseCount());
1193 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001194 "commandsFingerprint": "1",
1195 "stateFingerprint": "1",
1196 "traitsFingerprint": "1",
1197 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001198 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001199 EXPECT_JSON_EQ(kExpected, GetResponse());
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001200}
1201
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001202TEST_F(PrivetHandlerCheckForUpdatesTest, ServerTimeout) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001203 EXPECT_CALL(device_, GetHttpRequestTimeout())
1204 .WillOnce(Return(base::TimeDelta::FromMinutes(1)));
1205 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001206 "commandsFingerprint": "1",
1207 "stateFingerprint": "1",
1208 "traitsFingerprint": "1",
1209 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001210 })";
1211 base::Closure callback;
1212 EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(50)))
1213 .WillOnce(SaveArg<1>(&callback));
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001214 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001215 EXPECT_EQ(0, GetResponseCount());
1216 callback.Run();
1217 EXPECT_EQ(1, GetResponseCount());
1218 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001219 "commandsFingerprint": "1",
1220 "stateFingerprint": "1",
1221 "traitsFingerprint": "1",
1222 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001223 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001224 EXPECT_JSON_EQ(kExpected, GetResponse());
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001225}
1226
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001227TEST_F(PrivetHandlerCheckForUpdatesTest, VeryShortServerTimeout) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001228 EXPECT_CALL(device_, GetHttpRequestTimeout())
1229 .WillOnce(Return(base::TimeDelta::FromSeconds(5)));
1230 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001231 "commandsFingerprint": "1",
1232 "stateFingerprint": "1",
1233 "traitsFingerprint": "1",
1234 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001235 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001236 EXPECT_JSON_EQ(kInput, HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001237 EXPECT_EQ(1, GetResponseCount());
1238}
1239
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001240TEST_F(PrivetHandlerCheckForUpdatesTest, ServerAndUserTimeout) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001241 EXPECT_CALL(device_, GetHttpRequestTimeout())
1242 .WillOnce(Return(base::TimeDelta::FromMinutes(1)));
1243 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001244 "commandsFingerprint": "1",
1245 "stateFingerprint": "1",
1246 "traitsFingerprint": "1",
1247 "componentsFingerprint": "1",
1248 "waitTimeout": 10
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001249 })";
1250 base::Closure callback;
1251 EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(10)))
1252 .WillOnce(SaveArg<1>(&callback));
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001253 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001254 EXPECT_EQ(0, GetResponseCount());
1255 callback.Run();
1256 EXPECT_EQ(1, GetResponseCount());
1257 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001258 "commandsFingerprint": "1",
1259 "stateFingerprint": "1",
1260 "traitsFingerprint": "1",
1261 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001262 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001263 EXPECT_JSON_EQ(kExpected, GetResponse());
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001264}
1265
Alex Vakulenkoe3cc2302015-12-07 15:26:26 -08001266TEST_F(PrivetHandlerCheckForUpdatesTest, ChangeBeforeTimeout) {
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001267 EXPECT_CALL(device_, GetHttpRequestTimeout())
1268 .WillOnce(Return(base::TimeDelta::Max()));
1269 const char kInput[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001270 "commandsFingerprint": "1",
1271 "stateFingerprint": "1",
1272 "traitsFingerprint": "1",
1273 "componentsFingerprint": "1",
1274 "waitTimeout": 10
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001275 })";
1276 base::Closure callback;
1277 EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(10)))
1278 .WillOnce(SaveArg<1>(&callback));
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001279 EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput));
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001280 EXPECT_EQ(0, GetResponseCount());
Alex Vakulenkod91d6252015-12-05 17:14:39 -08001281 cloud_.NotifyOnTraitDefsChanged();
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001282 EXPECT_EQ(1, GetResponseCount());
1283 const char kExpected[] = R"({
Vitaly Buka3e860992016-02-10 14:01:46 -08001284 "commandsFingerprint": "2",
1285 "stateFingerprint": "1",
1286 "traitsFingerprint": "2",
1287 "componentsFingerprint": "1"
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001288 })";
Alex Vakulenko29a11ca2015-12-07 14:43:04 -08001289 EXPECT_JSON_EQ(kExpected, GetResponse());
Alex Vakulenkoefee3a22015-11-17 15:08:38 -08001290 callback.Run();
1291 EXPECT_EQ(1, GetResponseCount());
1292}
1293
Vitaly Bukab6f015a2015-07-09 14:59:23 -07001294} // namespace privet
1295} // namespace weave