1 // Copyright 2020 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/ui/webui/settings/chromeos/ambient_mode_handler.h"
6
7 #include <memory>
8
9 #include "ash/public/cpp/ambient/common/ambient_settings.h"
10 #include "ash/public/cpp/ambient/fake_ambient_backend_controller_impl.h"
11 #include "ash/public/cpp/test/test_image_downloader.h"
12 #include "base/test/metrics/histogram_tester.h"
13 #include "chrome/test/base/browser_with_test_window_test.h"
14 #include "content/public/test/test_web_ui.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace chromeos {
18
19 namespace settings {
20
21 namespace {
22
23 const char kWebCallbackFunctionName[] = "cr.webUIListenerCallback";
24
25 class TestAmbientModeHandler : public AmbientModeHandler {
26 public:
27 TestAmbientModeHandler() = default;
28 ~TestAmbientModeHandler() override = default;
29
30 // Make public for testing.
31 using AmbientModeHandler::AllowJavascript;
32 using AmbientModeHandler::RegisterMessages;
33 using AmbientModeHandler::set_web_ui;
34 };
35
36 } // namespace
37
38 class AmbientModeHandlerTest : public testing::Test {
39 public:
40 AmbientModeHandlerTest() = default;
41 ~AmbientModeHandlerTest() override = default;
42
SetUp()43 void SetUp() override {
44 web_ui_ = std::make_unique<content::TestWebUI>();
45 handler_ = std::make_unique<TestAmbientModeHandler>();
46 handler_->set_web_ui(web_ui_.get());
47 handler_->RegisterMessages();
48 handler_->AllowJavascript();
49 fake_backend_controller_ =
50 std::make_unique<ash::FakeAmbientBackendControllerImpl>();
51 image_downloader_ = std::make_unique<ash::TestImageDownloader>();
52 }
53
web_ui()54 content::TestWebUI* web_ui() { return web_ui_.get(); }
55
histogram_tester() const56 const base::HistogramTester& histogram_tester() const {
57 return histogram_tester_;
58 }
59
SetTopicSource(ash::AmbientModeTopicSource topic_source)60 void SetTopicSource(ash::AmbientModeTopicSource topic_source) {
61 if (!handler_->settings_)
62 handler_->settings_ = ash::AmbientSettings();
63
64 handler_->settings_->topic_source = topic_source;
65 }
66
RequestSettings()67 void RequestSettings() {
68 base::ListValue args;
69 handler_->HandleRequestSettings(&args);
70 }
71
RequestAlbums(ash::AmbientModeTopicSource topic_source)72 void RequestAlbums(ash::AmbientModeTopicSource topic_source) {
73 base::ListValue args;
74 args.Append(static_cast<int>(topic_source));
75 handler_->HandleRequestAlbums(&args);
76 }
77
HandleSetSelectedAlbums(const base::ListValue * args)78 void HandleSetSelectedAlbums(const base::ListValue* args) {
79 handler_->HandleSetSelectedAlbums(args);
80 }
81
FetchSettings()82 void FetchSettings() {
83 handler_->RequestSettingsAndAlbums(/*topic_source=*/base::nullopt);
84 }
85
UpdateSettings()86 void UpdateSettings() {
87 if (!handler_->settings_)
88 handler_->settings_ = ash::AmbientSettings();
89
90 handler_->UpdateSettings();
91 }
92
HasPendingFetchRequestAtHandler() const93 bool HasPendingFetchRequestAtHandler() const {
94 return handler_->has_pending_fetch_request_;
95 }
96
IsUpdateSettingsPendingAtHandler() const97 bool IsUpdateSettingsPendingAtHandler() const {
98 return handler_->is_updating_backend_;
99 }
100
HasPendingUpdatesAtHandler() const101 bool HasPendingUpdatesAtHandler() const {
102 return handler_->has_pending_updates_for_backend_;
103 }
104
GetFetchSettingsDelay()105 base::TimeDelta GetFetchSettingsDelay() {
106 return handler_->fetch_settings_retry_backoff_.GetTimeUntilRelease();
107 }
108
GetUpdateSettingsDelay()109 base::TimeDelta GetUpdateSettingsDelay() {
110 return handler_->update_settings_retry_backoff_.GetTimeUntilRelease();
111 }
112
FastForwardBy(base::TimeDelta time)113 void FastForwardBy(base::TimeDelta time) {
114 task_environment_.FastForwardBy(time);
115 }
116
IsFetchSettingsPendingAtBackend() const117 bool IsFetchSettingsPendingAtBackend() const {
118 return fake_backend_controller_->IsFetchSettingsAndAlbumsPending();
119 }
120
ReplyFetchSettingsAndAlbums(bool success)121 void ReplyFetchSettingsAndAlbums(bool success) {
122 fake_backend_controller_->ReplyFetchSettingsAndAlbums(success);
123 }
124
IsUpdateSettingsPendingAtBackend() const125 bool IsUpdateSettingsPendingAtBackend() const {
126 return fake_backend_controller_->IsUpdateSettingsPending();
127 }
128
ReplyUpdateSettings(bool success)129 void ReplyUpdateSettings(bool success) {
130 fake_backend_controller_->ReplyUpdateSettings(success);
131 }
132
BoolToString(bool x)133 std::string BoolToString(bool x) { return x ? "true" : "false"; }
134
VerifySettingsSent(ash::AmbientModeTopicSource topic_source,const std::string & temperature_unit)135 void VerifySettingsSent(ash::AmbientModeTopicSource topic_source,
136 const std::string& temperature_unit) {
137 EXPECT_EQ(2U, web_ui_->call_data().size());
138
139 // The call is structured such that the function name is the "web callback"
140 // name and the first argument is the name of the message being sent.
141 const auto& topic_source_call_data = *web_ui_->call_data().front();
142 const auto& temperature_unit_call_data = *web_ui_->call_data().back();
143
144 // Topic Source
145 EXPECT_EQ(kWebCallbackFunctionName, topic_source_call_data.function_name());
146 EXPECT_EQ("topic-source-changed",
147 topic_source_call_data.arg1()->GetString());
148 const base::DictionaryValue* dictionary = nullptr;
149 topic_source_call_data.arg2()->GetAsDictionary(&dictionary);
150 const base::Value* topic_source_value = dictionary->FindKey("topicSource");
151 EXPECT_EQ(static_cast<int>(topic_source), topic_source_value->GetInt());
152
153 // Temperature Unit
154 EXPECT_EQ(kWebCallbackFunctionName,
155 temperature_unit_call_data.function_name());
156 EXPECT_EQ("temperature-unit-changed",
157 temperature_unit_call_data.arg1()->GetString());
158 EXPECT_EQ(temperature_unit, temperature_unit_call_data.arg2()->GetString());
159 }
160
VerifyAlbumsSent(ash::AmbientModeTopicSource topic_source)161 void VerifyAlbumsSent(ash::AmbientModeTopicSource topic_source) {
162 // Art gallery has an extra call to update the topic source to Art gallery.
163 std::vector<std::unique_ptr<content::TestWebUI::CallData>>::size_type call_size =
164 topic_source == ash::AmbientModeTopicSource::kGooglePhotos ? 1U : 2U;
165 EXPECT_EQ(call_size, web_ui_->call_data().size());
166
167 if (topic_source == ash::AmbientModeTopicSource::kArtGallery) {
168 const auto& topic_source_call_data = *web_ui_->call_data().front();
169 const base::DictionaryValue* dictionary = nullptr;
170 topic_source_call_data.arg2()->GetAsDictionary(&dictionary);
171 const base::Value* topic_source_value =
172 dictionary->FindKey("topicSource");
173 EXPECT_EQ(static_cast<int>(topic_source), topic_source_value->GetInt());
174 }
175
176 const content::TestWebUI::CallData& call_data =
177 *web_ui_->call_data().back();
178
179 // The call is structured such that the function name is the "web callback"
180 // name and the first argument is the name of the message being sent.
181 EXPECT_EQ(kWebCallbackFunctionName, call_data.function_name());
182 EXPECT_EQ("albums-changed", call_data.arg1()->GetString());
183
184 // The test data is set in FakeAmbientBackendControllerImpl.
185 const base::DictionaryValue* dictionary = nullptr;
186 call_data.arg2()->GetAsDictionary(&dictionary);
187
188 const base::Value* topic_source_value = dictionary->FindKey("topicSource");
189 EXPECT_EQ(static_cast<int>(topic_source), topic_source_value->GetInt());
190
191 const base::Value* albums = dictionary->FindKey("albums");
192 EXPECT_EQ(2U, albums->GetList().size());
193
194 const base::DictionaryValue* album0;
195 albums->GetList()[0].GetAsDictionary(&album0);
196 EXPECT_EQ("0", album0->FindKey("albumId")->GetString());
197
198 const base::DictionaryValue* album1;
199 albums->GetList()[1].GetAsDictionary(&album1);
200 EXPECT_EQ("1", album1->FindKey("albumId")->GetString());
201
202 if (topic_source == ash::AmbientModeTopicSource::kGooglePhotos) {
203 EXPECT_EQ(false, album0->FindKey("checked")->GetBool());
204 EXPECT_EQ("album0", album0->FindKey("title")->GetString());
205
206 EXPECT_EQ(true, album1->FindKey("checked")->GetBool());
207 EXPECT_EQ("album1", album1->FindKey("title")->GetString());
208 } else {
209 EXPECT_EQ(true, album0->FindKey("checked")->GetBool());
210 EXPECT_EQ("art0", album0->FindKey("title")->GetString());
211
212 EXPECT_EQ(false, album1->FindKey("checked")->GetBool());
213 EXPECT_EQ("art1", album1->FindKey("title")->GetString());
214 }
215 }
216
217 private:
218 base::test::TaskEnvironment task_environment_{
219 base::test::TaskEnvironment::TimeSource::MOCK_TIME};
220 std::unique_ptr<content::TestWebUI> web_ui_;
221 std::unique_ptr<ash::FakeAmbientBackendControllerImpl>
222 fake_backend_controller_;
223 std::unique_ptr<ash::TestImageDownloader> image_downloader_;
224 std::unique_ptr<TestAmbientModeHandler> handler_;
225 base::HistogramTester histogram_tester_;
226 };
227
TEST_F(AmbientModeHandlerTest,TestSendTemperatureUnitAndTopicSource)228 TEST_F(AmbientModeHandlerTest, TestSendTemperatureUnitAndTopicSource) {
229 RequestSettings();
230 ReplyFetchSettingsAndAlbums(/*success=*/true);
231
232 // In FakeAmbientBackendControllerImpl, the |topic_source| is kGooglePhotos,
233 // the |temperature_unit| is kCelsius.
234 VerifySettingsSent(ash::AmbientModeTopicSource::kGooglePhotos, "celsius");
235 }
236
TEST_F(AmbientModeHandlerTest,TestSendAlbumsForGooglePhotos)237 TEST_F(AmbientModeHandlerTest, TestSendAlbumsForGooglePhotos) {
238 ash::AmbientModeTopicSource topic_source =
239 ash::AmbientModeTopicSource::kGooglePhotos;
240 RequestAlbums(topic_source);
241 ReplyFetchSettingsAndAlbums(/*success=*/true);
242 VerifyAlbumsSent(topic_source);
243 }
244
TEST_F(AmbientModeHandlerTest,TestSendAlbumsForArtGallery)245 TEST_F(AmbientModeHandlerTest, TestSendAlbumsForArtGallery) {
246 ash::AmbientModeTopicSource topic_source =
247 ash::AmbientModeTopicSource::kArtGallery;
248 RequestAlbums(topic_source);
249 ReplyFetchSettingsAndAlbums(/*success=*/true);
250 VerifyAlbumsSent(topic_source);
251 }
252
TEST_F(AmbientModeHandlerTest,TestFetchSettings)253 TEST_F(AmbientModeHandlerTest, TestFetchSettings) {
254 FetchSettings();
255 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
256
257 ReplyFetchSettingsAndAlbums(/*success=*/true);
258 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
259 }
260
TEST_F(AmbientModeHandlerTest,TestFetchSettingsFailedWillRetry)261 TEST_F(AmbientModeHandlerTest, TestFetchSettingsFailedWillRetry) {
262 FetchSettings();
263 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
264
265 ReplyFetchSettingsAndAlbums(/*success=*/false);
266 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
267
268 FastForwardBy(GetFetchSettingsDelay() * 1.5);
269 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
270 }
271
TEST_F(AmbientModeHandlerTest,TestFetchSettingsSecondRetryWillBackoff)272 TEST_F(AmbientModeHandlerTest, TestFetchSettingsSecondRetryWillBackoff) {
273 FetchSettings();
274 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
275
276 ReplyFetchSettingsAndAlbums(/*success=*/false);
277 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
278
279 base::TimeDelta delay1 = GetFetchSettingsDelay();
280 FastForwardBy(delay1 * 1.5);
281 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
282
283 ReplyFetchSettingsAndAlbums(/*success=*/false);
284 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
285
286 base::TimeDelta delay2 = GetFetchSettingsDelay();
287 EXPECT_GT(delay2, delay1);
288
289 FastForwardBy(delay2 * 1.5);
290 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
291 }
292
TEST_F(AmbientModeHandlerTest,TestFetchSettingsWillNotRetryMoreThanThreeTimes)293 TEST_F(AmbientModeHandlerTest,
294 TestFetchSettingsWillNotRetryMoreThanThreeTimes) {
295 FetchSettings();
296 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
297
298 ReplyFetchSettingsAndAlbums(/*success=*/false);
299 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
300
301 // 1st retry.
302 FastForwardBy(GetFetchSettingsDelay() * 1.5);
303 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
304
305 ReplyFetchSettingsAndAlbums(/*success=*/false);
306 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
307
308 // 2nd retry.
309 FastForwardBy(GetFetchSettingsDelay() * 1.5);
310 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
311
312 ReplyFetchSettingsAndAlbums(/*success=*/false);
313 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
314
315 // 3rd retry.
316 FastForwardBy(GetFetchSettingsDelay() * 1.5);
317 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
318
319 ReplyFetchSettingsAndAlbums(/*success=*/false);
320 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
321
322 // Will not retry.
323 FastForwardBy(GetFetchSettingsDelay() * 1.5);
324 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
325 }
326
TEST_F(AmbientModeHandlerTest,TestUpdateSettings)327 TEST_F(AmbientModeHandlerTest, TestUpdateSettings) {
328 UpdateSettings();
329 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
330 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
331 EXPECT_FALSE(HasPendingUpdatesAtHandler());
332
333 ReplyUpdateSettings(/*success=*/true);
334 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
335 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
336 EXPECT_FALSE(HasPendingUpdatesAtHandler());
337 }
338
TEST_F(AmbientModeHandlerTest,TestUpdateSettingsTwice)339 TEST_F(AmbientModeHandlerTest, TestUpdateSettingsTwice) {
340 UpdateSettings();
341 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
342 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
343 EXPECT_FALSE(HasPendingUpdatesAtHandler());
344
345 UpdateSettings();
346 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
347 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
348 EXPECT_TRUE(HasPendingUpdatesAtHandler());
349
350 ReplyUpdateSettings(/*success=*/true);
351 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
352 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
353 EXPECT_TRUE(HasPendingUpdatesAtHandler());
354
355 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
356 EXPECT_FALSE(HasPendingUpdatesAtHandler());
357 }
358
TEST_F(AmbientModeHandlerTest,TestUpdateSettingsFailedWillRetry)359 TEST_F(AmbientModeHandlerTest, TestUpdateSettingsFailedWillRetry) {
360 UpdateSettings();
361 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
362 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
363 EXPECT_FALSE(HasPendingUpdatesAtHandler());
364
365 ReplyUpdateSettings(/*success=*/false);
366 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
367 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
368 EXPECT_FALSE(HasPendingUpdatesAtHandler());
369
370 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
371 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
372 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
373 EXPECT_FALSE(HasPendingUpdatesAtHandler());
374 }
375
TEST_F(AmbientModeHandlerTest,TestUpdateSettingsSecondRetryWillBackoff)376 TEST_F(AmbientModeHandlerTest, TestUpdateSettingsSecondRetryWillBackoff) {
377 UpdateSettings();
378 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
379 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
380 EXPECT_FALSE(HasPendingUpdatesAtHandler());
381
382 ReplyUpdateSettings(/*success=*/false);
383 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
384 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
385 EXPECT_FALSE(HasPendingUpdatesAtHandler());
386
387 base::TimeDelta delay1 = GetUpdateSettingsDelay();
388 FastForwardBy(delay1 * 1.5);
389 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
390 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
391 EXPECT_FALSE(HasPendingUpdatesAtHandler());
392
393 ReplyUpdateSettings(/*success=*/false);
394 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
395 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
396 EXPECT_FALSE(HasPendingUpdatesAtHandler());
397
398 base::TimeDelta delay2 = GetUpdateSettingsDelay();
399 EXPECT_GT(delay2, delay1);
400
401 FastForwardBy(delay2 * 1.5);
402 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
403 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
404 EXPECT_FALSE(HasPendingUpdatesAtHandler());
405 }
406
TEST_F(AmbientModeHandlerTest,TestUpdateSettingsWillNotRetryMoreThanThreeTimes)407 TEST_F(AmbientModeHandlerTest,
408 TestUpdateSettingsWillNotRetryMoreThanThreeTimes) {
409 UpdateSettings();
410 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
411 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
412 EXPECT_FALSE(HasPendingUpdatesAtHandler());
413
414 ReplyUpdateSettings(/*success=*/false);
415 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
416 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
417 EXPECT_FALSE(HasPendingUpdatesAtHandler());
418
419 // 1st retry.
420 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
421 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
422 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
423 EXPECT_FALSE(HasPendingUpdatesAtHandler());
424
425 ReplyUpdateSettings(/*success=*/false);
426 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
427 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
428 EXPECT_FALSE(HasPendingUpdatesAtHandler());
429
430 // 2nd retry.
431 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
432 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
433 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
434 EXPECT_FALSE(HasPendingUpdatesAtHandler());
435
436 ReplyUpdateSettings(/*success=*/false);
437 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
438 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
439 EXPECT_FALSE(HasPendingUpdatesAtHandler());
440
441 // 3rd retry.
442 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
443 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
444 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
445 EXPECT_FALSE(HasPendingUpdatesAtHandler());
446
447 ReplyUpdateSettings(/*success=*/false);
448 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
449 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
450 EXPECT_FALSE(HasPendingUpdatesAtHandler());
451
452 // Will not retry.
453 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
454 EXPECT_FALSE(IsUpdateSettingsPendingAtBackend());
455 EXPECT_FALSE(IsUpdateSettingsPendingAtHandler());
456 EXPECT_FALSE(HasPendingUpdatesAtHandler());
457 }
458
TEST_F(AmbientModeHandlerTest,TestNoFetchRequestWhenUpdatingSettings)459 TEST_F(AmbientModeHandlerTest, TestNoFetchRequestWhenUpdatingSettings) {
460 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
461 UpdateSettings();
462 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
463
464 RequestSettings();
465 EXPECT_TRUE(HasPendingFetchRequestAtHandler());
466 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
467 }
468
TEST_F(AmbientModeHandlerTest,TestSendSettingsWhenUpdatedSettings)469 TEST_F(AmbientModeHandlerTest, TestSendSettingsWhenUpdatedSettings) {
470 // Simulate initial page request.
471 RequestSettings();
472 ReplyFetchSettingsAndAlbums(/*success=*/true);
473
474 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
475 SetTopicSource(ash::AmbientModeTopicSource::kArtGallery);
476 UpdateSettings();
477 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
478
479 RequestSettings();
480 EXPECT_TRUE(HasPendingFetchRequestAtHandler());
481 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
482
483 web_ui()->ClearTrackedCalls();
484 ReplyUpdateSettings(/*success=*/true);
485
486 // In FakeAmbientBackendControllerImpl, the |topic_source| is kGooglePhotos,
487 // the |temperature_unit| is kCelsius.
488 VerifySettingsSent(ash::AmbientModeTopicSource::kArtGallery, "celsius");
489 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
490 }
491
TEST_F(AmbientModeHandlerTest,TestSendAlbumsOfGooglePhotosWhenUpdatedSettings)492 TEST_F(AmbientModeHandlerTest,
493 TestSendAlbumsOfGooglePhotosWhenUpdatedSettings) {
494 // Simulate initial page request.
495 ash::AmbientModeTopicSource topic_source =
496 ash::AmbientModeTopicSource::kGooglePhotos;
497 RequestAlbums(topic_source);
498 ReplyFetchSettingsAndAlbums(/*success=*/true);
499 web_ui()->ClearTrackedCalls();
500
501 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
502 UpdateSettings();
503 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
504
505 RequestAlbums(topic_source);
506 EXPECT_TRUE(HasPendingFetchRequestAtHandler());
507 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
508
509 ReplyUpdateSettings(/*success=*/true);
510 VerifyAlbumsSent(topic_source);
511 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
512 }
513
TEST_F(AmbientModeHandlerTest,TestSendAlbumsOfArtGalleryWhenUpdatedSettings)514 TEST_F(AmbientModeHandlerTest, TestSendAlbumsOfArtGalleryWhenUpdatedSettings) {
515 // Simulate initial page request.
516 ash::AmbientModeTopicSource topic_source =
517 ash::AmbientModeTopicSource::kGooglePhotos;
518 RequestAlbums(topic_source);
519 ReplyFetchSettingsAndAlbums(/*success=*/true);
520 web_ui()->ClearTrackedCalls();
521
522 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
523 UpdateSettings();
524 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
525
526 RequestAlbums(topic_source);
527 EXPECT_TRUE(HasPendingFetchRequestAtHandler());
528 EXPECT_FALSE(IsFetchSettingsPendingAtBackend());
529
530 ReplyUpdateSettings(/*success=*/true);
531 VerifyAlbumsSent(topic_source);
532 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
533 }
534
TEST_F(AmbientModeHandlerTest,TestNotUpdateUIWhenFetechedSettings)535 TEST_F(AmbientModeHandlerTest, TestNotUpdateUIWhenFetechedSettings) {
536 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
537 RequestSettings();
538 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
539 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
540
541 UpdateSettings();
542 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
543 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
544
545 ReplyFetchSettingsAndAlbums(/*success=*/true);
546 EXPECT_EQ(0U, web_ui()->call_data().size());
547 }
548
TEST_F(AmbientModeHandlerTest,TestNotSendSettingsWhenFetechedSettings)549 TEST_F(AmbientModeHandlerTest, TestNotSendSettingsWhenFetechedSettings) {
550 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
551 RequestSettings();
552 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
553 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
554
555 UpdateSettings();
556 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
557 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
558
559 ReplyFetchSettingsAndAlbums(/*success=*/true);
560 EXPECT_EQ(0U, web_ui()->call_data().size());
561 }
562
TEST_F(AmbientModeHandlerTest,TestNotSendAlbumsWhenFetechedSettings)563 TEST_F(AmbientModeHandlerTest, TestNotSendAlbumsWhenFetechedSettings) {
564 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
565
566 ash::AmbientModeTopicSource topic_source =
567 ash::AmbientModeTopicSource::kGooglePhotos;
568 RequestAlbums(topic_source);
569 EXPECT_TRUE(IsFetchSettingsPendingAtBackend());
570 EXPECT_FALSE(HasPendingFetchRequestAtHandler());
571
572 UpdateSettings();
573 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
574 EXPECT_TRUE(IsUpdateSettingsPendingAtBackend());
575
576 ReplyFetchSettingsAndAlbums(/*success=*/true);
577 EXPECT_EQ(0U, web_ui()->call_data().size());
578 }
579
TEST_F(AmbientModeHandlerTest,TestSendSettingsWhenUpdateSettingsFailed)580 TEST_F(AmbientModeHandlerTest, TestSendSettingsWhenUpdateSettingsFailed) {
581 // Simulate initial page request.
582 RequestSettings();
583 ReplyFetchSettingsAndAlbums(/*success=*/true);
584
585 SetTopicSource(ash::AmbientModeTopicSource::kArtGallery);
586 UpdateSettings();
587 ReplyUpdateSettings(/*success=*/false);
588
589 // 1st retry.
590 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
591 ReplyUpdateSettings(/*success=*/false);
592
593 // 2nd retry.
594 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
595 ReplyUpdateSettings(/*success=*/false);
596
597 web_ui()->ClearTrackedCalls();
598 EXPECT_EQ(0U, web_ui()->call_data().size());
599
600 // 3rd retry.
601 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
602 ReplyUpdateSettings(/*success=*/false);
603 // In FakeAmbientBackendControllerImpl, the |topic_source| is kGooglePhotos,
604 // the |temperature_unit| is kCelsius.
605 VerifySettingsSent(ash::AmbientModeTopicSource::kGooglePhotos, "celsius");
606 }
607
TEST_F(AmbientModeHandlerTest,TestSendAlbumsOfGooglePhotosWhenUpdateSettingsFailed)608 TEST_F(AmbientModeHandlerTest,
609 TestSendAlbumsOfGooglePhotosWhenUpdateSettingsFailed) {
610 // Simulate initial page request.
611 ash::AmbientModeTopicSource topic_source =
612 ash::AmbientModeTopicSource::kGooglePhotos;
613 SetTopicSource(topic_source);
614 RequestAlbums(topic_source);
615 ReplyFetchSettingsAndAlbums(/*success=*/true);
616
617 UpdateSettings();
618 ReplyUpdateSettings(/*success=*/false);
619
620 // 1st retry.
621 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
622 ReplyUpdateSettings(/*success=*/false);
623
624 // 2nd retry.
625 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
626 ReplyUpdateSettings(/*success=*/false);
627
628 web_ui()->ClearTrackedCalls();
629 EXPECT_EQ(0U, web_ui()->call_data().size());
630
631 // 3rd retry.
632 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
633 ReplyUpdateSettings(/*success=*/false);
634 VerifyAlbumsSent(topic_source);
635 }
636
TEST_F(AmbientModeHandlerTest,TestSendAlbumsOfArtGalleryWhenUpdateSettingsFailed)637 TEST_F(AmbientModeHandlerTest,
638 TestSendAlbumsOfArtGalleryWhenUpdateSettingsFailed) {
639 // Simulate initial page request.
640 ash::AmbientModeTopicSource topic_source =
641 ash::AmbientModeTopicSource::kArtGallery;
642 SetTopicSource(topic_source);
643 RequestAlbums(topic_source);
644 ReplyFetchSettingsAndAlbums(/*success=*/true);
645
646 UpdateSettings();
647 ReplyUpdateSettings(/*success=*/false);
648
649 // 1st retry.
650 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
651 ReplyUpdateSettings(/*success=*/false);
652
653 // 2nd retry.
654 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
655 ReplyUpdateSettings(/*success=*/false);
656
657 web_ui()->ClearTrackedCalls();
658 EXPECT_EQ(0U, web_ui()->call_data().size());
659
660 // 3rd retry.
661 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
662 ReplyUpdateSettings(/*success=*/false);
663 VerifyAlbumsSent(topic_source);
664 }
665
666 // Test that there are two updates, the first update succeeded and the second
667 // update failed. When the second update failed, it will update UI to restore
668 // the latest successfully updated settings.
TEST_F(AmbientModeHandlerTest,TestSendSettingsWithCachedSettings)669 TEST_F(AmbientModeHandlerTest, TestSendSettingsWithCachedSettings) {
670 ash::AmbientModeTopicSource topic_source_google_photos =
671 ash::AmbientModeTopicSource::kGooglePhotos;
672 ash::AmbientModeTopicSource topic_source_art_gallery =
673 ash::AmbientModeTopicSource::kArtGallery;
674
675 // Simulate initial page request.
676 RequestSettings();
677 ReplyFetchSettingsAndAlbums(/*success=*/true);
678
679 // The first update.
680 SetTopicSource(topic_source_art_gallery);
681 UpdateSettings();
682 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
683
684 // There is the second change and pending update before retry.
685 SetTopicSource(topic_source_google_photos);
686 UpdateSettings();
687 EXPECT_TRUE(HasPendingUpdatesAtHandler());
688
689 // First update returns true and will start the second update.
690 ReplyUpdateSettings(/*success=*/true);
691 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
692 EXPECT_TRUE(IsUpdateSettingsPendingAtHandler());
693
694 ReplyUpdateSettings(/*success=*/false);
695
696 // 1st retry.
697 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
698 ReplyUpdateSettings(/*success=*/false);
699
700 // 2nd retry.
701 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
702 ReplyUpdateSettings(/*success=*/false);
703
704 web_ui()->ClearTrackedCalls();
705 EXPECT_EQ(0U, web_ui()->call_data().size());
706
707 // 3rd retry.
708 FastForwardBy(GetUpdateSettingsDelay() * 1.5);
709 ReplyUpdateSettings(/*success=*/false);
710 VerifySettingsSent(topic_source_art_gallery, "celsius");
711 }
712
TEST_F(AmbientModeHandlerTest,TestAlbumNumbersAreRecorded)713 TEST_F(AmbientModeHandlerTest, TestAlbumNumbersAreRecorded) {
714 RequestSettings();
715 ReplyFetchSettingsAndAlbums(/*success=*/true);
716
717 base::ListValue args;
718 base::DictionaryValue dictionary;
719 ash::AmbientModeTopicSource topic_source =
720 ash::AmbientModeTopicSource::kGooglePhotos;
721 dictionary.SetKey("topicSource", base::Value(static_cast<int>(topic_source)));
722
723 base::Value albums(base::Value::Type::LIST);
724 base::Value album(base::Value::Type::DICTIONARY);
725 album.SetKey("albumId", base::Value("0"));
726 albums.Append(std::move(album));
727 dictionary.SetKey("albums", std::move(albums));
728
729 args.Append(std::move(dictionary));
730 HandleSetSelectedAlbums(&args);
731
732 histogram_tester().ExpectTotalCount("Ash.AmbientMode.TotalNumberOfAlbums",
733 /*count=*/1);
734 histogram_tester().ExpectTotalCount("Ash.AmbientMode.SelectedNumberOfAlbums",
735 /*count=*/1);
736 }
737
738 } // namespace settings
739 } // namespace chromeos
740