Home | History | Annotate | Download | only in lock
      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 "chrome/browser/chromeos/login/lock/screen_locker_tester.h"
      6 
      7 #include <string>
      8 
      9 #include "base/strings/string_util.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "base/values.h"
     13 #include "chrome/browser/chromeos/login/auth/login_status_consumer.h"
     14 #include "chrome/browser/chromeos/login/auth/mock_authenticator.h"
     15 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
     16 #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h"
     17 #include "chrome/test/base/ui_test_utils.h"
     18 #include "content/public/browser/render_frame_host.h"
     19 #include "content/public/browser/render_view_host.h"
     20 #include "content/public/browser/web_contents.h"
     21 #include "content/public/browser/web_ui.h"
     22 #include "content/public/test/test_utils.h"
     23 #include "ui/views/controls/button/button.h"
     24 #include "ui/views/controls/label.h"
     25 #include "ui/views/controls/textfield/textfield.h"
     26 #include "ui/views/widget/root_view.h"
     27 
     28 using content::WebContents;
     29 
     30 namespace {
     31 
     32 // This class is used to observe state of the global ScreenLocker instance,
     33 // which can go away as a result of a successful authentication. As such,
     34 // it needs to directly reference the global ScreenLocker.
     35 class LoginAttemptObserver : public chromeos::LoginStatusConsumer {
     36  public:
     37   LoginAttemptObserver();
     38   virtual ~LoginAttemptObserver();
     39 
     40   void WaitForAttempt();
     41 
     42   // Overridden from LoginStatusConsumer:
     43   virtual void OnLoginFailure(const chromeos::LoginFailure& error) OVERRIDE {
     44     LoginAttempted();
     45   }
     46 
     47   virtual void OnLoginSuccess(
     48       const chromeos::UserContext& credentials) OVERRIDE {
     49     LoginAttempted();
     50   }
     51 
     52  private:
     53   void LoginAttempted();
     54 
     55   bool login_attempted_;
     56   bool waiting_;
     57 
     58   DISALLOW_COPY_AND_ASSIGN(LoginAttemptObserver);
     59 };
     60 
     61 LoginAttemptObserver::LoginAttemptObserver()
     62     : chromeos::LoginStatusConsumer(),
     63       login_attempted_(false),
     64       waiting_(false) {
     65   chromeos::ScreenLocker::default_screen_locker()->SetLoginStatusConsumer(this);
     66 }
     67 
     68 LoginAttemptObserver::~LoginAttemptObserver() {
     69   chromeos::ScreenLocker* global_locker =
     70       chromeos::ScreenLocker::default_screen_locker();
     71   if (global_locker)
     72     global_locker->SetLoginStatusConsumer(NULL);
     73 }
     74 
     75 void LoginAttemptObserver::WaitForAttempt() {
     76   if (!login_attempted_) {
     77     waiting_ = true;
     78     content::RunMessageLoop();
     79     waiting_ = false;
     80   }
     81   ASSERT_TRUE(login_attempted_);
     82 }
     83 
     84 void LoginAttemptObserver::LoginAttempted() {
     85   login_attempted_ = true;
     86   if (waiting_)
     87     base::MessageLoopForUI::current()->Quit();
     88 }
     89 
     90 }  // anyonymous namespace
     91 
     92 namespace chromeos {
     93 
     94 namespace test {
     95 
     96 class WebUIScreenLockerTester : public ScreenLockerTester {
     97  public:
     98   // ScreenLockerTester overrides:
     99   virtual void SetPassword(const std::string& password) OVERRIDE;
    100   virtual std::string GetPassword() OVERRIDE;
    101   virtual void EnterPassword(const std::string& password) OVERRIDE;
    102   virtual void EmulateWindowManagerReady() OVERRIDE;
    103   virtual views::Widget* GetWidget() const OVERRIDE;
    104   virtual views::Widget* GetChildWidget() const OVERRIDE;
    105 
    106  private:
    107   friend class chromeos::ScreenLocker;
    108 
    109   WebUIScreenLockerTester() {}
    110 
    111   content::RenderViewHost* RenderViewHost() const;
    112 
    113   // Returns the ScreenLockerWebUI object.
    114   WebUIScreenLocker* webui_screen_locker() const;
    115 
    116   // Returns the WebUI object from the screen locker.
    117   content::WebUI* webui() const;
    118 
    119   DISALLOW_COPY_AND_ASSIGN(WebUIScreenLockerTester);
    120 };
    121 
    122 void WebUIScreenLockerTester::SetPassword(const std::string& password) {
    123   webui()->GetWebContents()->GetMainFrame()->ExecuteJavaScript(
    124       base::ASCIIToUTF16(base::StringPrintf(
    125           "$('pod-row').pods[0].passwordElement.value = '%s';",
    126           password.c_str())));
    127 }
    128 
    129 std::string WebUIScreenLockerTester::GetPassword() {
    130   std::string result;
    131   scoped_ptr<base::Value> v = content::ExecuteScriptAndGetValue(
    132       RenderViewHost()->GetMainFrame(),
    133       "$('pod-row').pods[0].passwordElement.value;");
    134   CHECK(v->GetAsString(&result));
    135   return result;
    136 }
    137 
    138 void WebUIScreenLockerTester::EnterPassword(const std::string& password) {
    139   bool result;
    140   SetPassword(password);
    141 
    142   // Verify password is set.
    143   ASSERT_EQ(password, GetPassword());
    144 
    145   // Verify that "signin" button is hidden.
    146   scoped_ptr<base::Value> v = content::ExecuteScriptAndGetValue(
    147       RenderViewHost()->GetMainFrame(),
    148       "$('pod-row').pods[0].signinButtonElement.hidden;");
    149   ASSERT_TRUE(v->GetAsBoolean(&result));
    150   ASSERT_TRUE(result);
    151 
    152   // Attempt to sign in.
    153   LoginAttemptObserver login;
    154   v = content::ExecuteScriptAndGetValue(
    155       RenderViewHost()->GetMainFrame(),
    156       "$('pod-row').pods[0].activate();");
    157   ASSERT_TRUE(v->GetAsBoolean(&result));
    158   ASSERT_TRUE(result);
    159 
    160   // Wait for login attempt.
    161   login.WaitForAttempt();
    162 }
    163 
    164 void WebUIScreenLockerTester::EmulateWindowManagerReady() {
    165 }
    166 
    167 views::Widget* WebUIScreenLockerTester::GetWidget() const {
    168   return webui_screen_locker()->lock_window_;
    169 }
    170 
    171 views::Widget* WebUIScreenLockerTester::GetChildWidget() const {
    172   return webui_screen_locker()->lock_window_;
    173 }
    174 
    175 content::RenderViewHost* WebUIScreenLockerTester::RenderViewHost() const {
    176   return webui()->GetWebContents()->GetRenderViewHost();
    177 }
    178 
    179 WebUIScreenLocker* WebUIScreenLockerTester::webui_screen_locker() const {
    180   DCHECK(ScreenLocker::screen_locker_);
    181   return static_cast<WebUIScreenLocker*>(
    182       ScreenLocker::screen_locker_->delegate_.get());
    183 }
    184 
    185 content::WebUI* WebUIScreenLockerTester::webui() const {
    186   DCHECK(webui_screen_locker()->webui_ready_);
    187   content::WebUI* webui = webui_screen_locker()->GetWebUI();
    188   DCHECK(webui);
    189   return webui;
    190 }
    191 
    192 ScreenLockerTester::ScreenLockerTester() {
    193 }
    194 
    195 ScreenLockerTester::~ScreenLockerTester() {
    196 }
    197 
    198 bool ScreenLockerTester::IsLocked() {
    199   return ScreenLocker::screen_locker_ &&
    200       ScreenLocker::screen_locker_->locked_;
    201 }
    202 
    203 void ScreenLockerTester::InjectMockAuthenticator(
    204     const UserContext& user_context) {
    205   DCHECK(ScreenLocker::screen_locker_);
    206   ScreenLocker::screen_locker_->SetAuthenticator(
    207       new MockAuthenticator(ScreenLocker::screen_locker_, user_context));
    208 }
    209 
    210 }  // namespace test
    211 
    212 test::ScreenLockerTester* ScreenLocker::GetTester() {
    213   return new test::WebUIScreenLockerTester();
    214 }
    215 
    216 }  // namespace chromeos
    217