Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: chrome/browser/extensions/default_apps_provider_unittest.cc

Issue 8245018: Remove race condition when installing default apps into a new profile. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Addressing review comments Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 <string>
6
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h"
10 #include "base/values.h"
11 #include "base/version.h"
12 #include "chrome/browser/extensions/crx_installer.h"
13 #include "chrome/browser/extensions/default_apps_provider.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/external_extension_provider_interface.h"
16 #include "chrome/browser/extensions/external_policy_extension_loader.h"
17 #include "chrome/common/chrome_notification_types.h"
18 #include "chrome/common/extensions/extension.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/testing_pref_service.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "content/browser/browser_thread.h"
23 #include "content/common/notification_service.h"
24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_source.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace {
29
30 class MockExternalExtensionLoader : public ExternalExtensionLoader {
31 public:
32 MockExternalExtensionLoader() {}
33
34 void SetPrefs(const base::DictionaryValue& prefs) {
35 prefs_.reset(prefs.DeepCopy());
36 }
37
38 private:
39 virtual void StartLoading() {
40 // No actual loading to be done, simply use the prefs given.
41 LoadFinished();
42 }
43
44 virtual const FilePath GetBaseCrxFilePath() {
45 return FilePath(FILE_PATH_LITERAL("/tmp"));
46 }
47
48 DISALLOW_COPY_AND_ASSIGN(MockExternalExtensionLoader);
49 };
50
51 class MockExternalPolicyExtensionProviderVisitor
52 : public ExternalExtensionProviderInterface::VisitorInterface {
53 public:
54 MockExternalPolicyExtensionProviderVisitor() {
55 profile_.reset(new TestingProfile);
56 profile_->CreateExtensionService(CommandLine::ForCurrentProcess(),
57 FilePath(FILE_PATH_LITERAL("/tmp")), false);
58
59 // The provider owns the loader.
60 loader_ = new MockExternalExtensionLoader();
61 provider_.reset(new DefaultAppsProvider(this, loader_, profile_.get()));
62 }
63
64 virtual void OnExternalExtensionFileFound(const std::string& id,
65 const Version* version,
66 const FilePath& path,
67 Extension::Location unused) {
68 }
69
70 virtual void OnExternalExtensionUpdateUrlFound(
71 const std::string& id, const GURL& update_url,
72 Extension::Location location) {
73 ADD_FAILURE() << "There should be no external extensions from URLs.";
74 }
75
76 virtual void OnExternalProviderReady() {
77 EXPECT_TRUE(provider_->IsReady());
78 }
79
80 TestingProfile* profile() const { return profile_.get(); }
81 DefaultAppsProvider* provider() const { return provider_.get(); }
82 MockExternalExtensionLoader* loader() const { return loader_; }
83
84 private:
85 scoped_ptr<TestingProfile> profile_;
86 scoped_ptr<DefaultAppsProvider> provider_;
87 MockExternalExtensionLoader* loader_;
88
89 DISALLOW_COPY_AND_ASSIGN(MockExternalPolicyExtensionProviderVisitor);
90 };
91
92 class DefaultAppsProviderTest : public testing::Test {
93 public:
94 DefaultAppsProviderTest()
95 : loop_(MessageLoop::TYPE_IO),
96 ui_thread_(BrowserThread::UI, &loop_) {
97 }
98
99 virtual ~DefaultAppsProviderTest() {}
100
101 MockExternalPolicyExtensionProviderVisitor* visitor() {
102 return &visitor_;
103 }
104
105 int GetProviderState();
106
107 void AddExtensionToDictionary(base::DictionaryValue* prefs,
108 const char* id,
109 const char* name,
110 const char* version);
111
112 private:
113 // We need these to satisfy BrowserThread::CurrentlyOn(BrowserThread::UI)
114 // checks in ExternalExtensionProviderImpl.
115 MessageLoop loop_;
116 BrowserThread ui_thread_;
117 MockExternalPolicyExtensionProviderVisitor visitor_;
118 };
119
120 int DefaultAppsProviderTest::GetProviderState() {
121 return visitor()->profile()->GetPrefs()->GetInteger(
122 prefs::kDefaultAppsInstallState);
123 }
124
125 void DefaultAppsProviderTest::AddExtensionToDictionary(
126 base::DictionaryValue* prefs,
127 const char* id,
128 const char* name,
129 const char* version) {
130 scoped_ptr<base::DictionaryValue> extension(new base::DictionaryValue);
131
132 extension->SetString("external_crx", name);
133 extension->SetString("external_version", version);
134
135 prefs->Set(id, extension.release());
136 }
137
138 } // anonymous namespace
139
140 TEST_F(DefaultAppsProviderTest, NoExtensions) {
141 // Setup the loader to provide nothing.
142 base::DictionaryValue prefs;
143 visitor()->loader()->SetPrefs(prefs);
144
145 visitor()->provider()->VisitRegisteredExtension();
146
147 EXPECT_EQ(0u, visitor()->provider()->invalid_extensions().size());
148 EXPECT_EQ(0u, visitor()->provider()->install_error_extensions().size());
149 EXPECT_EQ(DefaultAppsProvider::kInstallDone, GetProviderState());
150 }
151
152 TEST_F(DefaultAppsProviderTest, InvalidExtension) {
153 // Setup the loader to one invalid extension.
154 base::DictionaryValue prefs;
155 prefs.SetInteger("bad_id", 0);
156 visitor()->loader()->SetPrefs(prefs);
157
158 // Run the provider.
159 visitor()->provider()->VisitRegisteredExtension();
160
161 // Make sure state is "done".
162 EXPECT_EQ(1u, visitor()->provider()->invalid_extensions().size());
163 EXPECT_EQ(0u, visitor()->provider()->install_error_extensions().size());
164 EXPECT_EQ(DefaultAppsProvider::kInstallDone, GetProviderState());
165 }
166
167 TEST_F(DefaultAppsProviderTest, InstallErrorExtension) {
168 // Setup the loader to one valid extension that fails to load.
169 base::DictionaryValue prefs;
170 AddExtensionToDictionary(&prefs, "blpcfgokakmgnkcojhhkbfbldkacnbeo",
171 "dummy.crx", "1.0.0.0");
172 visitor()->loader()->SetPrefs(prefs);
173
174 // Run the provider.
175 visitor()->provider()->VisitRegisteredExtension();
176
177 EXPECT_EQ(0u, visitor()->provider()->invalid_extensions().size());
178 EXPECT_EQ(0u, visitor()->provider()->install_error_extensions().size());
179 EXPECT_EQ(DefaultAppsProvider::kInstalling, GetProviderState());
180
181 // Pretend the load failed.
182 ExtensionService* service = visitor()->profile()->GetExtensionService();
183 scoped_refptr<CrxInstaller> crx_installer(service->MakeCrxInstaller(NULL));
184 crx_installer->set_expected_id("blpcfgokakmgnkcojhhkbfbldkacnbeo");
185 visitor()->provider()->Observe(
186 chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
187 content::Source<CrxInstaller>(crx_installer.get()),
188 NotificationService::NoDetails());
189
190 EXPECT_EQ(0u, visitor()->provider()->invalid_extensions().size());
191 EXPECT_EQ(1u, visitor()->provider()->install_error_extensions().size());
192 EXPECT_EQ(DefaultAppsProvider::kInstallDone, GetProviderState());
193 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698