File: reboot_notification_controller_unittest.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (278 lines) | stat: -rw-r--r-- 11,820 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/ash/device_scheduled_reboot/reboot_notification_controller.h"

#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/notifications/notification_handler.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "google_apis/gaia/gaia_id.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::message_center::Notification;

namespace {
constexpr char kEmailId[] = "test@example.com";
constexpr GaiaId::Literal kGaiaId("12345");
constexpr char kKioskEmailId[] = "test-kiosk@example.com";
constexpr GaiaId::Literal kKioskGaiaId("6789");
constexpr base::Time::Exploded kRebootTime2022Feb2At1520 = {.year = 2022,
                                                            .month = 2,
                                                            .day_of_week = 4,
                                                            .day_of_month = 2,
                                                            .hour = 15,
                                                            .minute = 20};
constexpr base::Time::Exploded kRebootTime2023May15At1115 = {.year = 2023,
                                                             .month = 5,
                                                             .day_of_week = 4,
                                                             .day_of_month = 15,
                                                             .hour = 11,
                                                             .minute = 15};

class ClickCounter {
 public:
  void ButtonClickCallback() { ++clicks; }
  int clicks = 0;
  base::WeakPtrFactory<ClickCounter> weak_ptr_factory_{this};
};
}  // namespace

class RebootNotificationControllerTest : public testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(profile_manager_.SetUp());

    std::unique_ptr<ash::FakeChromeUserManager> fake_user_manager =
        std::make_unique<ash::FakeChromeUserManager>();
    fake_user_manager_ = fake_user_manager.get();
    scoped_user_manager_ = std::make_unique<user_manager::ScopedUserManager>(
        std::move(fake_user_manager));
  }

 protected:
  std::optional<Notification> GetPendingRebootNotification() const {
    return display_service_tester_->GetNotification(
        ash::kPendingRebootNotificationId);
  }

  std::optional<Notification> GetPostRebootNotification() const {
    return display_service_tester_->GetNotification(
        ash::kPostRebootNotificationId);
  }

  int GetTransientNotificationCount() const {
    return display_service_tester_
        ->GetDisplayedNotificationsForType(NotificationHandler::Type::TRANSIENT)
        .size();
  }

  void CreateFakeUser(AccountId account_id) {
    profile_ = profile_manager_.CreateTestingProfile(account_id.GetUserEmail());
    fake_user_manager_->AddUser(account_id);
    display_service_tester_ =
        std::make_unique<NotificationDisplayServiceTester>(profile_);
  }

  void CreateFakeKioskUser(AccountId account_id) {
    profile_ = profile_manager_.CreateTestingProfile(account_id.GetUserEmail());
    fake_user_manager_->AddKioskChromeAppUser(account_id);
    display_service_tester_ =
        std::make_unique<NotificationDisplayServiceTester>(profile_);
  }

  void CreateFakeMgsUser(AccountId account_id) {
    profile_ = profile_manager_.CreateTestingProfile(account_id.GetUserEmail());
    fake_user_manager_->AddPublicAccountUser(account_id);
    display_service_tester_ =
        std::make_unique<NotificationDisplayServiceTester>(profile_);
  }

  void LoginFakeUser(AccountId account_id) {
    fake_user_manager_->LoginUser(account_id, true);
    EXPECT_EQ(ProfileManager::GetActiveUserProfile(), profile_);
  }

  content::BrowserTaskEnvironment test_environment_{
      base::test::TaskEnvironment::MainThreadType::UI};
  TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()};
  raw_ptr<TestingProfile> profile_ = nullptr;

  raw_ptr<ash::FakeChromeUserManager, DanglingUntriaged> fake_user_manager_ =
      nullptr;
  std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
  std::unique_ptr<NotificationDisplayServiceTester> display_service_tester_;
  RebootNotificationController notification_controller_;
};

TEST_F(RebootNotificationControllerTest, UserSessionShowsNotification) {
  AccountId account_id = AccountId::FromUserEmailGaiaId(kEmailId, kGaiaId);
  CreateFakeUser(account_id);
  base::Time reboot_time;
  ASSERT_TRUE(
      base::Time::FromLocalExploded(kRebootTime2022Feb2At1520, &reboot_time));

  // User is not logged in. Don't show notifications.
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::NullCallback());
  EXPECT_EQ(std::nullopt, GetPendingRebootNotification());
  notification_controller_.MaybeShowPostRebootNotification();
  EXPECT_EQ(std::nullopt, GetPostRebootNotification());

  // Log in user and show pending reboot notification.
  LoginFakeUser(account_id);
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::NullCallback());
  EXPECT_NE(std::nullopt, GetPendingRebootNotification());
  EXPECT_EQ(GetPendingRebootNotification()->message(),
            u"Your administrator will restart your device at 3:20\u202fPM on "
            u"Feb 2, 2022");

  // Show post reboot notification.
  notification_controller_.MaybeShowPostRebootNotification();
  EXPECT_NE(std::nullopt, GetPostRebootNotification());
  EXPECT_EQ(GetPostRebootNotification()->title(),
            u"Your administrator restarted your device");
}

TEST_F(RebootNotificationControllerTest, UserSessionNotificationChanged) {
  AccountId account_id = AccountId::FromUserEmailGaiaId(kEmailId, kGaiaId);
  CreateFakeUser(account_id);
  base::Time reboot_time1, reboot_time2;
  ASSERT_TRUE(
      base::Time::FromLocalExploded(kRebootTime2022Feb2At1520, &reboot_time1));
  ASSERT_TRUE(
      base::Time::FromLocalExploded(kRebootTime2023May15At1115, &reboot_time2));

  // User is not logged in. Don't show notification.
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time1, base::NullCallback());
  EXPECT_EQ(std::nullopt, GetPendingRebootNotification());
  EXPECT_EQ(GetTransientNotificationCount(), 0);

  // Log in user and show notification.
  LoginFakeUser(account_id);
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time1, base::NullCallback());
  EXPECT_NE(std::nullopt, GetPendingRebootNotification());
  EXPECT_EQ(GetPendingRebootNotification()->message(),
            u"Your administrator will restart your device at 3:20\u202fPM on "
            u"Feb 2, 2022");
  EXPECT_EQ(GetTransientNotificationCount(), 1);

  // Change reboot time. Close old notification and show new one.
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time2, base::NullCallback());
  EXPECT_NE(std::nullopt, GetPendingRebootNotification());
  EXPECT_EQ(
      GetPendingRebootNotification()->message(),
      u"Your administrator will restart your device at 11:15\u202fAM on May "
      u"15, 2023");
  EXPECT_EQ(GetTransientNotificationCount(), 1);
}

TEST_F(RebootNotificationControllerTest, ManagedGuestSessionShowsNotification) {
  AccountId account_id = AccountId::FromUserEmailGaiaId(kEmailId, kGaiaId);
  CreateFakeMgsUser(account_id);
  base::Time reboot_time;
  ASSERT_TRUE(
      base::Time::FromLocalExploded(kRebootTime2022Feb2At1520, &reboot_time));

  // User is not logged in. Don't show notification.
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::NullCallback());
  EXPECT_EQ(std::nullopt, GetPendingRebootNotification());
  notification_controller_.MaybeShowPostRebootNotification();
  EXPECT_EQ(std::nullopt, GetPostRebootNotification());

  // Log in user and show notification.
  LoginFakeUser(account_id);
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::NullCallback());
  EXPECT_NE(std::nullopt, GetPendingRebootNotification());
  EXPECT_EQ(GetPendingRebootNotification()->message(),
            u"Your administrator will restart your device at 3:20\u202fPM on "
            u"Feb 2, 2022");

  // Show post reboot notification.
  notification_controller_.MaybeShowPostRebootNotification();
  EXPECT_NE(std::nullopt, GetPostRebootNotification());
  EXPECT_EQ(GetPostRebootNotification()->title(),
            u"Your administrator restarted your device");
}

TEST_F(RebootNotificationControllerTest, KioskSessionDoesNotShowNotification) {
  AccountId account_id =
      AccountId::FromUserEmailGaiaId(kKioskEmailId, kKioskGaiaId);
  CreateFakeKioskUser(account_id);
  base::Time reboot_time;
  ASSERT_TRUE(
      base::Time::FromUTCExploded(kRebootTime2022Feb2At1520, &reboot_time));

  // User is not logged in. Don't show notifications.
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::NullCallback());
  EXPECT_EQ(std::nullopt, GetPendingRebootNotification());
  notification_controller_.MaybeShowPostRebootNotification();
  EXPECT_EQ(std::nullopt, GetPostRebootNotification());

  // Start kiosk session. Don't show notifications.
  LoginFakeUser(account_id);
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::NullCallback());
  EXPECT_EQ(std::nullopt, GetPendingRebootNotification());
  notification_controller_.MaybeShowPostRebootNotification();
  EXPECT_EQ(std::nullopt, GetPostRebootNotification());
}

TEST_F(RebootNotificationControllerTest, CloseNotification) {
  AccountId account_id = AccountId::FromUserEmailGaiaId(kEmailId, kGaiaId);
  CreateFakeUser(account_id);
  base::Time reboot_time;
  ASSERT_TRUE(
      base::Time::FromLocalExploded(kRebootTime2022Feb2At1520, &reboot_time));

  // Log in user and show notification.
  LoginFakeUser(account_id);
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::NullCallback());
  EXPECT_NE(std::nullopt, GetPendingRebootNotification());
  EXPECT_EQ(GetTransientNotificationCount(), 1);

  // Explicitly close notification.
  notification_controller_.CloseRebootNotification();
  EXPECT_EQ(std::nullopt, GetPendingRebootNotification());
  EXPECT_EQ(GetTransientNotificationCount(), 0);
}

TEST_F(RebootNotificationControllerTest, HandleNotificationClick) {
  AccountId account_id = AccountId::FromUserEmailGaiaId(kEmailId, kGaiaId);
  CreateFakeUser(account_id);
  base::Time reboot_time;
  ASSERT_TRUE(
      base::Time::FromLocalExploded(kRebootTime2022Feb2At1520, &reboot_time));

  // Log in user and show notification.
  LoginFakeUser(account_id);
  ClickCounter counter;
  notification_controller_.MaybeShowPendingRebootNotification(
      reboot_time, base::BindRepeating(&ClickCounter::ButtonClickCallback,
                                       counter.weak_ptr_factory_.GetWeakPtr()));
  auto notification = GetPendingRebootNotification().value();
  // Click on notification and do nothing.
  notification.delegate()->Click(std::nullopt, std::nullopt);
  EXPECT_EQ(counter.clicks, 0);
  // Click on notification button and run callback.
  notification.delegate()->Click(0, std::nullopt);
  EXPECT_EQ(counter.clicks, 1);
}