account_status_change_delegate_notifier_impl_unittest.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. // Copyright 2018 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. #include "ash/services/multidevice_setup/account_status_change_delegate_notifier_impl.h"
  5. #include <string>
  6. #include <vector>
  7. #include "ash/components/multidevice/remote_device_ref.h"
  8. #include "ash/components/multidevice/remote_device_test_util.h"
  9. #include "ash/services/device_sync/public/cpp/fake_device_sync_client.h"
  10. #include "ash/services/multidevice_setup/fake_account_status_change_delegate.h"
  11. #include "ash/services/multidevice_setup/fake_host_device_timestamp_manager.h"
  12. #include "ash/services/multidevice_setup/fake_host_status_provider.h"
  13. #include "ash/services/multidevice_setup/public/cpp/oobe_completion_tracker.h"
  14. #include "ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
  15. #include "base/test/simple_test_clock.h"
  16. #include "base/test/task_environment.h"
  17. #include "base/time/time.h"
  18. #include "components/sync_preferences/testing_pref_service_syncable.h"
  19. #include "testing/gtest/include/gtest/gtest.h"
  20. namespace ash {
  21. namespace multidevice_setup {
  22. namespace {
  23. const int64_t kTestTimeMillis = 1500000000000;
  24. const char kFakePhoneKey[] = "fake-phone-key";
  25. const char kFakePhoneName[] = "Phony Phone";
  26. const char kFakePhoneKeyA[] = "fake-phone-key-A";
  27. const char kFakePhoneNameA[] = "Phony Phone A";
  28. const char kFakePhoneKeyB[] = "fake-phone-key-B";
  29. const char kFakePhoneNameB[] = "Phony Phone B";
  30. const multidevice::RemoteDeviceRef kFakePhone =
  31. multidevice::RemoteDeviceRefBuilder()
  32. .SetPublicKey(kFakePhoneKey)
  33. .SetName(kFakePhoneName)
  34. .Build();
  35. // Alternate hosts for multi host tests
  36. const multidevice::RemoteDeviceRef kFakePhoneA =
  37. multidevice::RemoteDeviceRefBuilder()
  38. .SetPublicKey("fake-phone-key-A")
  39. .SetName("Phony Phone A")
  40. .Build();
  41. const multidevice::RemoteDeviceRef kFakePhoneB =
  42. multidevice::RemoteDeviceRefBuilder()
  43. .SetPublicKey("fake-phone-key-B")
  44. .SetName("Phony Phone B")
  45. .Build();
  46. } // namespace
  47. class MultiDeviceSetupAccountStatusChangeDelegateNotifierTest
  48. : public testing::Test {
  49. public:
  50. MultiDeviceSetupAccountStatusChangeDelegateNotifierTest(
  51. const MultiDeviceSetupAccountStatusChangeDelegateNotifierTest&) = delete;
  52. MultiDeviceSetupAccountStatusChangeDelegateNotifierTest& operator=(
  53. const MultiDeviceSetupAccountStatusChangeDelegateNotifierTest&) = delete;
  54. protected:
  55. MultiDeviceSetupAccountStatusChangeDelegateNotifierTest() = default;
  56. ~MultiDeviceSetupAccountStatusChangeDelegateNotifierTest() override = default;
  57. void SetUp() override {
  58. test_pref_service_ =
  59. std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
  60. AccountStatusChangeDelegateNotifierImpl::RegisterPrefs(
  61. test_pref_service_->registry());
  62. fake_delegate_ = std::make_unique<FakeAccountStatusChangeDelegate>();
  63. fake_host_status_provider_ = std::make_unique<FakeHostStatusProvider>();
  64. test_clock_ = std::make_unique<base::SimpleTestClock>();
  65. fake_host_device_timestamp_manager_ =
  66. std::make_unique<FakeHostDeviceTimestampManager>();
  67. fake_oobe_completion_tracker_ = std::make_unique<OobeCompletionTracker>();
  68. test_clock_->SetNow(base::Time::FromJavaTime(kTestTimeMillis));
  69. }
  70. void BuildAccountStatusChangeDelegateNotifier() {
  71. delegate_notifier_ =
  72. AccountStatusChangeDelegateNotifierImpl::Factory::Create(
  73. fake_host_status_provider_.get(), test_pref_service_.get(),
  74. fake_host_device_timestamp_manager_.get(),
  75. fake_oobe_completion_tracker_.get(), test_clock_.get());
  76. }
  77. multidevice::RemoteDeviceRef BuildFakePhone(std::string public_key,
  78. std::string name) {
  79. return multidevice::RemoteDeviceRefBuilder()
  80. .SetPublicKey(public_key)
  81. .SetName(name)
  82. .Build();
  83. }
  84. void SetHostWithStatus(
  85. mojom::HostStatus host_status,
  86. const absl::optional<multidevice::RemoteDeviceRef>& host_device) {
  87. fake_host_status_provider_->SetHostWithStatus(host_status, host_device);
  88. delegate_notifier_->FlushForTesting();
  89. }
  90. // Simulates finding a potential host, going through setup flow with it, and
  91. // verifying it.
  92. void SetUpHost(const multidevice::RemoteDeviceRef& host_device) {
  93. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  94. absl::nullopt /* host_device */);
  95. fake_host_device_timestamp_manager_->set_was_host_set_from_this_chromebook(
  96. true);
  97. SetHostWithStatus(
  98. mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation,
  99. host_device);
  100. SetHostWithStatus(mojom::HostStatus::kHostVerified, host_device);
  101. }
  102. // Simulates forgetting a set host.
  103. void ForgetHost() {
  104. fake_host_device_timestamp_manager_->set_was_host_set_from_this_chromebook(
  105. false);
  106. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  107. absl::nullopt /* host_device */);
  108. }
  109. void SetNewUserPotentialHostExistsTimestamp(int64_t timestamp) {
  110. test_pref_service_->SetInt64(AccountStatusChangeDelegateNotifierImpl::
  111. kNewUserPotentialHostExistsPrefName,
  112. timestamp);
  113. }
  114. void SetExistingUserChromebookAddedTimestamp(int64_t timestamp) {
  115. test_pref_service_->SetInt64(AccountStatusChangeDelegateNotifierImpl::
  116. kExistingUserChromebookAddedPrefName,
  117. timestamp);
  118. }
  119. void SetHostFromPreviousSession(std::string old_host_key) {
  120. std::string old_host_device_id =
  121. multidevice::RemoteDevice::GenerateDeviceId(old_host_key);
  122. test_pref_service_->SetString(
  123. AccountStatusChangeDelegateNotifierImpl::
  124. kVerifiedHostDeviceIdFromMostRecentHostStatusUpdatePrefName,
  125. old_host_device_id);
  126. }
  127. void SetAccountStatusChangeDelegateRemote() {
  128. delegate_notifier_->SetAccountStatusChangeDelegateRemote(
  129. fake_delegate_->GenerateRemote());
  130. delegate_notifier_->FlushForTesting();
  131. }
  132. // Simulates completing setup flow in OOBE.
  133. void CompleteOobeSetupFlow() {
  134. fake_host_status_provider_->SetHostWithStatus(
  135. mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  136. absl::nullopt /* host_device */);
  137. fake_oobe_completion_tracker_->MarkOobeShown();
  138. if (fake_delegate_)
  139. delegate_notifier_->FlushForTesting();
  140. }
  141. int64_t GetNewUserPotentialHostExistsTimestamp() {
  142. return test_pref_service_->GetInt64(
  143. AccountStatusChangeDelegateNotifierImpl::
  144. kNewUserPotentialHostExistsPrefName);
  145. }
  146. int64_t GetExistingUserChromebookAddedTimestamp() {
  147. return test_pref_service_->GetInt64(
  148. AccountStatusChangeDelegateNotifierImpl::
  149. kExistingUserChromebookAddedPrefName);
  150. }
  151. int64_t GetOobeSetupFlowTimestamp() {
  152. return test_pref_service_->GetInt64(
  153. AccountStatusChangeDelegateNotifierImpl::
  154. kOobeSetupFlowTimestampPrefName);
  155. }
  156. std::string GetMostRecentVerifiedHostDeviceIdPref() {
  157. return test_pref_service_->GetString(
  158. AccountStatusChangeDelegateNotifierImpl::
  159. kVerifiedHostDeviceIdFromMostRecentHostStatusUpdatePrefName);
  160. }
  161. FakeAccountStatusChangeDelegate* fake_delegate() {
  162. return fake_delegate_.get();
  163. }
  164. private:
  165. base::test::TaskEnvironment task_environment_;
  166. std::unique_ptr<FakeAccountStatusChangeDelegate> fake_delegate_;
  167. std::unique_ptr<FakeHostStatusProvider> fake_host_status_provider_;
  168. std::unique_ptr<sync_preferences::TestingPrefServiceSyncable>
  169. test_pref_service_;
  170. std::unique_ptr<FakeHostDeviceTimestampManager>
  171. fake_host_device_timestamp_manager_;
  172. std::unique_ptr<OobeCompletionTracker> fake_oobe_completion_tracker_;
  173. std::unique_ptr<base::SimpleTestClock> test_clock_;
  174. std::unique_ptr<AccountStatusChangeDelegateNotifier> delegate_notifier_;
  175. };
  176. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  177. SetObserverWithPotentialHost) {
  178. BuildAccountStatusChangeDelegateNotifier();
  179. SetAccountStatusChangeDelegateRemote();
  180. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  181. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  182. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  183. absl::nullopt /* host_device */);
  184. EXPECT_EQ(1u, fake_delegate()->num_new_user_potential_host_events_handled());
  185. EXPECT_EQ(kTestTimeMillis, GetNewUserPotentialHostExistsTimestamp());
  186. }
  187. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  188. PotentialHostAddedLater) {
  189. BuildAccountStatusChangeDelegateNotifier();
  190. SetAccountStatusChangeDelegateRemote();
  191. SetHostWithStatus(mojom::HostStatus::kNoEligibleHosts,
  192. absl::nullopt /* host_device */);
  193. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  194. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  195. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  196. absl::nullopt /* host_device */);
  197. EXPECT_EQ(1u, fake_delegate()->num_new_user_potential_host_events_handled());
  198. EXPECT_EQ(kTestTimeMillis, GetNewUserPotentialHostExistsTimestamp());
  199. }
  200. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  201. OnlyPotentialHostCausesNewUserEvent) {
  202. BuildAccountStatusChangeDelegateNotifier();
  203. SetAccountStatusChangeDelegateRemote();
  204. SetHostWithStatus(mojom::HostStatus::kNoEligibleHosts,
  205. absl::nullopt /* host_device */);
  206. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  207. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  208. SetHostWithStatus(
  209. mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation,
  210. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  211. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  212. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  213. SetHostWithStatus(mojom::HostStatus::kHostSetButNotYetVerified,
  214. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  215. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  216. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  217. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  218. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  219. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  220. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  221. }
  222. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  223. NoNewUserEventWithoutObserverSet) {
  224. BuildAccountStatusChangeDelegateNotifier();
  225. // All conditions for new user event are satisfied except for setting a
  226. // delegate.
  227. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  228. absl::nullopt /* host_device */);
  229. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  230. }
  231. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  232. NewUserFlowBlockedByOldNewUserTimestamp) {
  233. BuildAccountStatusChangeDelegateNotifier();
  234. int64_t earlier_test_time_millis = kTestTimeMillis / 2;
  235. SetNewUserPotentialHostExistsTimestamp(earlier_test_time_millis);
  236. SetAccountStatusChangeDelegateRemote();
  237. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  238. absl::nullopt /* host_device */);
  239. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  240. // Timestamp was not overwritten by clock.
  241. EXPECT_EQ(earlier_test_time_millis, GetNewUserPotentialHostExistsTimestamp());
  242. }
  243. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  244. NewUserFlowBlockedByOldChromebookAddedTimestamp) {
  245. BuildAccountStatusChangeDelegateNotifier();
  246. int64_t earlier_test_time_millis = kTestTimeMillis / 2;
  247. SetExistingUserChromebookAddedTimestamp(earlier_test_time_millis);
  248. SetAccountStatusChangeDelegateRemote();
  249. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  250. absl::nullopt /* host_device */);
  251. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  252. // Timestamp was not overwritten by clock.
  253. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  254. }
  255. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  256. LosingPotentialHostTriggersNoLongerNewUserEvent) {
  257. BuildAccountStatusChangeDelegateNotifier();
  258. SetAccountStatusChangeDelegateRemote();
  259. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  260. absl::nullopt /* host_device */);
  261. EXPECT_EQ(1u, fake_delegate()->num_new_user_potential_host_events_handled());
  262. EXPECT_EQ(0u, fake_delegate()->num_no_longer_new_user_events_handled());
  263. // All potential hosts are lost from the account.
  264. SetHostWithStatus(mojom::HostStatus::kNoEligibleHosts,
  265. absl::nullopt /* host_device */);
  266. EXPECT_EQ(1u, fake_delegate()->num_new_user_potential_host_events_handled());
  267. EXPECT_EQ(1u, fake_delegate()->num_no_longer_new_user_events_handled());
  268. }
  269. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  270. SettingHostTriggersNoLongerNewUserEvent) {
  271. BuildAccountStatusChangeDelegateNotifier();
  272. SetAccountStatusChangeDelegateRemote();
  273. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  274. absl::nullopt /* host_device */);
  275. EXPECT_EQ(1u, fake_delegate()->num_new_user_potential_host_events_handled());
  276. EXPECT_EQ(0u, fake_delegate()->num_no_longer_new_user_events_handled());
  277. // A potential host was set.
  278. SetHostWithStatus(
  279. mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation,
  280. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  281. EXPECT_EQ(1u, fake_delegate()->num_new_user_potential_host_events_handled());
  282. EXPECT_EQ(1u, fake_delegate()->num_no_longer_new_user_events_handled());
  283. }
  284. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  285. CompletingOobeSetupFlowBlocksNewUserEventIfNoDelegateIsSet) {
  286. BuildAccountStatusChangeDelegateNotifier();
  287. // Complete OOBE MultiDevice setup flow before delegate is set.
  288. EXPECT_EQ(0u, GetOobeSetupFlowTimestamp());
  289. CompleteOobeSetupFlow();
  290. EXPECT_EQ(kTestTimeMillis, GetOobeSetupFlowTimestamp());
  291. // Set delegate, which triggers event check.
  292. SetAccountStatusChangeDelegateRemote();
  293. EXPECT_EQ(0u, fake_delegate()->num_new_user_potential_host_events_handled());
  294. EXPECT_EQ(0u, GetNewUserPotentialHostExistsTimestamp());
  295. }
  296. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  297. CompletingOobeSetupFlowWithDelegateSetTriggersNoLongerNewUserEvent) {
  298. BuildAccountStatusChangeDelegateNotifier();
  299. SetAccountStatusChangeDelegateRemote();
  300. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  301. absl::nullopt /* host_device */);
  302. // Complete OOBE MultiDevice setup flow before delegate is set.
  303. EXPECT_EQ(0u, GetOobeSetupFlowTimestamp());
  304. CompleteOobeSetupFlow();
  305. EXPECT_EQ(kTestTimeMillis, GetOobeSetupFlowTimestamp());
  306. EXPECT_EQ(1u, fake_delegate()->num_new_user_potential_host_events_handled());
  307. EXPECT_EQ(1u, fake_delegate()->num_no_longer_new_user_events_handled());
  308. }
  309. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  310. NoLongerNewUserEventBlockedByOldChromebookAddedTimestamp) {
  311. BuildAccountStatusChangeDelegateNotifier();
  312. SetAccountStatusChangeDelegateRemote();
  313. // Record earlier Chromebook added event.
  314. int64_t earlier_test_time_millis = kTestTimeMillis / 2;
  315. SetExistingUserChromebookAddedTimestamp(earlier_test_time_millis);
  316. // A potential host was found.
  317. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  318. absl::nullopt /* host_device */);
  319. // A potential host was set. Note that this would trigger a NoLongerNewUser
  320. // event in the absence of the Chromebook added timestamp.
  321. SetHostWithStatus(
  322. mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation,
  323. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  324. EXPECT_EQ(0u, fake_delegate()->num_no_longer_new_user_events_handled());
  325. }
  326. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  327. NotifiesObserverForHostSwitchEvents) {
  328. const multidevice::RemoteDeviceRef fakePhone =
  329. BuildFakePhone(kFakePhoneKey, kFakePhoneName);
  330. BuildAccountStatusChangeDelegateNotifier();
  331. SetAccountStatusChangeDelegateRemote();
  332. // Check the delegate initializes to 0.
  333. EXPECT_EQ(0u,
  334. fake_delegate()->num_existing_user_host_switched_events_handled());
  335. // Set initially verified host.
  336. SetHostWithStatus(mojom::HostStatus::kHostVerified, fakePhone);
  337. // Host was set but has never been switched.
  338. EXPECT_EQ(0u,
  339. fake_delegate()->num_existing_user_host_switched_events_handled());
  340. // Switch to new verified host.
  341. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  342. BuildFakePhone(kFakePhoneKeyA, kFakePhoneNameA));
  343. EXPECT_EQ(1u,
  344. fake_delegate()->num_existing_user_host_switched_events_handled());
  345. // Switch to a different new verified host.
  346. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  347. BuildFakePhone(kFakePhoneKeyB, kFakePhoneNameB));
  348. EXPECT_EQ(2u,
  349. fake_delegate()->num_existing_user_host_switched_events_handled());
  350. // Switch back to initial host (verified).
  351. SetHostWithStatus(mojom::HostStatus::kHostVerified, fakePhone);
  352. EXPECT_EQ(3u,
  353. fake_delegate()->num_existing_user_host_switched_events_handled());
  354. }
  355. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  356. SettingSameHostTriggersNoHostSwitchedEvent) {
  357. BuildAccountStatusChangeDelegateNotifier();
  358. SetAccountStatusChangeDelegateRemote();
  359. // Set initially verified host.
  360. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  361. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  362. // Set to host with identical information.
  363. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  364. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  365. EXPECT_EQ(0u,
  366. fake_delegate()->num_existing_user_host_switched_events_handled());
  367. }
  368. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  369. ChangingHostDevicesTriggersHostSwitchEventWhenHostNameIsUnchanged) {
  370. BuildAccountStatusChangeDelegateNotifier();
  371. SetAccountStatusChangeDelegateRemote();
  372. // Set initially verified host.
  373. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  374. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  375. // Set to verified host with same name but different key.
  376. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  377. BuildFakePhone(kFakePhoneKeyA, kFakePhoneName));
  378. EXPECT_EQ(1u,
  379. fake_delegate()->num_existing_user_host_switched_events_handled());
  380. }
  381. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  382. VerifyingSetHostTriggersNoHostSwtichEvent) {
  383. const multidevice::RemoteDeviceRef fakePhone =
  384. BuildFakePhone(kFakePhoneKey, kFakePhoneName);
  385. BuildAccountStatusChangeDelegateNotifier();
  386. SetAccountStatusChangeDelegateRemote();
  387. // Set initial host but do not verify.
  388. SetHostWithStatus(mojom::HostStatus::kHostSetButNotYetVerified, fakePhone);
  389. // Verify host.
  390. SetHostWithStatus(mojom::HostStatus::kHostVerified, fakePhone);
  391. EXPECT_EQ(0u,
  392. fake_delegate()->num_existing_user_host_switched_events_handled());
  393. }
  394. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  395. OnlyVerifiedHostCausesHostSwitchedEvent) {
  396. BuildAccountStatusChangeDelegateNotifier();
  397. SetAccountStatusChangeDelegateRemote();
  398. // Set initially verified host.
  399. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  400. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  401. EXPECT_EQ(0u,
  402. fake_delegate()->num_existing_user_host_switched_events_handled());
  403. // Set a new host without verifying.
  404. SetHostWithStatus(mojom::HostStatus::kHostSetButNotYetVerified,
  405. BuildFakePhone(kFakePhoneKeyA, kFakePhoneNameA));
  406. EXPECT_EQ(0u,
  407. fake_delegate()->num_existing_user_host_switched_events_handled());
  408. // Set a different new host without confirming with backend so host is
  409. // unverified.
  410. SetHostWithStatus(
  411. mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation,
  412. BuildFakePhone(kFakePhoneKeyB, kFakePhoneNameB));
  413. EXPECT_EQ(0u,
  414. fake_delegate()->num_existing_user_host_switched_events_handled());
  415. }
  416. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  417. ForgettingAndThenSwitchingHostsDoesNotTriggerHostSwitchedEvent) {
  418. BuildAccountStatusChangeDelegateNotifier();
  419. SetAccountStatusChangeDelegateRemote();
  420. // Set initially verified host.
  421. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  422. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  423. EXPECT_EQ(0u,
  424. fake_delegate()->num_existing_user_host_switched_events_handled());
  425. ForgetHost();
  426. EXPECT_EQ(0u,
  427. fake_delegate()->num_existing_user_host_switched_events_handled());
  428. // Set a new verified host.
  429. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  430. BuildFakePhone(kFakePhoneKeyA, kFakePhoneNameA));
  431. EXPECT_EQ(0u,
  432. fake_delegate()->num_existing_user_host_switched_events_handled());
  433. }
  434. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  435. HostSwitchedBetweenSessions) {
  436. // Host set in some previous session.
  437. SetHostFromPreviousSession(
  438. BuildFakePhone(kFakePhoneKeyA, kFakePhoneNameA).GetDeviceId());
  439. BuildAccountStatusChangeDelegateNotifier();
  440. // Host switched and verified between sessions.
  441. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  442. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  443. SetAccountStatusChangeDelegateRemote();
  444. EXPECT_EQ(1u,
  445. fake_delegate()->num_existing_user_host_switched_events_handled());
  446. }
  447. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  448. NoHostSwitchedEventWithoutExistingHost) {
  449. BuildAccountStatusChangeDelegateNotifier();
  450. SetAccountStatusChangeDelegateRemote();
  451. SetUpHost(BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  452. EXPECT_EQ(0u,
  453. fake_delegate()->num_existing_user_host_switched_events_handled());
  454. }
  455. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  456. NoHostSwitchedEventWithoutObserverSet) {
  457. BuildAccountStatusChangeDelegateNotifier();
  458. // Set initially verified host.
  459. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  460. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  461. // All conditions for host switched event are satisfied except for setting a
  462. // delegate.
  463. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  464. BuildFakePhone(kFakePhoneKeyA, kFakePhoneNameA));
  465. EXPECT_EQ(0u,
  466. fake_delegate()->num_existing_user_host_switched_events_handled());
  467. }
  468. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  469. NotifiesObserverForChromebookAddedEvents) {
  470. BuildAccountStatusChangeDelegateNotifier();
  471. SetAccountStatusChangeDelegateRemote();
  472. // Check the delegate initializes to 0.
  473. EXPECT_EQ(
  474. 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  475. // Host is set and verified from another Chromebook while this one is logged
  476. // in.
  477. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  478. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  479. EXPECT_EQ(
  480. 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  481. }
  482. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  483. OnlyVerifiedHostCausesChromebookAddedEvent) {
  484. const multidevice::RemoteDeviceRef fakePhone =
  485. BuildFakePhone(kFakePhoneKey, kFakePhoneName);
  486. BuildAccountStatusChangeDelegateNotifier();
  487. SetAccountStatusChangeDelegateRemote();
  488. // Start with potential hosts but none set.
  489. SetHostWithStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  490. absl::nullopt /* host_device */);
  491. // Set a host without verifying.
  492. SetHostWithStatus(mojom::HostStatus::kHostSetButNotYetVerified, fakePhone);
  493. EXPECT_EQ(
  494. 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  495. // Verify the new host.
  496. SetHostWithStatus(mojom::HostStatus::kHostVerified, fakePhone);
  497. EXPECT_EQ(
  498. 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  499. }
  500. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  501. ReplacingUnverifiedHostAWithVerifiedHostBCausesChromebookAddedEvent) {
  502. BuildAccountStatusChangeDelegateNotifier();
  503. SetAccountStatusChangeDelegateRemote();
  504. // Start with potential hosts but none set.
  505. // Set initial host but do not verify.
  506. SetHostWithStatus(mojom::HostStatus::kHostSetButNotYetVerified,
  507. BuildFakePhone(kFakePhoneKeyA, kFakePhoneNameA));
  508. // Replace unverified Phone A with verified Phone B.
  509. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  510. BuildFakePhone(kFakePhoneKeyB, kFakePhoneNameB));
  511. // This causes a 'Chromebook added' event.
  512. EXPECT_EQ(
  513. 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  514. // It does not cause a 'host switched' event.
  515. EXPECT_EQ(0u,
  516. fake_delegate()->num_existing_user_host_switched_events_handled());
  517. }
  518. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  519. ChromebookAddedBetweenSessionsTriggersEvents) {
  520. BuildAccountStatusChangeDelegateNotifier();
  521. // Host is set and verified before this Chromebook is logged in.
  522. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  523. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  524. SetAccountStatusChangeDelegateRemote();
  525. EXPECT_EQ(
  526. 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  527. }
  528. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  529. ChromebookAddedEventBlockedIfHostWasSetFromThisChromebook) {
  530. const multidevice::RemoteDeviceRef fakePhone =
  531. BuildFakePhone(kFakePhoneKey, kFakePhoneName);
  532. BuildAccountStatusChangeDelegateNotifier();
  533. SetAccountStatusChangeDelegateRemote();
  534. SetUpHost(fakePhone);
  535. // The host was set on this Chromebook so it should not trigger the Chromebook
  536. // added event
  537. EXPECT_EQ(
  538. 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  539. ForgetHost();
  540. // Set verified host on another Chromebook.
  541. SetHostWithStatus(mojom::HostStatus::kHostVerified, fakePhone);
  542. EXPECT_EQ(
  543. 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  544. }
  545. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  546. OldTimestampInPreferencesDoesNotPreventChromebookAddedEvent) {
  547. int64_t earlier_test_time_millis = kTestTimeMillis / 2;
  548. SetExistingUserChromebookAddedTimestamp(earlier_test_time_millis);
  549. // Check timestamp was written.
  550. EXPECT_EQ(earlier_test_time_millis,
  551. GetExistingUserChromebookAddedTimestamp());
  552. BuildAccountStatusChangeDelegateNotifier();
  553. SetAccountStatusChangeDelegateRemote();
  554. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  555. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  556. EXPECT_EQ(
  557. 1u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  558. // Timestamp was overwritten by clock.
  559. EXPECT_EQ(kTestTimeMillis, GetExistingUserChromebookAddedTimestamp());
  560. }
  561. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  562. NoChromebookAddedEventWithoutObserverSet) {
  563. BuildAccountStatusChangeDelegateNotifier();
  564. // Triggers event check. Note that all conditions for Chromebook added event
  565. // are satisfied except for setting a delegate.
  566. SetHostWithStatus(mojom::HostStatus::kHostVerified,
  567. BuildFakePhone(kFakePhoneKey, kFakePhoneName));
  568. EXPECT_EQ(
  569. 0u, fake_delegate()->num_existing_user_chromebook_added_events_handled());
  570. }
  571. TEST_F(MultiDeviceSetupAccountStatusChangeDelegateNotifierTest,
  572. VerifiedHostIdStaysUpToDateInPrefs) {
  573. const multidevice::RemoteDeviceRef fakePhone =
  574. BuildFakePhone(kFakePhoneKey, kFakePhoneName);
  575. const multidevice::RemoteDeviceRef fakePhoneA =
  576. BuildFakePhone(kFakePhoneKeyA, kFakePhoneNameA);
  577. BuildAccountStatusChangeDelegateNotifier();
  578. SetAccountStatusChangeDelegateRemote();
  579. // Check the delegate initializes to empty.
  580. EXPECT_EQ(GetMostRecentVerifiedHostDeviceIdPref(), "");
  581. // Set initially verified host.
  582. SetHostWithStatus(mojom::HostStatus::kHostVerified, fakePhone);
  583. EXPECT_EQ(GetMostRecentVerifiedHostDeviceIdPref(), fakePhone.GetDeviceId());
  584. // Switch to an unverified host.
  585. SetHostWithStatus(mojom::HostStatus::kHostSetButNotYetVerified, fakePhoneA);
  586. // The host is set but not verified so the pref should be set to empty.
  587. EXPECT_EQ(GetMostRecentVerifiedHostDeviceIdPref(), "");
  588. // Verify the new host.
  589. SetHostWithStatus(mojom::HostStatus::kHostVerified, fakePhoneA);
  590. EXPECT_EQ(GetMostRecentVerifiedHostDeviceIdPref(), fakePhoneA.GetDeviceId());
  591. ForgetHost();
  592. EXPECT_EQ(GetMostRecentVerifiedHostDeviceIdPref(), "");
  593. }
  594. } // namespace multidevice_setup
  595. } // namespace ash