drive_first_run_browsertest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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
25namespace chromeos {
26
27namespace {
28
29// Directory containing data files for the tests.
30const char kTestDirectory[] = "drive_first_run";
31
32// Directory containing correct hosted app page served by the test server.
33const char kGoodServerDirectory[] = "good";
34
35// Directory containing incorrect hosted app page served by the test server.
36const char kBadServerDirectory[] = "bad";
37
38// Name of the test hosted app .crx file.
39const char kTestAppCrxName[] = "app.crx";
40
41// App id of the test hosted app.
42const char kTestAppId[] = "kipccbklifbfblhpplnmklieangbjnhb";
43
44// The endpoint belonging to the test hosted app.
45const char kTestEndpointUrl[] = "http://example.com/endpoint.html";
46
47}  // namespace
48
49class DriveFirstRunTest : public InProcessBrowserTest,
50                          public DriveFirstRunController::Observer {
51 protected:
52  DriveFirstRunTest();
53
54  // InProcessBrowserTest overrides:
55  virtual void SetUpOnMainThread() OVERRIDE;
56  virtual void CleanUpOnMainThread() 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
86DriveFirstRunTest::DriveFirstRunTest() :
87    timed_out_(false),
88    waiting_for_result_(false),
89    success_(false) {}
90
91void 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
105void DriveFirstRunTest::CleanUpOnMainThread() {
106  InProcessBrowserTest::CleanUpOnMainThread();
107  content::RunAllPendingInMessageLoop();
108}
109
110void DriveFirstRunTest::InitTestServer(const std::string& directory) {
111  embedded_test_server()->ServeFilesFromDirectory(
112      test_data_dir_.AppendASCII(directory));
113  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
114
115  // Configure the endpoint to use the test server's port.
116  const GURL url(kTestEndpointUrl);
117  GURL::Replacements replacements;
118  std::string port(base::IntToString(embedded_test_server()->port()));
119  replacements.SetPortStr(port);
120  endpoint_url_ = url.ReplaceComponents(replacements).spec();
121  controller_->SetAppInfoForTest(kTestAppId, endpoint_url_);
122}
123
124void DriveFirstRunTest::InstallApp() {
125  ExtensionService* extension_service = extensions::ExtensionSystem::Get(
126      browser()->profile())->extension_service();
127  scoped_refptr<extensions::CrxInstaller> installer =
128      extensions::CrxInstaller::CreateSilent(extension_service);
129
130  installer->InstallCrx(test_data_dir_.AppendASCII(kTestAppCrxName));
131  ExtensionTestNotificationObserver observer(browser());
132  observer.WaitForExtensionLoad();
133
134  ASSERT_TRUE(extension_service->GetExtensionById(kTestAppId, false));
135}
136
137void DriveFirstRunTest::EnableOfflineMode() {
138  controller_->EnableOfflineMode();
139}
140
141void DriveFirstRunTest::SetDelays(int initial_delay_secs, int timeout_secs) {
142  controller_->SetDelaysForTest(initial_delay_secs, timeout_secs);
143}
144
145bool DriveFirstRunTest::WaitForFirstRunResult() {
146  waiting_for_result_ = true;
147  runner_ = new content::MessageLoopRunner;
148  runner_->Run();
149  EXPECT_FALSE(waiting_for_result_);
150  return success_;
151}
152
153void DriveFirstRunTest::OnCompletion(bool success) {
154  EXPECT_TRUE(waiting_for_result_);
155  waiting_for_result_ = false;
156  success_ = success;
157  runner_->Quit();
158
159  // |controller_| will eventually delete itself upon completion, so invalidate
160  // the pointer.
161  controller_ = NULL;
162}
163
164void DriveFirstRunTest::OnTimedOut() {
165  timed_out_ = true;
166}
167
168IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, OfflineEnabled) {
169  InstallApp();
170  InitTestServer(kGoodServerDirectory);
171  EnableOfflineMode();
172  EXPECT_TRUE(WaitForFirstRunResult());
173}
174
175IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, AppNotInstalled) {
176  InitTestServer(kGoodServerDirectory);
177  EnableOfflineMode();
178  EXPECT_FALSE(WaitForFirstRunResult());
179  EXPECT_FALSE(timed_out());
180}
181
182IN_PROC_BROWSER_TEST_F(DriveFirstRunTest, TimedOut) {
183  // Test that the controller times out instead of hanging forever.
184  InstallApp();
185  InitTestServer(kBadServerDirectory);
186  SetDelays(0, 0);
187  EnableOfflineMode();
188  EXPECT_FALSE(WaitForFirstRunResult());
189  EXPECT_TRUE(timed_out());
190}
191
192}  // namespace chromeos
193