oobe_browsertest.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
1// Copyright (c) 2013 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 "base/command_line.h" 6#include "base/path_service.h" 7#include "chrome/browser/chrome_browser_main.h" 8#include "chrome/browser/chrome_browser_main_extra_parts.h" 9#include "chrome/browser/chrome_content_browser_client.h" 10#include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h" 11#include "chrome/browser/chromeos/login/existing_user_controller.h" 12#include "chrome/browser/chromeos/login/webui_login_display.h" 13#include "chrome/browser/chromeos/login/wizard_controller.h" 14#include "chrome/browser/ui/browser.h" 15#include "chrome/common/chrome_notification_types.h" 16#include "chrome/common/chrome_paths.h" 17#include "chrome/common/chrome_switches.h" 18#include "chrome/test/base/in_process_browser_test.h" 19#include "chrome/test/base/interactive_test_utils.h" 20#include "chrome/test/base/ui_test_utils.h" 21#include "chromeos/chromeos_switches.h" 22#include "content/public/browser/notification_observer.h" 23#include "content/public/browser/notification_registrar.h" 24#include "content/public/browser/notification_service.h" 25#include "content/public/test/test_utils.h" 26#include "google_apis/gaia/gaia_switches.h" 27#include "net/test/embedded_test_server/embedded_test_server.h" 28#include "net/test/embedded_test_server/http_request.h" 29#include "net/test/embedded_test_server/http_response.h" 30#include "testing/gmock/include/gmock/gmock.h" 31#include "testing/gtest/include/gtest/gtest.h" 32 33using namespace net::test_server; 34 35namespace { 36 37// Used to add an observer to NotificationService after it's created. 38class TestBrowserMainExtraParts 39 : public ChromeBrowserMainExtraParts, 40 public content::NotificationObserver { 41 public: 42 TestBrowserMainExtraParts() 43 : webui_visible_(false), 44 browsing_data_removed_(false), 45 signin_screen_shown_(false) {} 46 virtual ~TestBrowserMainExtraParts() {} 47 48 // ChromeBrowserMainExtraParts implementation. 49 virtual void PreEarlyInitialization() OVERRIDE { 50 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE, 51 content::NotificationService::AllSources()); 52 registrar_.Add(this, chrome::NOTIFICATION_SESSION_STARTED, 53 content::NotificationService::AllSources()); 54 registrar_.Add(this, chrome::NOTIFICATION_BROWSING_DATA_REMOVED, 55 content::NotificationService::AllSources()); 56 } 57 58 void set_quit_task(const base::Closure& quit_task) { quit_task_ = quit_task; } 59 void set_gaia_url(const std::string& url) { gaia_url_ = url; } 60 61 private: 62 // Overridden from content::NotificationObserver: 63 virtual void Observe(int type, 64 const content::NotificationSource& source, 65 const content::NotificationDetails& details) OVERRIDE { 66 if (type == chrome::NOTIFICATION_LOGIN_WEBUI_VISIBLE) { 67 LOG(INFO) << "NOTIFICATION_LOGIN_WEBUI_VISIBLE"; 68 webui_visible_ = true; 69 if (browsing_data_removed_ && !signin_screen_shown_) { 70 signin_screen_shown_ = true; 71 ShowSigninScreen(); 72 } 73 } else if (type == chrome::NOTIFICATION_BROWSING_DATA_REMOVED) { 74 LOG(INFO) << "chrome::NOTIFICATION_BROWSING_DATA_REMOVED"; 75 browsing_data_removed_ = true; 76 if (webui_visible_ && !signin_screen_shown_) { 77 signin_screen_shown_ = true; 78 ShowSigninScreen(); 79 } 80 } else if (type == chrome::NOTIFICATION_SESSION_STARTED) { 81 LOG(INFO) << "chrome::NOTIFICATION_SESSION_STARTED"; 82 quit_task_.Run(); 83 } else { 84 NOTREACHED(); 85 } 86 } 87 88 void ShowSigninScreen() { 89 chromeos::ExistingUserController* controller = 90 chromeos::ExistingUserController::current_controller(); 91 CHECK(controller); 92 chromeos::WebUILoginDisplay* webui_login_display = 93 static_cast<chromeos::WebUILoginDisplay*>( 94 controller->login_display()); 95 CHECK(webui_login_display); 96 webui_login_display->SetGaiaOriginForTesting(gaia_url_); 97 webui_login_display->ShowSigninScreenForCreds("username", "password"); 98 // TODO(glotov): mock GAIA server (test_server_) should support 99 // username/password configuration. 100 } 101 102 bool webui_visible_, browsing_data_removed_, signin_screen_shown_; 103 content::NotificationRegistrar registrar_; 104 base::Closure quit_task_; 105 std::string gaia_url_; 106 107 DISALLOW_COPY_AND_ASSIGN(TestBrowserMainExtraParts); 108}; 109 110class TestContentBrowserClient : public chrome::ChromeContentBrowserClient { 111 public: 112 TestContentBrowserClient() {} 113 virtual ~TestContentBrowserClient() {} 114 115 virtual content::BrowserMainParts* CreateBrowserMainParts( 116 const content::MainFunctionParams& parameters) OVERRIDE { 117 ChromeBrowserMainParts* main_parts = static_cast<ChromeBrowserMainParts*>( 118 ChromeContentBrowserClient::CreateBrowserMainParts(parameters)); 119 120 browser_main_extra_parts_ = new TestBrowserMainExtraParts(); 121 main_parts->AddParts(browser_main_extra_parts_); 122 return main_parts; 123 } 124 125 TestBrowserMainExtraParts* browser_main_extra_parts_; 126 127 private: 128 DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient); 129}; 130 131const base::FilePath kServiceLogin("chromeos/service_login.html"); 132 133class OobeTest : public chromeos::CrosInProcessBrowserTest { 134 protected: 135 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 136 command_line->AppendSwitch(chromeos::switches::kLoginManager); 137 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); 138 command_line->AppendSwitch( 139 chromeos::switches::kDisableChromeCaptivePortalDetector); 140 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); 141 command_line->AppendSwitchASCII( 142 chromeos::switches::kAuthExtensionPath, "gaia_auth"); 143 } 144 145 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 146 content_browser_client_.reset(new TestContentBrowserClient()); 147 original_content_browser_client_ = content::SetBrowserClientForTesting( 148 content_browser_client_.get()); 149 base::FilePath test_data_dir; 150 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); 151 CHECK(file_util::ReadFileToString(test_data_dir.Append(kServiceLogin), 152 &service_login_response_)); 153 } 154 155 virtual void SetUpOnMainThread() OVERRIDE { 156 test_server_ = new EmbeddedTestServer( 157 content::BrowserThread::GetMessageLoopProxyForThread( 158 content::BrowserThread::IO)); 159 CHECK(test_server_->InitializeAndWaitUntilReady()); 160 test_server_->RegisterRequestHandler( 161 base::Bind(&OobeTest::HandleRequest, base::Unretained(this))); 162 LOG(INFO) << "Set up http server at " << test_server_->base_url(); 163 CHECK(test_server_->port() >= 8040 && test_server_->port() < 8045) 164 << "Current manifest_test.json for gaia_login restrictions " 165 << "does not allow this port"; 166 167 const std::string gaia_url = 168 "http://localhost:" + test_server_->base_url().port(); 169 content_browser_client_->browser_main_extra_parts_->set_gaia_url(gaia_url); 170 } 171 172 virtual void CleanUpOnMainThread() OVERRIDE { 173 LOG(INFO) << "Stopping the http server."; 174 EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete()); 175 delete test_server_; // Destructor wants UI thread. 176 } 177 178 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { 179 GURL url = test_server_->GetURL(request.relative_url); 180 LOG(INFO) << "Http request: " << url.spec(); 181 182 scoped_ptr<HttpResponse> http_response(new HttpResponse()); 183 if (url.path() == "/ServiceLogin") { 184 http_response->set_code(net::test_server::SUCCESS); 185 http_response->set_content(service_login_response_); 186 http_response->set_content_type("text/html"); 187 } else if (url.path() == "/ServiceLoginAuth") { 188 LOG(INFO) << "Params: " << request.content; 189 static const char kContinueParam[] = "continue="; 190 int continue_arg_begin = request.content.find(kContinueParam) + 191 arraysize(kContinueParam) - 1; 192 int continue_arg_end = request.content.find("&", continue_arg_begin); 193 const std::string continue_url = request.content.substr( 194 continue_arg_begin, continue_arg_end - continue_arg_begin); 195 http_response->set_code(net::test_server::SUCCESS); 196 const std::string redirect_js = 197 "document.location.href = unescape('" + continue_url + "');"; 198 http_response->set_content( 199 "<HTML><HEAD><SCRIPT>\n" + redirect_js + "\n</SCRIPT></HEAD></HTML>"); 200 http_response->set_content_type("text/html"); 201 } else { 202 NOTREACHED() << url.path(); 203 } 204 return http_response.Pass(); 205 } 206 207 scoped_ptr<TestContentBrowserClient> content_browser_client_; 208 content::ContentBrowserClient* original_content_browser_client_; 209 std::string service_login_response_; 210 EmbeddedTestServer* test_server_; // cant use scoped_ptr because destructor 211 // needs UI thread. 212}; 213 214IN_PROC_BROWSER_TEST_F(OobeTest, NewUser) { 215 chromeos::WizardController::SkipPostLoginScreensForTesting(); 216 chromeos::WizardController* wizard_controller = 217 chromeos::WizardController::default_controller(); 218 CHECK(wizard_controller); 219 wizard_controller->SkipToLoginForTesting(); 220 221 scoped_refptr<content::MessageLoopRunner> runner = 222 new content::MessageLoopRunner; 223 content_browser_client_->browser_main_extra_parts_->set_quit_task( 224 runner->QuitClosure()); 225 runner->Run(); 226} 227 228} 229