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.
5 #include "chrome/browser/extensions/webstore_installer.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/webstore_installer_test.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
13 #include "chrome/common/extensions/webstore_install_result.h"
14 #include "extensions/browser/extension_registry.h"
15 #include "extensions/common/extension.h"
16 #include "extensions/common/extension_builder.h"
17 #include "extensions/common/value_builder.h"
19 namespace extensions
{
23 const char kExtensionName
[] = "InstallerExtension";
24 const char kWebstoreDomain
[] = "cws.com";
25 const char kAppDomain
[] = "app.com";
26 const char kNonAppDomain
[] = "nonapp.com";
27 const char kTestExtensionId
[] = "ecglahbcnmdpdciemllbhojghbkagdje";
28 const char kTestDataPath
[] = "extensions/api_test/webstore_inline_install";
29 const char kCrxFilename
[] = "extension.crx";
33 // Test version of WebstoreInstaller that intercepts the destructor.
34 class TestWebstoreInstaller
: public WebstoreInstaller
{
36 TestWebstoreInstaller(Profile
* profile
,
38 content::WebContents
* web_contents
,
39 const std::string
& id
,
40 scoped_ptr
<Approval
> approval
,
43 profile
, delegate
, web_contents
, id
, approval
.Pass(), source
) {}
45 void SetDeletedClosure(const base::Closure
& cb
) { deleted_closure_
= cb
; }
48 ~TestWebstoreInstaller() override
{
49 if (!deleted_closure_
.is_null())
50 deleted_closure_
.Run();
53 base::Closure deleted_closure_
;
56 class WebstoreInstallerBrowserTest
57 : public WebstoreInstallerTest
,
58 public WebstoreInstaller::Delegate
{
60 WebstoreInstallerBrowserTest()
61 : WebstoreInstallerTest(
67 ~WebstoreInstallerBrowserTest() override
{}
69 void SetDoneClosure(const base::Closure
& done_closure
) {
70 done_closure_
= done_closure
;
73 bool success() const { return success_
; }
75 // Overridden from WebstoreInstaller::Delegate:
76 void OnExtensionDownloadStarted(const std::string
& id
,
77 content::DownloadItem
* item
) override
;
78 void OnExtensionDownloadProgress(const std::string
& id
,
79 content::DownloadItem
* item
) override
;
80 void OnExtensionInstallSuccess(const std::string
& id
) override
;
81 void OnExtensionInstallFailure(
82 const std::string
& id
,
83 const std::string
& error
,
84 WebstoreInstaller::FailureReason reason
) override
;
87 base::Closure done_closure_
;
91 void WebstoreInstallerBrowserTest::OnExtensionDownloadStarted(
92 const std::string
& id
, content::DownloadItem
* item
) {
95 void WebstoreInstallerBrowserTest::OnExtensionDownloadProgress(
96 const std::string
& id
, content::DownloadItem
* item
) {
99 void WebstoreInstallerBrowserTest::OnExtensionInstallSuccess(
100 const std::string
& id
) {
105 void WebstoreInstallerBrowserTest::OnExtensionInstallFailure(
106 const std::string
& id
,
107 const std::string
& error
,
108 WebstoreInstaller::FailureReason reason
) {
113 IN_PROC_BROWSER_TEST_F(WebstoreInstallerBrowserTest
, WebstoreInstall
) {
114 scoped_ptr
<base::DictionaryValue
> manifest(
115 DictionaryBuilder().Set("name", kExtensionName
)
116 .Set("description", "Foo")
117 .Set("manifest_version", 2)
118 .Set("version", "1.0")
120 ListBuilder().Append("tabs"))
123 content::WebContents
* active_web_contents
=
124 browser()->tab_strip_model()->GetActiveWebContents();
125 ASSERT_TRUE(active_web_contents
);
127 // Create an approval.
128 scoped_ptr
<WebstoreInstaller::Approval
> approval
=
129 WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
130 browser()->profile(),
135 // Create and run a WebstoreInstaller.
136 base::RunLoop run_loop
;
137 SetDoneClosure(run_loop
.QuitClosure());
138 TestWebstoreInstaller
* installer
=
139 new TestWebstoreInstaller(
140 browser()->profile(),
145 WebstoreInstaller::INSTALL_SOURCE_OTHER
);
149 EXPECT_TRUE(success());
150 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
151 ASSERT_TRUE(registry
->enabled_extensions().GetByID(kTestExtensionId
));
154 IN_PROC_BROWSER_TEST_F(WebstoreInstallerBrowserTest
, SimultaneousInstall
) {
155 scoped_ptr
<base::DictionaryValue
> manifest(
156 DictionaryBuilder().Set("name", kExtensionName
)
157 .Set("description", "Foo")
158 .Set("manifest_version", 2)
159 .Set("version", "1.0")
161 ListBuilder().Append("tabs"))
164 content::WebContents
* active_web_contents
=
165 browser()->tab_strip_model()->GetActiveWebContents();
166 ASSERT_TRUE(active_web_contents
);
168 // Create an approval.
169 scoped_ptr
<WebstoreInstaller::Approval
> approval
=
170 WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
171 browser()->profile(),
173 scoped_ptr
<base::DictionaryValue
>(manifest
->DeepCopy()),
176 // Create and run a WebstoreInstaller.
177 base::RunLoop run_loop
;
178 SetDoneClosure(run_loop
.QuitClosure());
179 scoped_refptr
<TestWebstoreInstaller
> installer
=
180 new TestWebstoreInstaller(
181 browser()->profile(),
186 WebstoreInstaller::INSTALL_SOURCE_OTHER
);
189 // Simulate another mechanism installing the same extension.
190 scoped_refptr
<const Extension
> extension
=
191 ExtensionBuilder().SetLocation(Manifest::INTERNAL
)
192 .SetID(kTestExtensionId
)
193 .SetManifest(manifest
.Pass())
195 extension_service()->OnExtensionInstalled(extension
.get(),
196 syncer::StringOrdinal(),
201 // Wait for the WebstoreInstaller to be destroyed. Bad things happen if we
202 // don't wait for this.
203 base::RunLoop run_loop2
;
204 installer
->SetDeletedClosure(run_loop2
.QuitClosure());
208 EXPECT_TRUE(success());
209 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile());
210 // Extension ends up as disabled because of permissions.
211 ASSERT_TRUE(registry
->disabled_extensions().GetByID(kTestExtensionId
));
214 } // namespace extensions