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