// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/background/background_mode_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/cookie_settings.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_impl.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sessions/session_backend.h"
#include "chrome/browser/sessions/session_service_factory.h"
#include "chrome/browser/sessions/session_service_test_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/content_settings.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/net_util.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_data_stream.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_test_job.h"

#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#endif

namespace {

Browser* FindOneOtherBrowserForProfile(Profile* profile,
                                       Browser* not_this_browser) {
  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
    if (*it != not_this_browser && it->profile() == profile)
      return *it;
  }
  return NULL;
}

// We need to serve the test files so that PRE_Test and Test can access the same
// page using the same URL. In addition, perceived security origin of the page
// needs to stay the same, so e.g., redirecting the URL requests doesn't
// work. (If we used a test server, the PRE_Test and Test would have separate
// instances running on separate ports.)

base::LazyInstance<std::map<std::string, std::string> > g_file_contents =
    LAZY_INSTANCE_INITIALIZER;

net::URLRequestJob* URLRequestFaker(
    net::URLRequest* request,
    net::NetworkDelegate* network_delegate,
    const std::string& scheme) {
  return new net::URLRequestTestJob(
      request, network_delegate, net::URLRequestTestJob::test_headers(),
      g_file_contents.Get()[request->url().path()], true);
}

base::LazyInstance<std::string> g_last_upload_bytes = LAZY_INSTANCE_INITIALIZER;

net::URLRequestJob* URLRequestFakerForPostRequests(
    net::URLRequest* request,
    net::NetworkDelegate* network_delegate,
    const std::string& scheme) {
  // Read the uploaded data and store it to g_last_upload_bytes.
  const net::UploadDataStream* upload_data = request->get_upload();
  g_last_upload_bytes.Get().clear();
  if (upload_data) {
    const ScopedVector<net::UploadElementReader>& readers =
        upload_data->element_readers();
    for (size_t i = 0; i < readers.size(); ++i) {
      const net::UploadBytesElementReader* bytes_reader =
          readers[i]->AsBytesReader();
      if (bytes_reader) {
        g_last_upload_bytes.Get() +=
            std::string(bytes_reader->bytes(), bytes_reader->length());
      }
    }
  }
  return new net::URLRequestTestJob(
      request, network_delegate, net::URLRequestTestJob::test_headers(),
      "<html><head><title>PASS</title></head><body>Data posted</body></html>",
      true);
}

class FakeBackgroundModeManager : public BackgroundModeManager {
 public:
  FakeBackgroundModeManager()
      : BackgroundModeManager(
            CommandLine::ForCurrentProcess(),
            &g_browser_process->profile_manager()->GetProfileInfoCache()),
        background_mode_active_(false) {}

  void SetBackgroundModeActive(bool active) {
    background_mode_active_ = active;
  }

  virtual bool IsBackgroundModeActive() OVERRIDE {
    return background_mode_active_;
  }

 private:
  bool background_mode_active_;

};

}  // namespace

class BetterSessionRestoreTest : public InProcessBrowserTest {
 public:
  BetterSessionRestoreTest()
      : fake_server_address_("http://www.test.com/"),
        test_path_("session_restore/"),
        title_pass_(ASCIIToUTF16("PASS")),
        title_storing_(ASCIIToUTF16("STORING")),
        title_error_write_failed_(ASCIIToUTF16("ERROR_WRITE_FAILED")),
        title_error_empty_(ASCIIToUTF16("ERROR_EMPTY")) {
    // Set up the URL request filtering.
    std::vector<std::string> test_files;
    test_files.push_back("common.js");
    test_files.push_back("cookies.html");
    test_files.push_back("local_storage.html");
    test_files.push_back("post.html");
    test_files.push_back("post_with_password.html");
    test_files.push_back("session_cookies.html");
    test_files.push_back("session_storage.html");
    base::FilePath test_file_dir;
    CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &test_file_dir));
    test_file_dir =
        test_file_dir.AppendASCII("chrome/test/data").AppendASCII(test_path_);

    for (std::vector<std::string>::const_iterator it = test_files.begin();
         it != test_files.end(); ++it) {
      base::FilePath path = test_file_dir.AppendASCII(*it);
      std::string contents;
      CHECK(base::ReadFileToString(path, &contents));
      g_file_contents.Get()["/" + test_path_ + *it] = contents;
      net::URLRequestFilter::GetInstance()->AddUrlHandler(
          GURL(fake_server_address_ + test_path_ + *it),
          &URLRequestFaker);
    }
    net::URLRequestFilter::GetInstance()->AddUrlHandler(
        GURL(fake_server_address_ + test_path_ + "posted.php"),
        &URLRequestFakerForPostRequests);
  }

 protected:
  virtual void SetUpOnMainThread() OVERRIDE {
    SessionServiceTestHelper helper(
        SessionServiceFactory::GetForProfile(browser()->profile()));
    helper.SetForceBrowserNotAliveWithNoWindows(true);
    helper.ReleaseService();
    g_browser_process->set_background_mode_manager_for_test(
        scoped_ptr<BackgroundModeManager>(new FakeBackgroundModeManager));
  }

  void StoreDataWithPage(const std::string& filename) {
    StoreDataWithPage(browser(), filename);
  }

  void StoreDataWithPage(Browser* browser, const std::string& filename) {
    content::WebContents* web_contents =
        browser->tab_strip_model()->GetActiveWebContents();
    content::TitleWatcher title_watcher(web_contents, title_storing_);
    title_watcher.AlsoWaitForTitle(title_pass_);
    title_watcher.AlsoWaitForTitle(title_error_write_failed_);
    title_watcher.AlsoWaitForTitle(title_error_empty_);
    ui_test_utils::NavigateToURL(
        browser, GURL(fake_server_address_ + test_path_ + filename));
    string16 final_title = title_watcher.WaitAndGetTitle();
    EXPECT_EQ(title_storing_, final_title);
  }

  void NavigateAndCheckStoredData(const std::string& filename) {
    NavigateAndCheckStoredData(browser(), filename);
  }

  void NavigateAndCheckStoredData(Browser* browser,
                                  const std::string& filename) {
    // Navigate to a page which has previously stored data; check that the
    // stored data can be accessed.
    content::WebContents* web_contents =
        browser->tab_strip_model()->GetActiveWebContents();
    content::TitleWatcher title_watcher(web_contents, title_pass_);
    title_watcher.AlsoWaitForTitle(title_storing_);
    title_watcher.AlsoWaitForTitle(title_error_write_failed_);
    title_watcher.AlsoWaitForTitle(title_error_empty_);
    ui_test_utils::NavigateToURL(
        browser, GURL(fake_server_address_ + test_path_ + filename));
    string16 final_title = title_watcher.WaitAndGetTitle();
    EXPECT_EQ(title_pass_, final_title);
  }

  void CheckReloadedPageRestored() {
    CheckTitle(browser(), title_pass_);
  }

  void CheckReloadedPageRestored(Browser* browser) {
    CheckTitle(browser, title_pass_);
  }

  void CheckReloadedPageNotRestored() {
    CheckReloadedPageNotRestored(browser());
  }

  void CheckReloadedPageNotRestored(Browser* browser) {
    CheckTitle(browser, title_storing_);
  }

  void CheckTitle(Browser* browser, const string16& expected_title) {
    content::WebContents* web_contents =
        browser->tab_strip_model()->GetWebContentsAt(0);
    content::TitleWatcher title_watcher(web_contents, expected_title);
    title_watcher.AlsoWaitForTitle(title_pass_);
    title_watcher.AlsoWaitForTitle(title_storing_);
    title_watcher.AlsoWaitForTitle(title_error_write_failed_);
    title_watcher.AlsoWaitForTitle(title_error_empty_);
    // It's possible that the title was already the right one before
    // title_watcher was created.
    string16 first_title = web_contents->GetTitle();
    if (first_title != title_pass_ &&
        first_title != title_storing_ &&
        first_title != title_error_write_failed_ &&
        first_title != title_error_empty_) {
      string16 final_title = title_watcher.WaitAndGetTitle();
      EXPECT_EQ(expected_title, final_title);
    } else {
      EXPECT_EQ(expected_title, first_title);
    }
  }

  void PostFormWithPage(const std::string& filename, bool password_present) {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    content::TitleWatcher title_watcher(web_contents, title_pass_);
    ui_test_utils::NavigateToURL(
        browser(), GURL(fake_server_address_ + test_path_ + filename));
    string16 final_title = title_watcher.WaitAndGetTitle();
    EXPECT_EQ(title_pass_, final_title);
    EXPECT_TRUE(g_last_upload_bytes.Get().find("posted-text") !=
                std::string::npos);
    EXPECT_TRUE(g_last_upload_bytes.Get().find("text-entered") !=
                std::string::npos);
    if (password_present) {
      EXPECT_TRUE(g_last_upload_bytes.Get().find("posted-password") !=
                  std::string::npos);
      EXPECT_TRUE(g_last_upload_bytes.Get().find("password-entered") !=
                  std::string::npos);
    }
  }

  void CheckFormRestored(bool text_present, bool password_present) {
    CheckFormRestored(browser(), text_present, password_present);
  }

  void CheckFormRestored(
      Browser* browser, bool text_present, bool password_present) {
    CheckReloadedPageRestored(browser);
    if (text_present) {
      EXPECT_TRUE(g_last_upload_bytes.Get().find("posted-text") !=
                  std::string::npos);
      EXPECT_TRUE(g_last_upload_bytes.Get().find("text-entered") !=
                  std::string::npos);
    } else {
      EXPECT_TRUE(g_last_upload_bytes.Get().find("posted-text") ==
                  std::string::npos);
      EXPECT_TRUE(g_last_upload_bytes.Get().find("text-entered") ==
                  std::string::npos);
    }
    if (password_present) {
      EXPECT_TRUE(g_last_upload_bytes.Get().find("posted-password") !=
                  std::string::npos);
      EXPECT_TRUE(g_last_upload_bytes.Get().find("password-entered") !=
                  std::string::npos);
    } else {
      EXPECT_TRUE(g_last_upload_bytes.Get().find("posted-password") ==
                  std::string::npos);
      EXPECT_TRUE(g_last_upload_bytes.Get().find("password-entered") ==
                  std::string::npos);
    }
  }

  void CloseBrowserSynchronously(Browser* browser) {
    content::WindowedNotificationObserver observer(
        chrome::NOTIFICATION_BROWSER_CLOSED,
        content::NotificationService::AllSources());
    browser->window()->Close();
#if defined(OS_MACOSX)
    // BrowserWindowController depends on the auto release pool being recycled
    // in the message loop to delete itself, which frees the Browser object
    // which fires this event.
    AutoreleasePool()->Recycle();
#endif
    observer.Wait();
  }

  virtual Browser* QuitBrowserAndRestore(Browser* browser) {
    Profile* profile = browser->profile();

    // Close the browser.
    chrome::StartKeepAlive();
    CloseBrowserSynchronously(browser);

    // Create a new window, which should trigger session restore.
    ui_test_utils::BrowserAddedObserver window_observer;
    chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
    Browser* new_browser = window_observer.WaitForSingleNewBrowser();
    chrome::EndKeepAlive();

    return new_browser;
  }

  std::string fake_server_address() {
    return fake_server_address_;
  }

  std::string test_path() {
    return test_path_;
  }

  void EnableBackgroundMode() {
    static_cast<FakeBackgroundModeManager*>(
        g_browser_process->background_mode_manager())->
        SetBackgroundModeActive(true);
  }

  void DisableBackgroundMode() {
    static_cast<FakeBackgroundModeManager*>(
        g_browser_process->background_mode_manager())->
        SetBackgroundModeActive(false);
  }

 private:
  const std::string fake_server_address_;
  const std::string test_path_;
  const string16 title_pass_;
  const string16 title_storing_;
  const string16 title_error_write_failed_;
  const string16 title_error_empty_;

  DISALLOW_COPY_AND_ASSIGN(BetterSessionRestoreTest);
};

class ContinueWhereILeftOffTest : public BetterSessionRestoreTest {
 public:
  ContinueWhereILeftOffTest() { }

  virtual void SetUpOnMainThread() OVERRIDE {
    BetterSessionRestoreTest::SetUpOnMainThread();
    SessionStartupPref::SetStartupPref(
        browser()->profile(), SessionStartupPref(SessionStartupPref::LAST));
  }

 protected:
  virtual Browser* QuitBrowserAndRestore(Browser* browser) OVERRIDE {
    content::WindowedNotificationObserver session_restore_observer(
        chrome::NOTIFICATION_SESSION_RESTORE_DONE,
        content::NotificationService::AllSources());
    Browser* new_browser =
        BetterSessionRestoreTest::QuitBrowserAndRestore(browser);
    session_restore_observer.Wait();
    return new_browser;
  }

  DISALLOW_COPY_AND_ASSIGN(ContinueWhereILeftOffTest);
};

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PRE_SessionCookies) {
  // Set the startup preference to "continue where I left off" and visit a page
  // which stores a session cookie.
  StoreDataWithPage("session_cookies.html");
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, SessionCookies) {
  // The browsing session will be continued; just wait for the page to reload
  // and check the stored data.
  CheckReloadedPageRestored();
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PRE_SessionStorage) {
  StoreDataWithPage("session_storage.html");
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, SessionStorage) {
  CheckReloadedPageRestored();
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
                       PRE_PRE_LocalStorageClearedOnExit) {
  StoreDataWithPage("local_storage.html");
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
                       PRE_LocalStorageClearedOnExit) {
  // Normally localStorage is restored.
  CheckReloadedPageRestored();
  // ... but not if it's set to clear on exit.
  CookieSettings::Factory::GetForProfile(browser()->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, LocalStorageClearedOnExit) {
  CheckReloadedPageNotRestored();
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
                       PRE_PRE_CookiesClearedOnExit) {
  StoreDataWithPage("cookies.html");
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PRE_CookiesClearedOnExit) {
  // Normally cookies are restored.
  CheckReloadedPageRestored();
  // ... but not if the content setting is set to clear on exit.
  CookieSettings::Factory::GetForProfile(browser()->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, CookiesClearedOnExit) {
  CheckReloadedPageNotRestored();
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PRE_Post) {
  PostFormWithPage("post.html", false);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, Post) {
  CheckFormRestored(true, false);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PRE_PostWithPassword) {
  PostFormWithPage("post_with_password.html", true);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PostWithPassword) {
  CheckReloadedPageRestored();
  // The form data contained passwords, so it's removed completely.
  CheckFormRestored(false, false);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, SessionCookiesBrowserClose) {
  // Set the startup preference to "continue where I left off" and visit a page
  // which stores a session cookie.
  StoreDataWithPage("session_cookies.html");
  Browser* new_browser = QuitBrowserAndRestore(browser());
  // The browsing session will be continued; just wait for the page to reload
  // and check the stored data.
  CheckReloadedPageRestored(new_browser);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
                       CookiesClearedOnBrowserClose) {
  StoreDataWithPage("cookies.html");
  // Normally cookies are restored.
  Browser* new_browser = QuitBrowserAndRestore(browser());
  CheckReloadedPageRestored(new_browser);
  // ... but not if the content setting is set to clear on exit.
  CookieSettings::Factory::GetForProfile(new_browser->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
  // ... unless background mode is active.
  EnableBackgroundMode();
  new_browser = QuitBrowserAndRestore(new_browser);
  CheckReloadedPageRestored(new_browser);

  DisableBackgroundMode();
  new_browser = QuitBrowserAndRestore(new_browser);
  if (browser_defaults::kBrowserAliveWithNoWindows)
    CheckReloadedPageRestored(new_browser);
  else
    CheckReloadedPageNotRestored(new_browser);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest, PostBrowserClose) {
  PostFormWithPage("post.html", false);
  Browser* new_browser = QuitBrowserAndRestore(browser());
  CheckFormRestored(new_browser, true, false);
}

IN_PROC_BROWSER_TEST_F(ContinueWhereILeftOffTest,
                       PostWithPasswordBrowserClose) {
  PostFormWithPage("post_with_password.html", true);
  Browser* new_browser = QuitBrowserAndRestore(browser());
  CheckReloadedPageRestored(new_browser);
  // The form data contained passwords, so it's removed completely.
  CheckFormRestored(new_browser, false, false);
}

class RestartTest : public BetterSessionRestoreTest {
 public:
  RestartTest() { }
  virtual ~RestartTest() { }
 protected:
  void Restart() {
    // Simluate restarting the browser, but let the test exit peacefully.
    for (chrome::BrowserIterator it; !it.done(); it.Next())
      content::BrowserContext::SaveSessionState(it->profile());
    PrefService* pref_service = g_browser_process->local_state();
    pref_service->SetBoolean(prefs::kWasRestarted, true);
#if defined(OS_WIN)
    if (pref_service->HasPrefPath(prefs::kRestartSwitchMode))
      pref_service->SetBoolean(prefs::kRestartSwitchMode, false);
#endif
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(RestartTest);
};

IN_PROC_BROWSER_TEST_F(RestartTest, PRE_SessionCookies) {
  StoreDataWithPage("session_cookies.html");
  Restart();
}

IN_PROC_BROWSER_TEST_F(RestartTest, SessionCookies) {
  CheckReloadedPageRestored();
}

IN_PROC_BROWSER_TEST_F(RestartTest, PRE_SessionStorage) {
  StoreDataWithPage("session_storage.html");
  Restart();
}

IN_PROC_BROWSER_TEST_F(RestartTest, SessionStorage) {
  CheckReloadedPageRestored();
}

IN_PROC_BROWSER_TEST_F(RestartTest, PRE_LocalStorageClearedOnExit) {
  StoreDataWithPage("local_storage.html");
  CookieSettings::Factory::GetForProfile(browser()->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
  Restart();
}

IN_PROC_BROWSER_TEST_F(RestartTest, LocalStorageClearedOnExit) {
  CheckReloadedPageRestored();
}

IN_PROC_BROWSER_TEST_F(RestartTest, PRE_CookiesClearedOnExit) {
  StoreDataWithPage("cookies.html");
  CookieSettings::Factory::GetForProfile(browser()->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
  Restart();
}

IN_PROC_BROWSER_TEST_F(RestartTest, CookiesClearedOnExit) {
  CheckReloadedPageRestored();
}

IN_PROC_BROWSER_TEST_F(RestartTest, PRE_Post) {
  PostFormWithPage("post.html", false);
  Restart();
}

IN_PROC_BROWSER_TEST_F(RestartTest, Post) {
  CheckFormRestored(true, false);
}

IN_PROC_BROWSER_TEST_F(RestartTest, PRE_PostWithPassword) {
  PostFormWithPage("post_with_password.html", true);
  Restart();
}

IN_PROC_BROWSER_TEST_F(RestartTest, PostWithPassword) {
  // The form data contained passwords, so it's removed completely.
  CheckFormRestored(false, false);
}

// These tests ensure that the Better Session Restore features are not triggered
// when they shouldn't be.
class NoSessionRestoreTest : public BetterSessionRestoreTest {
 public:
  NoSessionRestoreTest() { }

  virtual void SetUpOnMainThread() OVERRIDE {
    BetterSessionRestoreTest::SetUpOnMainThread();
    SessionStartupPref::SetStartupPref(
        browser()->profile(), SessionStartupPref(SessionStartupPref::DEFAULT));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(NoSessionRestoreTest);
};

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, PRE_SessionCookies) {
  StoreDataWithPage("session_cookies.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, SessionCookies) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(std::string(content::kAboutBlankURL),
            web_contents->GetURL().spec());
  // When we navigate to the page again, it doens't see the data previously
  // stored.
  StoreDataWithPage("session_cookies.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, PRE_SessionStorage) {
  StoreDataWithPage("session_storage.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, SessionStorage) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(std::string(content::kAboutBlankURL),
            web_contents->GetURL().spec());
  StoreDataWithPage("session_storage.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest,
                       PRE_PRE_LocalStorageClearedOnExit) {
  StoreDataWithPage("local_storage.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, PRE_LocalStorageClearedOnExit) {
  // Normally localStorage is persisted.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(std::string(content::kAboutBlankURL),
            web_contents->GetURL().spec());
  NavigateAndCheckStoredData("local_storage.html");
  // ... but not if it's set to clear on exit.
  CookieSettings::Factory::GetForProfile(browser()->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, LocalStorageClearedOnExit) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(std::string(content::kAboutBlankURL),
            web_contents->GetURL().spec());
  StoreDataWithPage("local_storage.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, PRE_PRE_CookiesClearedOnExit) {
  StoreDataWithPage("cookies.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, PRE_CookiesClearedOnExit) {
  // Normally cookies are restored.
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(std::string(content::kAboutBlankURL),
            web_contents->GetURL().spec());
  NavigateAndCheckStoredData("cookies.html");
  // ... but not if the content setting is set to clear on exit.
  CookieSettings::Factory::GetForProfile(browser()->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, CookiesClearedOnExit) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(std::string(content::kAboutBlankURL),
            web_contents->GetURL().spec());
  StoreDataWithPage("local_storage.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, SessionCookiesBrowserClose) {
  StoreDataWithPage("session_cookies.html");
  EnableBackgroundMode();
  Browser* new_browser = QuitBrowserAndRestore(browser());
  NavigateAndCheckStoredData(new_browser, "session_cookies.html");
  DisableBackgroundMode();
  new_browser = QuitBrowserAndRestore(new_browser);
  if (browser_defaults::kBrowserAliveWithNoWindows)
    NavigateAndCheckStoredData(new_browser, "session_cookies.html");
  else
    StoreDataWithPage(new_browser, "session_cookies.html");
}

IN_PROC_BROWSER_TEST_F(NoSessionRestoreTest, CookiesClearedOnBrowserClose) {
  StoreDataWithPage("cookies.html");

  // Normally cookies are restored.
  Browser* new_browser = QuitBrowserAndRestore(browser());
  NavigateAndCheckStoredData(new_browser, "cookies.html");

  // ... but not if the content setting is set to clear on exit.
  CookieSettings::Factory::GetForProfile(new_browser->profile())->
      SetDefaultCookieSetting(CONTENT_SETTING_SESSION_ONLY);
  // ... unless background mode is active.
  EnableBackgroundMode();
  new_browser = QuitBrowserAndRestore(new_browser);
  NavigateAndCheckStoredData(new_browser, "cookies.html");
  DisableBackgroundMode();
  new_browser = QuitBrowserAndRestore(new_browser);
  if (browser_defaults::kBrowserAliveWithNoWindows)
    NavigateAndCheckStoredData(new_browser, "cookies.html");
  else
    StoreDataWithPage(new_browser, "cookies.html");
}
