1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string>
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_service.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringprintf.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_process.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/login/signin_specifics.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/test/oobe_base_test.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/login/wizard_controller.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/auth/key.h"
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/auth/user_context.h"
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h"
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h"
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/notification_service.h"
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/process_manager.h"
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/test/extension_test_message_listener.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/test/result_catcher.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_constants.h"
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h"
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cookies/canonical_cookie.h"
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/cookies/cookie_store.h"
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/embedded_test_server/http_request.h"
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/embedded_test_server/http_response.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context.h"
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using net::test_server::BasicHttpResponse;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using net::test_server::HttpRequest;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using net::test_server::HttpResponse;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chromeos {
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Email of owner account for test.
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestAccountId[] = "username@gmail.com";
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestRawAccountId[] = "User.Name";
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestAccountPassword[] = "fake-password";
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestAuthCode[] = "fake-auth-code";
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestGaiaUberToken[] = "fake-uber-token";
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestAuthLoginAccessToken[] = "fake-access-token";
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestRefreshToken[] = "fake-refresh-token";
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestAuthSIDCookie[] = "fake-auth-SID-cookie";
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestAuthLSIDCookie[] = "fake-auth-LSID-cookie";
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestSessionSIDCookie[] = "fake-session-SID-cookie";
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestSessionLSIDCookie[] = "fake-session-LSID-cookie";
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestSession2SIDCookie[] = "fake-session2-SID-cookie";
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestSession2LSIDCookie[] = "fake-session2-LSID-cookie";
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestUserinfoToken[] = "fake-userinfo-token";
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestLoginToken[] = "fake-login-token";
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestSyncToken[] = "fake-sync-token";
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTestAuthLoginToken[] = "fake-oauthlogin-token";
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class OAuth2LoginManagerStateWaiter : public OAuth2LoginManager::Observer {
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit OAuth2LoginManagerStateWaiter(Profile* profile)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     : profile_(profile),
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       waiting_for_state_(false),
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       final_state_(OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED) {
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WaitForStates(
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::set<OAuth2LoginManager::SessionRestoreState>& states) {
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!waiting_for_state_);
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OAuth2LoginManager* login_manager =
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile_);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    states_ = states;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (states_.find(login_manager->state()) != states_.end()) {
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      final_state_ = login_manager->state();
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    waiting_for_state_ = true;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    login_manager->AddObserver(this);
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_ = new content::MessageLoopRunner;
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_->Run();
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    login_manager->RemoveObserver(this);
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OAuth2LoginManager::SessionRestoreState final_state() { return final_state_; }
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // OAuth2LoginManager::Observer overrides.
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnSessionRestoreStateChanged(
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Profile* user_profile,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OAuth2LoginManager::SessionRestoreState state) OVERRIDE {
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!waiting_for_state_)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (states_.find(state) == states_.end())
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    final_state_ = state;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    waiting_for_state_ = false;
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_->Quit();
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Profile* profile_;
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::set<OAuth2LoginManager::SessionRestoreState> states_;
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool waiting_for_state_;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OAuth2LoginManager::SessionRestoreState final_state_;
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner_;
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OAuth2LoginManagerStateWaiter);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class OAuth2Test : public OobeBaseTest {
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OAuth2Test() {}
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetupGaiaServerForNewAccount() {
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::MergeSessionParams params;
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.auth_sid_cookie = kTestAuthSIDCookie;
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.auth_lsid_cookie = kTestAuthLSIDCookie;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.auth_code = kTestAuthCode;
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.refresh_token = kTestRefreshToken;
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.access_token = kTestAuthLoginAccessToken;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.gaia_uber_token = kTestGaiaUberToken;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.session_sid_cookie = kTestSessionSIDCookie;
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.session_lsid_cookie = kTestSessionLSIDCookie;
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->SetMergeSessionParams(params);
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetupGaiaServerWithAccessTokens();
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetupGaiaServerForUnexpiredAccount() {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::MergeSessionParams params;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.email = kTestAccountId;
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->SetMergeSessionParams(params);
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetupGaiaServerWithAccessTokens();
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetupGaiaServerForExpiredAccount() {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::MergeSessionParams params;
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.gaia_uber_token = kTestGaiaUberToken;
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.session_sid_cookie = kTestSession2SIDCookie;
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    params.session_lsid_cookie = kTestSession2LSIDCookie;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->SetMergeSessionParams(params);
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetupGaiaServerWithAccessTokens();
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void LoginAsExistingUser() {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::WindowedNotificationObserver(
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::NotificationService::AllSources()).Wait();
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    JsExpect("!!document.querySelector('#account-picker')");
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    JsExpect("!!document.querySelector('#pod-row')");
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(TryToLogin(kTestAccountId, kTestAccountPassword));
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* profile = ProfileManager::GetPrimaryUserProfile();
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Wait for the session merge to finish.
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE);
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Check for existance of refresh token.
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ProfileOAuth2TokenService* token_service =
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(token_service->RefreshTokenIsAvailable(kTestAccountId));
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool TryToLogin(const std::string& username,
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  const std::string& password) {
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!AddUserToSession(username, password))
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (const user_manager::User* active_user =
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            user_manager::UserManager::Get()->GetActiveUser()) {
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return active_user->email() == username;
1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  user_manager::User::OAuthTokenStatus GetOAuthStatusFromLocalState(
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::string& user_id) const {
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrefService* local_state = g_browser_process->local_state();
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue* prefs_oauth_status =
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        local_state->GetDictionary("OAuthTokenStatus");
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int oauth_token_status = user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN;
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (prefs_oauth_status &&
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        prefs_oauth_status->GetIntegerWithoutPathExpansion(
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            user_id, &oauth_token_status)) {
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_manager::User::OAuthTokenStatus result =
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          static_cast<user_manager::User::OAuthTokenStatus>(oauth_token_status);
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return result;
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return user_manager::User::OAUTH_TOKEN_STATUS_UNKNOWN;
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // OobeBaseTest overrides.
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual Profile* profile() OVERRIDE {
2226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (user_manager::UserManager::Get()->GetActiveUser())
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return ProfileManager::GetPrimaryUserProfile();
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return OobeBaseTest::profile();
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool AddUserToSession(const std::string& username,
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const std::string& password) {
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ExistingUserController* controller =
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ExistingUserController::current_controller();
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!controller) {
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ADD_FAILURE();
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UserContext user_context(username);
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    user_context.SetKey(Key(password));
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    controller->Login(user_context, SigninSpecifics());
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::WindowedNotificationObserver(
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        chrome::NOTIFICATION_SESSION_STARTED,
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::NotificationService::AllSources()).Wait();
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const user_manager::UserList& logged_users =
2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        user_manager::UserManager::Get()->GetLoggedInUsers();
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    for (user_manager::UserList::const_iterator it = logged_users.begin();
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         it != logged_users.end();
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)         ++it) {
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if ((*it)->email() == username)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return true;
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetupGaiaServerWithAccessTokens() {
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Configure OAuth authentication.
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // This token satisfies the userinfo.email request from
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // DeviceOAuth2TokenService used in token validation.
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::AccessTokenInfo userinfo_token_info;
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_token_info.token = kTestUserinfoToken;
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_token_info.scopes.insert(
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "https://www.googleapis.com/auth/userinfo.email");
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_token_info.audience = gaia_urls->oauth2_chrome_client_id();
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_token_info.email = kTestAccountId;
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->IssueOAuthToken(kTestRefreshToken, userinfo_token_info);
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::AccessTokenInfo userinfo_profile_token_info;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_profile_token_info.token = kTestUserinfoToken;
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_profile_token_info.scopes.insert(
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "https://www.googleapis.com/auth/userinfo.profile");
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_profile_token_info.audience = gaia_urls->oauth2_chrome_client_id();
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    userinfo_profile_token_info.email = kTestAccountId;
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->IssueOAuthToken(kTestRefreshToken, userinfo_profile_token_info);
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // The any-api access token for accessing the token minting endpoint.
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::AccessTokenInfo login_token_info;
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    login_token_info.token = kTestLoginToken;
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    login_token_info.scopes.insert(GaiaConstants::kAnyApiOAuth2Scope);
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    login_token_info.audience = gaia_urls->oauth2_chrome_client_id();
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->IssueOAuthToken(kTestRefreshToken, login_token_info);
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // The /auth/chromesync access token for accessing sync endpoint.
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::AccessTokenInfo sync_token_info;
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_token_info.token = kTestSyncToken;
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_token_info.scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sync_token_info.audience = gaia_urls->oauth2_chrome_client_id();
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->IssueOAuthToken(kTestRefreshToken, sync_token_info);
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::AccessTokenInfo auth_login_token_info;
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    auth_login_token_info.token = kTestAuthLoginToken;
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    auth_login_token_info.scopes.insert(GaiaConstants::kOAuth1LoginScope);
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    auth_login_token_info.audience = gaia_urls->oauth2_chrome_client_id();
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_->IssueOAuthToken(kTestRefreshToken, auth_login_token_info);
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CheckSessionState(OAuth2LoginManager::SessionRestoreState state) {
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OAuth2LoginManager* login_manager =
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         OAuth2LoginManagerFactory::GetInstance()->GetForProfile(
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             profile());
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_EQ(state, login_manager->state());
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WaitForMergeSessionCompletion(
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      OAuth2LoginManager::SessionRestoreState final_state) {
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Wait for the session merge to finish.
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::set<OAuth2LoginManager::SessionRestoreState> states;
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    states.insert(OAuth2LoginManager::SESSION_RESTORE_DONE);
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    states.insert(OAuth2LoginManager::SESSION_RESTORE_FAILED);
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    states.insert(OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED);
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OAuth2LoginManagerStateWaiter merge_session_waiter(profile());
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    merge_session_waiter.WaitForStates(states);
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(merge_session_waiter.final_state(), final_state);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void StartNewUserSession(bool wait_for_merge) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetupGaiaServerForNewAccount();
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SimulateNetworkOnline();
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chromeos::WizardController::SkipPostLoginScreensForTesting();
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chromeos::WizardController* wizard_controller =
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        chromeos::WizardController::default_controller();
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    wizard_controller->SkipToLoginForTesting(LoginScreenContext());
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::WindowedNotificationObserver(
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::NotificationService::AllSources()).Wait();
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Use capitalized and dotted user name on purpose to make sure
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // our email normalization kicks in.
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetLoginDisplay()->ShowSigninScreenForCreds(kTestRawAccountId,
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                kTestAccountPassword);
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::WindowedNotificationObserver(
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      chrome::NOTIFICATION_SESSION_STARTED,
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::NotificationService::AllSources()).Wait();
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (wait_for_merge) {
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Wait for the session merge to finish.
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE);
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OAuth2Test);
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CookieReader : public base::RefCountedThreadSafe<CookieReader> {
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CookieReader() {
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ReadCookies(Profile* profile) {
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context_ = profile->GetRequestContext();
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::BrowserThread::PostTask(
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::BrowserThread::IO, FROM_HERE,
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&CookieReader::ReadCookiesOnIOThread,
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   this));
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_ = new content::MessageLoopRunner;
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_->Run();
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string GetCookieValue(const std::string& name) {
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (std::vector<net::CanonicalCookie>::const_iterator iter =
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             cookie_list_.begin();
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        iter != cookie_list_.end();
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ++iter) {
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (iter->Name() == name) {
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return iter->Value();
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::string();
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  friend class base::RefCountedThreadSafe<CookieReader>;
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~CookieReader() {
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ReadCookiesOnIOThread() {
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    context_->GetURLRequestContext()->cookie_store()->GetCookieMonster()->
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GetAllCookiesAsync(base::Bind(
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &CookieReader::OnGetAllCookiesOnUIThread,
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            this));
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnGetAllCookiesOnUIThread(const net::CookieList& cookies) {
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cookie_list_ = cookies;
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::BrowserThread::PostTask(
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::BrowserThread::UI, FROM_HERE,
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&CookieReader::OnCookiesReadyOnUIThread,
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   this));
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnCookiesReadyOnUIThread() {
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_->Quit();
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> context_;
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  net::CookieList cookie_list_;
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner_;
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CookieReader);
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// PRE_MergeSession is testing merge session for a new profile.
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_PRE_PRE_MergeSession) {
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartNewUserSession(true);
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check for existance of refresh token.
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ProfileOAuth2TokenService* token_service =
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ProfileOAuth2TokenServiceFactory::GetForProfile(
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            profile());
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(token_service->RefreshTokenIsAvailable(kTestAccountId));
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<CookieReader> cookie_reader(new CookieReader());
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cookie_reader->ReadCookies(profile());
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSessionSIDCookie);
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSessionLSIDCookie);
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// MergeSession test is running merge session process for an existing profile
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that was generated in PRE_PRE_PRE_MergeSession test. In this test, we
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// are not running /MergeSession process since the /ListAccounts call confirms
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that the session is not stale.
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_PRE_MergeSession) {
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetupGaiaServerForUnexpiredAccount();
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SimulateNetworkOnline();
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoginAsExistingUser();
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<CookieReader> cookie_reader(new CookieReader());
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cookie_reader->ReadCookies(profile());
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // These are still cookie values form the initial session since
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // /ListAccounts
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSessionSIDCookie);
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSessionLSIDCookie);
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// MergeSession test is running merge session process for an existing profile
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that was generated in PRE_PRE_MergeSession test.
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_MergeSession) {
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetupGaiaServerForExpiredAccount();
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SimulateNetworkOnline();
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LoginAsExistingUser();
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<CookieReader> cookie_reader(new CookieReader());
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cookie_reader->ReadCookies(profile());
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // These should be cookie values that we generated by calling /MergeSession,
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // since /ListAccounts should have tell us that the initial session cookies
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // are stale.
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSession2SIDCookie);
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSession2LSIDCookie);
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// MergeSession test is attempting to merge session for an existing profile
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that was generated in PRE_PRE_MergeSession test. This attempt should fail
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// since FakeGaia instance isn't configured to return relevant tokens/cookies.
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This test is flaky, see: crbug.com/408867.
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciIN_PROC_BROWSER_TEST_F(OAuth2Test, DISABLED_MergeSession) {
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SimulateNetworkOnline();
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::WindowedNotificationObserver(
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::NotificationService::AllSources()).Wait();
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  JsExpect("!!document.querySelector('#account-picker')");
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  JsExpect("!!document.querySelector('#pod-row')");
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(TryToLogin(kTestAccountId, kTestAccountPassword));
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait for the session merge to finish.
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_FAILED);
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(GetOAuthStatusFromLocalState(kTestAccountId),
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kGooglePageContent[] =
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "<html><title>Hello!</title><script>alert('hello');</script>"
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "<body>Hello Google!</body></html>";
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kRandomPageContent[] =
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "<html><title>SomthingElse</title><body>I am SomethingElse</body></html>";
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kHelloPagePath[] = "/hello_google";
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kRandomPagePath[] = "/non_google_page";
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// FakeGoogle serves content of http://www.google.com/hello_google page for
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// merge session tests.
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FakeGoogle {
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeGoogle() : start_event_(true, false) {
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~FakeGoogle() {}
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // The scheme and host of the URL is actually not important but required to
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // get a valid GURL in order to parse |request.relative_url|.
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GURL request_url = GURL("http://localhost").Resolve(request.relative_url);
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(WARNING) << "Requesting page " << request.relative_url;
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string request_path = request_url.path();
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse());
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (request_path == kHelloPagePath) {  // Serving "google" page.
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      start_event_.Signal();
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::BrowserThread::PostTask(
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          content::BrowserThread::UI, FROM_HERE,
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&FakeGoogle::QuitRunnerOnUIThread,
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::Unretained(this)));
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      http_response->set_code(net::HTTP_OK);
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      http_response->set_content_type("text/html");
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      http_response->set_content(kGooglePageContent);
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else if (request_path == kRandomPagePath) {  // Serving "non-google" page.
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      http_response->set_code(net::HTTP_OK);
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      http_response->set_content_type("text/html");
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      http_response->set_content(kRandomPageContent);
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return scoped_ptr<HttpResponse>();      // Request not understood.
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return http_response.PassAs<HttpResponse>();
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // True if we have already served the test page.
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool IsPageRequested () {
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return start_event_.IsSignaled();
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Waits until we receive a request to serve the test page.
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WaitForPageRequest() {
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // If we have already served the request, bail out.
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (start_event_.IsSignaled())
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_ = new content::MessageLoopRunner;
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_->Run();
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void QuitRunnerOnUIThread() {
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (runner_.get())
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      runner_->Quit();
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This event will tell us when we actually see HTTP request on the server
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // side. It should be signalled only after the page/XHR throttle had been
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // removed (after merge session completes).
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::WaitableEvent start_event_;
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner_;
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeGoogle);
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// FakeGaia specialization that can delay /MergeSession handler until
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// we explicitly call DelayedFakeGaia::UnblockMergeSession().
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DelayedFakeGaia : public FakeGaia {
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DelayedFakeGaia()
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)     : blocking_event_(true, false),
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       start_event_(true, false) {
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void UnblockMergeSession() {
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blocking_event_.Signal();
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WaitForMergeSessionToStart() {
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // If we have already served the request, bail out.
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (start_event_.IsSignaled())
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_ = new content::MessageLoopRunner;
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    runner_->Run();
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // FakeGaia overrides.
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void HandleMergeSession(const HttpRequest& request,
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  BasicHttpResponse* http_response) OVERRIDE {
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    start_event_.Signal();
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::BrowserThread::PostTask(
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::BrowserThread::UI, FROM_HERE,
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&DelayedFakeGaia::QuitRunnerOnUIThread,
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(this)));
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    blocking_event_.Wait();
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FakeGaia::HandleMergeSession(request, http_response);
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void QuitRunnerOnUIThread() {
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (runner_.get())
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      runner_->Quit();
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::WaitableEvent blocking_event_;
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::WaitableEvent start_event_;
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner_;
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DelayedFakeGaia);
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MergeSessionTest : public OAuth2Test {
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MergeSessionTest() : delayed_fake_gaia_(new DelayedFakeGaia()) {
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_gaia_.reset(delayed_fake_gaia_);
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OAuth2Test::SetUpCommandLine(command_line);
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Get fake URL for fake google.com.
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& server_url = embedded_test_server()->base_url();
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string google_host("www.google.com");
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GURL::Replacements replace_google_host;
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    replace_google_host.SetHostStr(google_host);
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GURL google_url = server_url.ReplaceComponents(replace_google_host);
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fake_google_page_url_ = google_url.Resolve(kHelloPagePath);
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string non_google_host("www.somethingelse.org");
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GURL::Replacements replace_non_google_host;
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    replace_non_google_host.SetHostStr(non_google_host);
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GURL non_google_url = server_url.ReplaceComponents(replace_non_google_host);
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    non_google_page_url_ = non_google_url.Resolve(kRandomPagePath);
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    embedded_test_server()->RegisterRequestHandler(
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&FakeGoogle::HandleRequest,
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(&fake_google_)));
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    OAuth2Test::SetUp();
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void UnblockMergeSession() {
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delayed_fake_gaia_->UnblockMergeSession();
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void WaitForMergeSessionToStart() {
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delayed_fake_gaia_->WaitForMergeSessionToStart();
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void JsExpect(content::WebContents* contents,
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                const std::string& expression) {
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool result;
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        contents,
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "window.domAutomationController.send(!!(" + expression + "));",
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         &result));
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(result) << expression;
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL& GetBackGroundPageUrl(const std::string& extension_id) {
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extensions::ProcessManager* manager =
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        extensions::ExtensionSystem::Get(profile())->process_manager();
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extensions::ExtensionHost* host =
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        manager->GetBackgroundHostForExtension(extension_id);
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return host->host_contents()->GetURL();
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void JsExpectOnBackgroundPage(const std::string& extension_id,
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                const std::string& expression) {
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extensions::ProcessManager* manager =
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        extensions::ExtensionSystem::Get(profile())->process_manager();
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extensions::ExtensionHost* host =
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        manager->GetBackgroundHostForExtension(extension_id);
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (host == NULL) {
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ADD_FAILURE() << "Extension " << extension_id
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    << " has no background page.";
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    JsExpect(host->host_contents(), expression);
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeGoogle fake_google_;
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DelayedFakeGaia* delayed_fake_gaia_;
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL fake_google_page_url_;
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL non_google_page_url_;
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MergeSessionTest);
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Browser* FindOrCreateVisibleBrowser(Profile* profile) {
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome::ScopedTabbedBrowserDisplayer displayer(
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile, chrome::GetActiveDesktop());
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Browser* browser = displayer.browser();
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (browser->tab_strip_model()->count() == 0)
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    chrome::AddTabAt(browser, GURL(), -1, true);
6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return browser;
6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MergeSessionTest, PageThrottle) {
6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartNewUserSession(false);
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Try to open a page from google.com.
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Browser* browser =
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FindOrCreateVisibleBrowser(profile());
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      browser,
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fake_google_page_url_,
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait until we get send merge session request.
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitForMergeSessionToStart();
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make sure the page is blocked by the throttle.
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fake_google_.IsPageRequested());
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check that throttle page is displayed instead.
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 title;
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_test_utils::GetCurrentTabTitle(browser, &title);
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Loaded page at the start : " << title;
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Unblock GAIA request.
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UnblockMergeSession();
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait for the session merge to finish.
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE);
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make sure the test page is served.
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fake_google_.WaitForPageRequest();
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check that real page is no longer blocked by the throttle and that the
7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // real page pops up JS dialog.
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(dialog->IsJavaScriptModalDialog());
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  JavaScriptAppModalDialog* js_dialog =
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<JavaScriptAppModalDialog*>(dialog);
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  js_dialog->native_dialog()->AcceptAppModalDialog();
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui_test_utils::GetCurrentTabTitle(browser, &title);
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "Loaded page at the end : " << title;
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MergeSessionTest, XHRThrottle) {
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StartNewUserSession(false);
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait until we get send merge session request.
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitForMergeSessionToStart();
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Reset ExtensionBrowserTest::observer_ to the right browser object.
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Browser* browser = FindOrCreateVisibleBrowser(profile());
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  observer_.reset(new ExtensionTestNotificationObserver(browser));
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Run background page tests. The tests will just wait for XHR request
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to complete.
7491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extensions::ResultCatcher catcher;
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<ExtensionTestMessageListener> non_google_xhr_listener(
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new ExtensionTestMessageListener("non-google-xhr-received", false));
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Load extension with a background page. The background page will
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // attempt to load |fake_google_page_url_| via XHR.
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::Extension* ext = LoadExtension(
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test_data_dir_.AppendASCII("merge_session"));
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(ext);
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Kick off XHR request from the extension.
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  JsExpectOnBackgroundPage(
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ext->id(),
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::StringPrintf("startThrottledTests('%s', '%s')",
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         fake_google_page_url_.spec().c_str(),
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         non_google_page_url_.spec().c_str()));
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that we've sent XHR request form the extension side...
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  JsExpectOnBackgroundPage(ext->id(),
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           "googleRequestSent && !googleResponseReceived");
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ...but didn't see it on the server side yet.
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(fake_google_.IsPageRequested());
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Unblock GAIA request.
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UnblockMergeSession();
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait for the session merge to finish.
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE);
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Wait until non-google XHR content to load first.
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(non_google_xhr_listener->WaitUntilSatisfied());
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!catcher.GetNextResult()) {
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string message = catcher.message();
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ADD_FAILURE() << "Tests failed: " << message;
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(fake_google_.IsPageRequested());
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace chromeos
792