Home | History | Annotate | Download | only in first_run
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/bind.h"
      6 #include "base/files/file_path.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/path_service.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "chrome/browser/chromeos/first_run/drive_first_run_controller.h"
     12 #include "chrome/browser/extensions/crx_installer.h"
     13 #include "chrome/browser/extensions/extension_service.h"
     14 #include "chrome/browser/extensions/extension_test_notification_observer.h"
     15 #include "chrome/common/chrome_paths.h"
     16 #include "chrome/test/base/in_process_browser_test.h"
     17 #include "content/public/test/test_utils.h"
     18 #include "extensions/browser/extension_system.h"
     19 #include "net/dns/mock_host_resolver.h"
     20 #include "net/http/http_status_code.h"
     21 #include "net/test/embedded_test_server/embedded_test_server.h"
     22 #include "net/test/embedded_test_server/http_request.h"
     23 #include "net/test/embedded_test_server/http_response.h"
     24 
     25 namespace chromeos {
     26 
     27 namespace {
     28 
     29 // Directory containing data files for the tests.
     30 const char kTestDirectory[] = "drive_first_run";
     31 
     32 // Directory containing correct hosted app page served by the test server.
     33 const char kGoodServerDirectory[] = "good";
     34 
     35 // Directory containing incorrect hosted app page served by the test server.
     36 const char kBadServerDirectory[] = "bad";
     37 
     38 // Name of the test hosted app .crx file.
     39 const char kTestAppCrxName[] = "app.crx";
     40 
     41 // App id of the test hosted app.
     42 const char kTestAppId[] = "kipccbklifbfblhpplnmklieangbjnhb";
     43 
     44 // The endpoint belonging to the test hosted app.
     45 const char kTestEndpointUrl[] = "http://example.com/endpoint.html";
     46 
     47 }  // namespace
     48 
     49 class DriveFirstRunTest : public InProcessBrowserTest,
     50                           public DriveFirstRunController::Observer {
     51  protected:
     52   DriveFirstRunTest();
     53 
     54   // InProcessBrowserTest overrides:
     55   virtual void SetUpOnMainThread() OVERRIDE;
     56   virtual void TearDownOnMainThread() OVERRIDE;
     57 
     58   // DriveFirstRunController::Observer overrides:
     59   virtual void OnCompletion(bool success) OVERRIDE;
     60   virtual void OnTimedOut() OVERRIDE;
     61 
     62   void InstallApp();
     63 
     64   void InitTestServer(const std::string& directory);
     65 
     66   bool WaitForFirstRunResult();
     67 
     68   void EnableOfflineMode();
     69 
     70   void SetDelays(int initial_delay_secs, int timeout_secs);
     71 
     72   bool timed_out() const { return timed_out_; }
     73 
     74  private:
     75   // |controller_| is responsible for its own lifetime.
     76   DriveFirstRunController* controller_;
     77   scoped_refptr<content::MessageLoopRunner> runner_;
     78 
     79   bool timed_out_;
     80   bool waiting_for_result_;
     81   bool success_;
     82   base::FilePath test_data_dir_;
     83   std::string endpoint_url_;
     84 };
     85 
     86 DriveFirstRunTest::DriveFirstRunTest() :
     87     timed_out_(false),
     88     waiting_for_result_(false),
     89     success_(false) {}
     90 
     91 void DriveFirstRunTest::SetUpOnMainThread() {
     92   InProcessBrowserTest::SetUpOnMainThread();
     93   PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
     94   test_data_dir_ = test_data_dir_.AppendASCII(kTestDirectory);
     95 
     96   host_resolver()->AddRule("example.com", "127.0.0.1");
     97 
     98   // |controller_| will delete itself when it completes.
     99   controller_ = new DriveFirstRunController(browser()->profile());
    100   controller_->AddObserver(this);
    101   controller_->SetDelaysForTest(0, 10);
    102   controller_->SetAppInfoForTest(kTestAppId, kTestEndpointUrl);
    103 }
    104 
    105 void DriveFirstRunTest::TearDownOnMainThread() {
    106   content::RunAllPendingInMessageLoop();
    107 }
    108 
    109 void DriveFirstRunTest::InitTestServer(const std::string& directory) {
    110   embedded_test_server()->ServeFilesFromDirectory(
    111       test_data_dir_.AppendASCII(directory));
    112   ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    113 
    114   // Configure the endpoint to use the test server's port.
    115   const GURL url(kTestEndpointUrl);
    116   GURL::Replacements replacements;
    117   std::string port(base::IntToString(embedded_test_server()->port()));
    118   replacements.SetPortStr(port);
    119   endpoint_url_ = url.ReplaceComponents(replacements).spec();
    120   controller_->SetAppInfoForTest(kTestAppId, endpoint_url_);
    121 }
    122 
    123 void DriveFirstRunTest::InstallApp() {
    124   ExtensionService* extension_service = extensions::ExtensionSystem::Get(
    125       browser()->profile())->extension_service();
    126   scoped_refptr<extensions::CrxInstaller> installer =
    127       extensions::CrxInstaller::CreateSilent(extension_service);
    128 
    129   installer->InstallCrx(test_data_dir_.AppendASCII(kTestAppCrxName));
    130   ExtensionTestNotificationObserver observer(browser());
    131   observer.WaitForExtensionLoad();
    132 
    133   ASSERT_TRUE(extension_service->GetExtensionById(kTestAppId, false));
    134 }
    135 
    136 void DriveFirstRunTest::EnableOfflineMode() {
    137   controller_->EnableOfflineMode();
    138 }
    139 
    140 void DriveFirstRunTest::SetDelays(int initial_delay_secs, int timeout_secs) {
    141   controller_->SetDelaysForTest(initial_delay_secs, timeout_secs);
    142 }
    143 
    144 bool DriveFirstRunTest::WaitForFirstRunResult() {
    145   waiting_for_result_ = true;
    146   runner_ = new content::MessageLoopRunner;
    147   runner_->Run();
    148   EXPECT_FALSE(waiting_for_result_);
    149   return success_;
    150 }
    151 
    152 void DriveFirstRunTest::OnCompletion(bool success) {
    153   EXPECT_TRUE(waiting_for_result_);
    154   waiting_for_result_ = false;
    155   success_ = success;
    156   runner_->Quit();
    157 
    158   // |controller_| will eventually delete itself upon completion, so invalidate
    159   // the pointer.
    160   controller_ = NULL;
    161 }
    162 
    163 void DriveFirstRunTest::OnTimedOut() {
    164   timed_out_ = true;
    165 }
    166 
    167 IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, OfflineEnabled) {
    168   InstallApp();
    169   InitTestServer(kGoodServerDirectory);
    170   EnableOfflineMode();
    171   EXPECT_TRUE(WaitForFirstRunResult());
    172 }
    173 
    174 IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, AppNotInstalled) {
    175   InitTestServer(kGoodServerDirectory);
    176   EnableOfflineMode();
    177   EXPECT_FALSE(WaitForFirstRunResult());
    178   EXPECT_FALSE(timed_out());
    179 }
    180 
    181 IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, TimedOut) {
    182   // Test that the controller times out instead of hanging forever.
    183   InstallApp();
    184   InitTestServer(kBadServerDirectory);
    185   SetDelays(0, 0);
    186   EnableOfflineMode();
    187   EXPECT_FALSE(WaitForFirstRunResult());
    188   EXPECT_TRUE(timed_out());
    189 }
    190 
    191 }  // namespace chromeos
    192