1// Copyright 2014 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/files/file_path.h"
6#include "chrome/browser/extensions/active_install_data.h"
7#include "chrome/browser/extensions/install_tracker.h"
8#include "chrome/test/base/testing_profile.h"
9#include "extensions/browser/extension_registry.h"
10#include "extensions/common/extension.h"
11#include "extensions/common/manifest_constants.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14using extensions::ActiveInstallData;
15using extensions::Extension;
16using extensions::ExtensionRegistry;
17using extensions::InstallTracker;
18using extensions::InstallObserver;
19using extensions::ScopedActiveInstall;
20
21namespace {
22
23// Random extension ids for testing.
24const char kExtensionId1[] = "oochhailbdickimldhhodijaldpllppf";
25const char kExtensionId2[] = "ahionppacfhbbmpmlcbkdgcpokfpflji";
26const char kExtensionId3[] = "ladmcjmmmmgonboiadnaindoekpbljde";
27
28scoped_refptr<Extension> CreateDummyExtension(const std::string& id) {
29  base::DictionaryValue manifest;
30  manifest.SetString(extensions::manifest_keys::kVersion, "1.0");
31  manifest.SetString(extensions::manifest_keys::kName, "Dummy name");
32
33  std::string error;
34  scoped_refptr<Extension> extension;
35  extension = Extension::Create(base::FilePath(),
36                                extensions::Manifest::INTERNAL,
37                                manifest,
38                                Extension::NO_FLAGS,
39                                id,
40                                &error);
41  EXPECT_TRUE(extension.get()) << "Error creating extension: " << error;
42  return extension;
43}
44
45}  // namespace
46
47class InstallTrackerTest : public testing::Test {
48 public:
49  InstallTrackerTest() {
50    profile_.reset(new TestingProfile());
51    tracker_.reset(new InstallTracker(profile_.get(), NULL));
52  }
53
54  virtual ~InstallTrackerTest() {}
55
56 protected:
57  Profile* profile() { return profile_.get(); }
58  InstallTracker* tracker() { return tracker_.get(); }
59
60  void VerifyInstallData(const ActiveInstallData& original,
61                         const ActiveInstallData& retrieved) {
62    EXPECT_EQ(original.extension_id, retrieved.extension_id);
63    EXPECT_EQ(original.is_ephemeral, retrieved.is_ephemeral);
64    EXPECT_EQ(original.percent_downloaded, retrieved.percent_downloaded);
65  }
66
67  scoped_ptr<TestingProfile> profile_;
68  scoped_ptr<InstallTracker> tracker_;
69};
70
71// Verifies that active installs are registered and deregistered correctly.
72TEST_F(InstallTrackerTest, AddAndRemoveActiveInstalls) {
73  ActiveInstallData install_data1(kExtensionId1);
74  install_data1.percent_downloaded = 76;
75  ActiveInstallData install_data2(kExtensionId2);
76  install_data2.is_ephemeral = true;
77
78  tracker_->AddActiveInstall(install_data1);
79  tracker_->AddActiveInstall(install_data2);
80
81  const ActiveInstallData* retrieved_data1 =
82      tracker_->GetActiveInstall(kExtensionId1);
83  const ActiveInstallData* retrieved_data2 =
84      tracker_->GetActiveInstall(kExtensionId2);
85  const ActiveInstallData* retrieved_data3 =
86      tracker_->GetActiveInstall(kExtensionId3);
87  ASSERT_TRUE(retrieved_data1);
88  ASSERT_TRUE(retrieved_data2);
89  ASSERT_FALSE(retrieved_data3);
90  VerifyInstallData(install_data1, *retrieved_data1);
91  VerifyInstallData(install_data2, *retrieved_data2);
92  retrieved_data1 = NULL;
93  retrieved_data2 = NULL;
94
95  tracker_->RemoveActiveInstall(kExtensionId1);
96  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
97  EXPECT_TRUE(tracker_->GetActiveInstall(kExtensionId2));
98  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId3));
99}
100
101// Verifies that active installs are registered and deregistered correctly
102// using ScopedActiveInstall.
103TEST_F(InstallTrackerTest, ScopedActiveInstallDeregister) {
104  // Verify the constructor that registers the install.
105  ActiveInstallData install_data(kExtensionId1);
106  install_data.percent_downloaded = 6;
107  scoped_ptr<ScopedActiveInstall> scoped_active_install(
108      new ScopedActiveInstall(tracker(), install_data));
109
110  const ActiveInstallData* retrieved_data =
111      tracker_->GetActiveInstall(kExtensionId1);
112  ASSERT_TRUE(retrieved_data);
113  VerifyInstallData(install_data, *retrieved_data);
114  retrieved_data = NULL;
115
116  scoped_active_install.reset();
117  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
118
119  // Verify the constructor that doesn't register the install.
120  scoped_active_install.reset(
121      new ScopedActiveInstall(tracker(), kExtensionId1));
122  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
123
124  tracker_->AddActiveInstall(install_data);
125  EXPECT_TRUE(tracker_->GetActiveInstall(kExtensionId1));
126
127  scoped_active_install.reset();
128  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
129}
130
131// Verifies that ScopedActiveInstall can be cancelled.
132TEST_F(InstallTrackerTest, ScopedActiveInstallCancelled) {
133  ActiveInstallData install_data(kExtensionId1);
134  install_data.percent_downloaded = 87;
135  scoped_ptr<ScopedActiveInstall> scoped_active_install(
136      new ScopedActiveInstall(tracker(), install_data));
137
138  const ActiveInstallData* retrieved_data =
139      tracker_->GetActiveInstall(kExtensionId1);
140  ASSERT_TRUE(retrieved_data);
141  VerifyInstallData(install_data, *retrieved_data);
142  retrieved_data = NULL;
143
144  scoped_active_install->CancelDeregister();
145  scoped_active_install.reset();
146
147  retrieved_data = tracker_->GetActiveInstall(kExtensionId1);
148  ASSERT_TRUE(retrieved_data);
149  VerifyInstallData(install_data, *retrieved_data);
150}
151
152// Verifies that the download progress is updated correctly.
153TEST_F(InstallTrackerTest, DownloadProgressUpdated) {
154  ActiveInstallData install_data(kExtensionId1);
155  tracker_->AddActiveInstall(install_data);
156
157  const ActiveInstallData* retrieved_data =
158      tracker_->GetActiveInstall(kExtensionId1);
159  ASSERT_TRUE(retrieved_data);
160  EXPECT_EQ(0, retrieved_data->percent_downloaded);
161
162  const int kUpdatedDownloadProgress = 23;
163  tracker_->OnDownloadProgress(kExtensionId1, kUpdatedDownloadProgress);
164
165  retrieved_data = tracker_->GetActiveInstall(kExtensionId1);
166  ASSERT_TRUE(retrieved_data);
167  EXPECT_EQ(kUpdatedDownloadProgress, retrieved_data->percent_downloaded);
168}
169
170// Verifies that OnBeginExtensionInstall() registers an active install and
171// OnInstallFailure() removes an active install.
172TEST_F(InstallTrackerTest, ExtensionInstallFailure) {
173  InstallObserver::ExtensionInstallParams install_params(
174      kExtensionId1, std::string(), gfx::ImageSkia(), false, false);
175  install_params.is_ephemeral = true;
176  tracker_->OnBeginExtensionInstall(install_params);
177
178  const ActiveInstallData* retrieved_data =
179      tracker_->GetActiveInstall(kExtensionId1);
180  ASSERT_TRUE(retrieved_data);
181  EXPECT_EQ(0, retrieved_data->percent_downloaded);
182  EXPECT_EQ(install_params.extension_id, retrieved_data->extension_id);
183  EXPECT_EQ(install_params.is_ephemeral, retrieved_data->is_ephemeral);
184  retrieved_data = NULL;
185
186  tracker_->OnInstallFailure(kExtensionId1);
187  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
188}
189
190// Verifies that OnExtensionInstalled() notification removes an active install.
191TEST_F(InstallTrackerTest, ExtensionInstalledEvent) {
192  InstallObserver::ExtensionInstallParams install_params(
193      kExtensionId1, std::string(), gfx::ImageSkia(), false, false);
194  tracker_->OnBeginExtensionInstall(install_params);
195
196  const ActiveInstallData* retrieved_data =
197      tracker_->GetActiveInstall(kExtensionId1);
198  ASSERT_TRUE(retrieved_data);
199  EXPECT_EQ(0, retrieved_data->percent_downloaded);
200  EXPECT_EQ(install_params.extension_id, retrieved_data->extension_id);
201  EXPECT_EQ(install_params.is_ephemeral, retrieved_data->is_ephemeral);
202  retrieved_data = NULL;
203
204  // Simulate an extension install.
205  scoped_refptr<Extension> extension = CreateDummyExtension(kExtensionId1);
206  ASSERT_TRUE(extension.get());
207  ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
208  ASSERT_TRUE(registry);
209  registry->AddEnabled(extension);
210  registry->TriggerOnInstalled(extension.get(), false);
211
212  EXPECT_FALSE(tracker_->GetActiveInstall(kExtensionId1));
213}
214