1// Copyright 2014 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 <string>
6#include <vector>
7
8#include "base/strings/string16.h"
9#include "base/strings/string_util.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h"
12#include "chrome/browser/signin/easy_unlock_service.h"
13#include "chrome/browser/signin/screenlock_bridge.h"
14#include "chrome/grit/generated_resources.h"
15#include "chrome/test/base/testing_browser_process.h"
16#include "testing/gtest/include/gtest/gtest.h"
17#include "ui/base/l10n/l10n_util.h"
18
19namespace {
20
21// Icons used by EasyUnlockScreenlockStateHandler. The icon id values are the
22// same as the ones set by ScreenlockBridge.
23const char kLockedIconId[] = "locked";
24const char kUnlockedIconId[] = "unlocked";
25const char kSpinnerIconId[] = "spinner";
26const char kHardlockedIconId[] = "hardlocked";
27
28// Checks if |input| string has any unreplaced placeholders.
29bool StringHasPlaceholders(const base::string16& input) {
30  std::vector<size_t> offsets;
31  std::vector<base::string16> subst;
32  subst.push_back(base::string16());
33
34  base::string16 replaced = ReplaceStringPlaceholders(input, subst, &offsets);
35  return !offsets.empty();
36}
37
38// Fake lock handler to be used in these tests.
39class TestLockHandler : public ScreenlockBridge::LockHandler {
40 public:
41  explicit TestLockHandler(const std::string& user_email)
42      : user_email_(user_email),
43        show_icon_count_(0u),
44        auth_type_(OFFLINE_PASSWORD) {
45  }
46  virtual ~TestLockHandler() {}
47
48  // ScreenlockBridge::LockHandler implementation:
49  virtual void ShowBannerMessage(const base::string16& message) OVERRIDE {
50    ASSERT_FALSE(true) << "Should not be reached.";
51  }
52
53  virtual void ShowUserPodCustomIcon(
54      const std::string& user_email,
55      const ScreenlockBridge::UserPodCustomIconOptions& icon) OVERRIDE {
56    ASSERT_EQ(user_email_, user_email);
57    ++show_icon_count_;
58    last_custom_icon_ = icon.ToDictionaryValue().Pass();
59    ValidateCustomIcon();
60  }
61
62  virtual void HideUserPodCustomIcon(const std::string& user_email) OVERRIDE {
63    ASSERT_EQ(user_email_, user_email);
64    last_custom_icon_.reset();
65  }
66
67  virtual void EnableInput() OVERRIDE {
68    ASSERT_FALSE(true) << "Should not be reached.";
69  }
70
71  virtual void SetAuthType(const std::string& user_email,
72                           AuthType auth_type,
73                           const base::string16& auth_value) OVERRIDE {
74    ASSERT_EQ(user_email_, user_email);
75    // Generally, this is allowed, but EasyUnlockScreenlockStateHandler should
76    // avoid resetting the same auth type.
77    EXPECT_NE(auth_type_, auth_type);
78
79    auth_type_ = auth_type;
80    auth_value_ = auth_value;
81  }
82
83  virtual AuthType GetAuthType(const std::string& user_email) const OVERRIDE {
84    EXPECT_EQ(user_email_, user_email);
85    return auth_type_;
86  }
87
88  virtual void Unlock(const std::string& user_email) OVERRIDE {
89    ASSERT_FALSE(true) << "Should not be reached.";
90  }
91
92  virtual void AttemptEasySignin(const std::string& user_email,
93                                 const std::string& secret,
94                                 const std::string& key_label) OVERRIDE {
95    ASSERT_FALSE(true) << "Should not be reached.";
96  }
97
98  // Utility methods used by tests:
99
100  // Gets last set auth value.
101  base::string16 GetAuthValue() const {
102    return auth_value_;
103  }
104
105  // Sets the auth value.
106  void SetAuthValue(const base::string16& value) {
107    auth_value_ = value;
108  }
109
110  // Returns the number of times an icon was shown since the last call to this
111  // method.
112  size_t GetAndResetShowIconCount() {
113    size_t result = show_icon_count_;
114    show_icon_count_ = 0u;
115    return result;
116  }
117
118  // Whether the custom icon is set.
119  bool HasCustomIcon() const {
120    return last_custom_icon_;
121  }
122
123  // If custom icon is set, returns the icon's id.
124  // If there is no icon, or if it doesn't have an id set, returns an empty
125  // string.
126  std::string GetCustomIconId() const {
127    std::string result;
128    if (last_custom_icon_)
129      last_custom_icon_->GetString("id", &result);
130    return result;
131  }
132
133  // Whether the custom icon is set and it has a tooltip.
134  bool CustomIconHasTooltip() const {
135    return last_custom_icon_ && last_custom_icon_->HasKey("tooltip");
136  }
137
138  // Gets the custom icon's tooltip text, if one is set.
139  base::string16 GetCustomIconTooltip() const {
140    base::string16 result;
141    if (last_custom_icon_)
142      last_custom_icon_->GetString("tooltip.text", &result);
143    return result;
144  }
145
146  // Whether the custom icon's tooltip should be autoshown. If the icon is not
147  // set, or it doesn't have a tooltip, returns false.
148  bool IsCustomIconTooltipAutoshown() const {
149    bool result = false;
150    if (last_custom_icon_)
151      last_custom_icon_->GetBoolean("tooltip.autoshow", &result);
152    return result;
153  }
154
155  // Whether the custom icon is set and if has hardlock capability enabed.
156  bool CustomIconHardlocksOnClick() const {
157    bool result = false;
158    if (last_custom_icon_)
159      last_custom_icon_->GetBoolean("hardlockOnClick", &result);
160    return result;
161  }
162
163 private:
164  // Does some sanity checks on the last icon set by |ShowUserPodCustomIcon|.
165  // It will cause a test failure if the icon is not valid.
166  void ValidateCustomIcon() {
167    ASSERT_TRUE(last_custom_icon_.get());
168
169    EXPECT_TRUE(last_custom_icon_->HasKey("id"));
170
171    if (last_custom_icon_->HasKey("tooltip")) {
172      base::string16 tooltip;
173      EXPECT_TRUE(last_custom_icon_->GetString("tooltip.text", &tooltip));
174      EXPECT_FALSE(tooltip.empty());
175      EXPECT_FALSE(StringHasPlaceholders(tooltip));
176    }
177  }
178
179  // The fake user email used in test. All methods called on |this| should be
180  // associated with this user.
181  const std::string user_email_;
182
183  // The last icon set using |SetUserPodCustomIcon|. Call to
184  // |HideUserPodcustomIcon| resets it.
185  scoped_ptr<base::DictionaryValue> last_custom_icon_;
186  size_t show_icon_count_;
187
188  // Auth type and value set using |SetAuthType|.
189  AuthType auth_type_;
190  base::string16 auth_value_;
191
192  DISALLOW_COPY_AND_ASSIGN(TestLockHandler);
193};
194
195class EasyUnlockScreenlockStateHandlerTest : public testing::Test {
196 public:
197  EasyUnlockScreenlockStateHandlerTest() : user_email_("test_user@gmail.com") {}
198  virtual ~EasyUnlockScreenlockStateHandlerTest() {}
199
200  virtual void SetUp() OVERRIDE {
201    TestingBrowserProcess::GetGlobal()->SetApplicationLocale("en-US");
202
203    // Create and inject fake lock handler to the screenlock bridge.
204    lock_handler_.reset(new TestLockHandler(user_email_));
205    ScreenlockBridge* screenlock_bridge = ScreenlockBridge::Get();
206    screenlock_bridge->SetLockHandler(lock_handler_.get());
207
208    // Create the screenlock state handler object that will be tested.
209    state_handler_.reset(new EasyUnlockScreenlockStateHandler(
210        user_email_,
211        EasyUnlockScreenlockStateHandler::NO_HARDLOCK,
212        screenlock_bridge));
213  }
214
215  virtual void TearDown() OVERRIDE {
216    ScreenlockBridge::Get()->SetLockHandler(NULL);
217    lock_handler_.reset();
218    state_handler_.reset();
219  }
220
221 protected:
222  // The state handler that is being tested.
223  scoped_ptr<EasyUnlockScreenlockStateHandler> state_handler_;
224
225  // The user associated with |state_handler_|.
226  const std::string user_email_;
227
228  // Faked lock handler given to ScreenlockBridge during the test. Abstracts
229  // the screen lock UI.
230  scoped_ptr<TestLockHandler> lock_handler_;
231};
232
233TEST_F(EasyUnlockScreenlockStateHandlerTest, AuthenticatedTrialRun) {
234  state_handler_->SetTrialRun();
235  state_handler_->ChangeState(
236      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
237
238  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
239  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
240            lock_handler_->GetAuthType(user_email_));
241
242  ASSERT_TRUE(lock_handler_->HasCustomIcon());
243  EXPECT_EQ(kUnlockedIconId, lock_handler_->GetCustomIconId());
244  EXPECT_TRUE(lock_handler_->CustomIconHasTooltip());
245  EXPECT_TRUE(lock_handler_->IsCustomIconTooltipAutoshown());
246  EXPECT_FALSE(lock_handler_->CustomIconHardlocksOnClick());
247
248  state_handler_->ChangeState(
249      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
250  // Duplicated state change should be ignored.
251  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
252}
253
254TEST_F(EasyUnlockScreenlockStateHandlerTest, AuthenticatedNotInitialRun) {
255  state_handler_->ChangeState(
256      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
257
258  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
259  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
260            lock_handler_->GetAuthType(user_email_));
261
262  ASSERT_TRUE(lock_handler_->HasCustomIcon());
263  EXPECT_EQ(kUnlockedIconId, lock_handler_->GetCustomIconId());
264  EXPECT_TRUE(lock_handler_->CustomIconHasTooltip());
265  EXPECT_FALSE(lock_handler_->IsCustomIconTooltipAutoshown());
266  EXPECT_TRUE(lock_handler_->CustomIconHardlocksOnClick());
267}
268
269TEST_F(EasyUnlockScreenlockStateHandlerTest, IsActive) {
270  EXPECT_FALSE(state_handler_->IsActive());
271  state_handler_->ChangeState(
272      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
273  EXPECT_TRUE(state_handler_->IsActive());
274  state_handler_->ChangeState(
275      EasyUnlockScreenlockStateHandler::STATE_INACTIVE);
276  EXPECT_FALSE(state_handler_->IsActive());
277}
278
279TEST_F(EasyUnlockScreenlockStateHandlerTest, BluetoothConnecting) {
280  state_handler_->ChangeState(
281      EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
282  EXPECT_TRUE(state_handler_->IsActive());
283
284  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
285  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
286            lock_handler_->GetAuthType(user_email_));
287
288  ASSERT_TRUE(lock_handler_->HasCustomIcon());
289  EXPECT_EQ(kSpinnerIconId, lock_handler_->GetCustomIconId());
290  EXPECT_FALSE(lock_handler_->CustomIconHasTooltip());
291  EXPECT_TRUE(lock_handler_->CustomIconHardlocksOnClick());
292
293  state_handler_->ChangeState(
294      EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
295  // Duplicated state change should be ignored.
296  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
297}
298
299TEST_F(EasyUnlockScreenlockStateHandlerTest, HardlockedState) {
300  state_handler_->ChangeState(
301      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
302
303  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
304  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
305            lock_handler_->GetAuthType(user_email_));
306
307  state_handler_->SetHardlockState(
308      EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
309
310  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
311  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
312            lock_handler_->GetAuthType(user_email_));
313
314  ASSERT_TRUE(lock_handler_->HasCustomIcon());
315  EXPECT_EQ(kHardlockedIconId, lock_handler_->GetCustomIconId());
316  EXPECT_TRUE(lock_handler_->CustomIconHasTooltip());
317  EXPECT_TRUE(lock_handler_->IsCustomIconTooltipAutoshown());
318  EXPECT_FALSE(lock_handler_->CustomIconHardlocksOnClick());
319
320  state_handler_->SetHardlockState(
321      EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
322
323  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
324  ASSERT_TRUE(lock_handler_->HasCustomIcon());
325}
326
327TEST_F(EasyUnlockScreenlockStateHandlerTest, HardlockedStateNoPairing) {
328  state_handler_->ChangeState(
329      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
330
331  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
332  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
333            lock_handler_->GetAuthType(user_email_));
334
335  state_handler_->SetHardlockState(
336      EasyUnlockScreenlockStateHandler::NO_PAIRING);
337
338  EXPECT_FALSE(lock_handler_->HasCustomIcon());
339  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
340            lock_handler_->GetAuthType(user_email_));
341}
342
343TEST_F(EasyUnlockScreenlockStateHandlerTest, StatesWithLockedIcon) {
344  std::vector<EasyUnlockScreenlockStateHandler::State> states;
345  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH);
346  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
347  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED);
348  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE);
349  states.push_back(
350      EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED);
351  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED);
352
353  for (size_t i = 0; i < states.size(); ++i) {
354    state_handler_->ChangeState(states[i]);
355    EXPECT_TRUE(state_handler_->IsActive());
356
357    EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount())
358        << "State: " << states[i];
359    EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
360              lock_handler_->GetAuthType(user_email_))
361        << "State: " << states[i];
362
363    ASSERT_TRUE(lock_handler_->HasCustomIcon())
364        << "State: " << states[i];
365    EXPECT_EQ(kLockedIconId, lock_handler_->GetCustomIconId())
366        << "State: " << states[i];
367    EXPECT_TRUE(lock_handler_->CustomIconHasTooltip())
368        << "State: " << states[i];
369    EXPECT_FALSE(lock_handler_->IsCustomIconTooltipAutoshown())
370        << "State: " << states[i];
371    EXPECT_TRUE(lock_handler_->CustomIconHardlocksOnClick())
372        << "State: " << states[i];
373
374    state_handler_->ChangeState(states[i]);
375    EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount())
376        << "State: " << states[i];
377  }
378}
379
380// Verifies tooltips are autoshown on initial run.
381TEST_F(EasyUnlockScreenlockStateHandlerTest, StatesWithLockedIcon_TrialRun) {
382  state_handler_->SetTrialRun();
383
384  std::vector<EasyUnlockScreenlockStateHandler::State> states;
385  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH);
386  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
387  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED);
388  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE);
389  states.push_back(
390      EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED);
391  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED);
392
393  for (size_t i = 0; i < states.size(); ++i) {
394    state_handler_->ChangeState(states[i]);
395    ASSERT_TRUE(lock_handler_->HasCustomIcon())
396        << "State: " << states[i];
397    EXPECT_TRUE(lock_handler_->CustomIconHasTooltip())
398        << "State: " << states[i];
399    EXPECT_TRUE(lock_handler_->IsCustomIconTooltipAutoshown())
400        << "State: " << states[i];
401  }
402
403  ScreenlockBridge::Get()->SetLockHandler(NULL);
404  lock_handler_.reset(new TestLockHandler(user_email_));
405  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
406  ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
407
408  // After the screen unlocks the tooltips should not be shown anymore.
409  for (size_t i = 0; i < states.size(); ++i) {
410    state_handler_->ChangeState(states[i]);
411    ASSERT_TRUE(lock_handler_->HasCustomIcon())
412        << "State: " << states[i];
413    EXPECT_TRUE(lock_handler_->CustomIconHasTooltip())
414        << "State: " << states[i];
415    EXPECT_FALSE(lock_handler_->IsCustomIconTooltipAutoshown())
416        << "State: " << states[i];
417  }
418}
419
420TEST_F(EasyUnlockScreenlockStateHandlerTest, SettingTrialRunUpdatesUI) {
421  state_handler_->ChangeState(
422      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
423
424  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
425  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
426            lock_handler_->GetAuthType(user_email_));
427
428  ASSERT_TRUE(lock_handler_->HasCustomIcon());
429  ASSERT_FALSE(lock_handler_->IsCustomIconTooltipAutoshown());
430
431  state_handler_->SetTrialRun();
432
433  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
434  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
435            lock_handler_->GetAuthType(user_email_));
436
437  ASSERT_TRUE(lock_handler_->HasCustomIcon());
438  ASSERT_TRUE(lock_handler_->IsCustomIconTooltipAutoshown());
439}
440
441TEST_F(EasyUnlockScreenlockStateHandlerTest,
442       LockScreenClearedOnStateHandlerDestruction) {
443  state_handler_->ChangeState(
444      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
445
446  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
447  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
448            lock_handler_->GetAuthType(user_email_));
449
450  ASSERT_TRUE(lock_handler_->HasCustomIcon());
451
452  state_handler_.reset();
453
454  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
455  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
456            lock_handler_->GetAuthType(user_email_));
457
458  ASSERT_FALSE(lock_handler_->HasCustomIcon());
459}
460
461TEST_F(EasyUnlockScreenlockStateHandlerTest, StatePreservedWhenScreenUnlocks) {
462  state_handler_->ChangeState(
463      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
464
465  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
466  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
467            lock_handler_->GetAuthType(user_email_));
468  ASSERT_TRUE(lock_handler_->HasCustomIcon());
469
470  ScreenlockBridge::Get()->SetLockHandler(NULL);
471  lock_handler_.reset(new TestLockHandler(user_email_));
472  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
473  ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
474
475  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
476  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
477            lock_handler_->GetAuthType(user_email_));
478  ASSERT_TRUE(lock_handler_->HasCustomIcon());
479}
480
481TEST_F(EasyUnlockScreenlockStateHandlerTest, StateChangeWhileScreenUnlocked) {
482  state_handler_->ChangeState(
483      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
484
485  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
486  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
487            lock_handler_->GetAuthType(user_email_));
488  ASSERT_TRUE(lock_handler_->HasCustomIcon());
489
490  ScreenlockBridge::Get()->SetLockHandler(NULL);
491  lock_handler_.reset(new TestLockHandler(user_email_));
492  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
493
494  state_handler_->ChangeState(
495      EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
496
497  ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
498
499  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
500  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
501            lock_handler_->GetAuthType(user_email_));
502  ASSERT_TRUE(lock_handler_->HasCustomIcon());
503  EXPECT_EQ(kSpinnerIconId, lock_handler_->GetCustomIconId());
504}
505
506TEST_F(EasyUnlockScreenlockStateHandlerTest,
507       HardlockEnabledAfterInitialUnlock) {
508  state_handler_->SetTrialRun();
509
510  std::vector<EasyUnlockScreenlockStateHandler::State> states;
511  states.push_back(
512      EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
513  states.push_back(
514      EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED);
515  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH);
516  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
517  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED);
518  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE);
519  // This one should go last as changing state to AUTHENTICATED enables hard
520  // locking.
521  states.push_back(EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
522
523  for (size_t i = 0; i < states.size(); ++i) {
524    state_handler_->ChangeState(states[i]);
525    ASSERT_TRUE(lock_handler_->HasCustomIcon()) << "State: " << states[i];
526    EXPECT_FALSE(lock_handler_->CustomIconHardlocksOnClick())
527        << "State: " << states[i];
528  }
529
530  ScreenlockBridge::Get()->SetLockHandler(NULL);
531  lock_handler_.reset(new TestLockHandler(user_email_));
532  ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
533
534  for (size_t i = 0; i < states.size(); ++i) {
535    state_handler_->ChangeState(states[i]);
536    ASSERT_TRUE(lock_handler_->HasCustomIcon()) << "State: " << states[i];
537    EXPECT_TRUE(lock_handler_->CustomIconHardlocksOnClick())
538        << "State: " << states[i];
539  }
540}
541
542TEST_F(EasyUnlockScreenlockStateHandlerTest,
543       NoPairingHardlockClearsIcon) {
544  state_handler_->ChangeState(
545      EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED);
546
547  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
548  ASSERT_TRUE(lock_handler_->HasCustomIcon());
549  EXPECT_EQ(kLockedIconId, lock_handler_->GetCustomIconId());
550
551  state_handler_->SetHardlockState(
552      EasyUnlockScreenlockStateHandler::NO_PAIRING);
553
554  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
555  ASSERT_FALSE(lock_handler_->HasCustomIcon());
556}
557
558TEST_F(EasyUnlockScreenlockStateHandlerTest, PairingChangedHardlock) {
559  state_handler_->ChangeState(
560      EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED);
561
562  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
563  ASSERT_TRUE(lock_handler_->HasCustomIcon());
564  EXPECT_EQ(kLockedIconId, lock_handler_->GetCustomIconId());
565
566  state_handler_->SetHardlockState(
567      EasyUnlockScreenlockStateHandler::PAIRING_CHANGED);
568
569  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
570  ASSERT_TRUE(lock_handler_->HasCustomIcon());
571  EXPECT_EQ(kHardlockedIconId, lock_handler_->GetCustomIconId());
572
573  state_handler_->ChangeState(
574      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
575
576  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
577  ASSERT_TRUE(lock_handler_->HasCustomIcon());
578  EXPECT_EQ(kHardlockedIconId, lock_handler_->GetCustomIconId());
579}
580
581TEST_F(EasyUnlockScreenlockStateHandlerTest,
582       PairingChangedHardlockIneffectiveOnInitialRun) {
583  state_handler_->SetTrialRun();
584
585  state_handler_->ChangeState(
586      EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED);
587
588  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
589  ASSERT_TRUE(lock_handler_->HasCustomIcon());
590  EXPECT_EQ(kLockedIconId, lock_handler_->GetCustomIconId());
591
592  state_handler_->SetHardlockState(
593      EasyUnlockScreenlockStateHandler::PAIRING_CHANGED);
594
595  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
596  ASSERT_TRUE(lock_handler_->HasCustomIcon());
597  EXPECT_EQ(kLockedIconId, lock_handler_->GetCustomIconId());
598}
599
600TEST_F(EasyUnlockScreenlockStateHandlerTest, InactiveStateHidesIcon) {
601  state_handler_->ChangeState(
602      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
603
604  ASSERT_TRUE(lock_handler_->HasCustomIcon());
605
606  state_handler_->ChangeState(
607      EasyUnlockScreenlockStateHandler::STATE_INACTIVE);
608
609  ASSERT_FALSE(lock_handler_->HasCustomIcon());
610}
611
612TEST_F(EasyUnlockScreenlockStateHandlerTest,
613       AuthenticatedStateClearsPreviousAuthValue) {
614  state_handler_->ChangeState(
615      EasyUnlockScreenlockStateHandler::STATE_INACTIVE);
616
617  lock_handler_->SetAuthValue(base::ASCIIToUTF16("xxx"));
618
619  state_handler_->ChangeState(
620      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
621
622  EXPECT_EQ(l10n_util::GetStringUTF16(
623                IDS_EASY_UNLOCK_SCREENLOCK_USER_POD_AUTH_VALUE),
624            lock_handler_->GetAuthValue());
625
626  state_handler_->ChangeState(
627      EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
628
629  EXPECT_EQ(base::string16(), lock_handler_->GetAuthValue());
630}
631
632TEST_F(EasyUnlockScreenlockStateHandlerTest,
633       ChangingStateDoesNotAffectAuthValueIfAuthTypeDoesNotChange) {
634  lock_handler_->SetAuthValue(base::ASCIIToUTF16("xxx"));
635
636  state_handler_->ChangeState(
637      EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
638  EXPECT_EQ(base::ASCIIToUTF16("xxx"), lock_handler_->GetAuthValue());
639
640  state_handler_->ChangeState(
641      EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED);
642  EXPECT_EQ(base::ASCIIToUTF16("xxx"), lock_handler_->GetAuthValue());
643
644  state_handler_->ChangeState(
645      EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
646  EXPECT_EQ(base::ASCIIToUTF16("xxx"), lock_handler_->GetAuthValue());
647  ASSERT_TRUE(lock_handler_->HasCustomIcon());
648  EXPECT_EQ(kSpinnerIconId, lock_handler_->GetCustomIconId());
649}
650
651TEST_F(EasyUnlockScreenlockStateHandlerTest, StateChangesIgnoredIfHardlocked) {
652  state_handler_->ChangeState(
653      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
654
655  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
656  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
657            lock_handler_->GetAuthType(user_email_));
658
659  state_handler_->SetHardlockState(
660      EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
661
662  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
663  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
664            lock_handler_->GetAuthType(user_email_));
665  ASSERT_TRUE(lock_handler_->HasCustomIcon());
666  EXPECT_EQ(kHardlockedIconId, lock_handler_->GetCustomIconId());
667
668  state_handler_->ChangeState(
669      EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
670  ASSERT_TRUE(lock_handler_->HasCustomIcon());
671  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
672
673  state_handler_->ChangeState(
674      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
675  ASSERT_TRUE(lock_handler_->HasCustomIcon());
676  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
677  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
678            lock_handler_->GetAuthType(user_email_));
679}
680
681TEST_F(EasyUnlockScreenlockStateHandlerTest,
682       LockScreenChangeableOnLockAfterHardlockReset) {
683  state_handler_->ChangeState(
684      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
685
686  state_handler_->SetHardlockState(
687      EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
688  EXPECT_EQ(2u, lock_handler_->GetAndResetShowIconCount());
689
690  state_handler_->SetHardlockState(
691      EasyUnlockScreenlockStateHandler::NO_HARDLOCK);
692
693  ScreenlockBridge::Get()->SetLockHandler(NULL);
694  lock_handler_.reset(new TestLockHandler(user_email_));
695  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
696  ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
697
698  state_handler_->ChangeState(
699      EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
700
701  EXPECT_EQ(2u, lock_handler_->GetAndResetShowIconCount());
702  EXPECT_TRUE(lock_handler_->HasCustomIcon());
703
704  ScreenlockBridge::Get()->SetLockHandler(NULL);
705  lock_handler_.reset(new TestLockHandler(user_email_));
706  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
707  ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
708
709  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
710  EXPECT_TRUE(lock_handler_->HasCustomIcon());
711  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
712            lock_handler_->GetAuthType(user_email_));
713  EXPECT_EQ(kLockedIconId, lock_handler_->GetCustomIconId());
714
715  state_handler_->ChangeState(
716      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
717  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
718  EXPECT_TRUE(lock_handler_->HasCustomIcon());
719  EXPECT_EQ(ScreenlockBridge::LockHandler::USER_CLICK,
720            lock_handler_->GetAuthType(user_email_));
721  EXPECT_TRUE(lock_handler_->CustomIconHardlocksOnClick());
722}
723
724TEST_F(EasyUnlockScreenlockStateHandlerTest, HardlockStatePersistsOverUnlocks) {
725  state_handler_->ChangeState(
726      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
727  state_handler_->SetHardlockState(
728      EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
729  EXPECT_EQ(2u, lock_handler_->GetAndResetShowIconCount());
730
731  ScreenlockBridge::Get()->SetLockHandler(NULL);
732  lock_handler_.reset(new TestLockHandler(user_email_));
733  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
734  ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
735
736  EXPECT_EQ(1u, lock_handler_->GetAndResetShowIconCount());
737  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
738            lock_handler_->GetAuthType(user_email_));
739  ASSERT_TRUE(lock_handler_->HasCustomIcon());
740  EXPECT_EQ(kHardlockedIconId, lock_handler_->GetCustomIconId());
741
742  state_handler_->ChangeState(
743      EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
744  EXPECT_EQ(0u, lock_handler_->GetAndResetShowIconCount());
745  EXPECT_TRUE(lock_handler_->HasCustomIcon());
746  EXPECT_EQ(ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
747            lock_handler_->GetAuthType(user_email_));
748}
749
750TEST_F(EasyUnlockScreenlockStateHandlerTest, NoOverrideOnlineSignin) {
751  lock_handler_->SetAuthType(user_email_,
752                             ScreenlockBridge::LockHandler::ONLINE_SIGN_IN,
753                             base::string16());
754
755  std::vector<EasyUnlockScreenlockStateHandler::State> states;
756  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH);
757  states.push_back(EasyUnlockScreenlockStateHandler::STATE_NO_PHONE);
758  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED);
759  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE);
760  states.push_back(
761      EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED);
762  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED);
763  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE);
764  states.push_back(EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED);
765  states.push_back(EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED);
766
767  for (size_t i = 0; i < states.size(); ++i) {
768    state_handler_->ChangeState(states[i]);
769    EXPECT_EQ(ScreenlockBridge::LockHandler::ONLINE_SIGN_IN,
770              lock_handler_->GetAuthType(user_email_));
771  }
772
773  std::vector<EasyUnlockScreenlockStateHandler::HardlockState> hardlock_states;
774  hardlock_states.push_back(EasyUnlockScreenlockStateHandler::NO_HARDLOCK);
775  hardlock_states.push_back(EasyUnlockScreenlockStateHandler::USER_HARDLOCK);
776  hardlock_states.push_back(EasyUnlockScreenlockStateHandler::PAIRING_CHANGED);
777  hardlock_states.push_back(EasyUnlockScreenlockStateHandler::PAIRING_ADDED);
778  hardlock_states.push_back(EasyUnlockScreenlockStateHandler::NO_PAIRING);
779  hardlock_states.push_back(EasyUnlockScreenlockStateHandler::LOGIN_FAILED);
780
781  for (size_t i = 0; i < hardlock_states.size(); ++i) {
782    state_handler_->SetHardlockState(hardlock_states[i]);
783    EXPECT_EQ(ScreenlockBridge::LockHandler::ONLINE_SIGN_IN,
784              lock_handler_->GetAuthType(user_email_));
785  }
786}
787
788}  // namespace
789