OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/files/file_util.h" | 5 #include "base/files/file_util.h" |
6 #include "base/macros.h" | 6 #include "base/macros.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 | 105 |
106 // Creates a new ExtensionToolbarModel for the given |context|. | 106 // Creates a new ExtensionToolbarModel for the given |context|. |
107 KeyedService* BuildToolbarModel(content::BrowserContext* context) { | 107 KeyedService* BuildToolbarModel(content::BrowserContext* context) { |
108 return new ExtensionToolbarModel(Profile::FromBrowserContext(context), | 108 return new ExtensionToolbarModel(Profile::FromBrowserContext(context), |
109 ExtensionPrefs::Get(context)); | 109 ExtensionPrefs::Get(context)); |
110 } | 110 } |
111 | 111 |
112 // Given a |profile|, assigns the testing keyed service function to | 112 // Given a |profile|, assigns the testing keyed service function to |
113 // BuildToolbarModel() and uses it to create and initialize a new | 113 // BuildToolbarModel() and uses it to create and initialize a new |
114 // ExtensionToolbarModel. | 114 // ExtensionToolbarModel. |
115 ExtensionToolbarModel* CreateToolbarModelForProfile(Profile* profile) { | 115 // |wait_for_ready| indicates whether or not to post the ExtensionSystem's |
| 116 // ready task. |
| 117 ExtensionToolbarModel* CreateToolbarModelForProfile(Profile* profile, |
| 118 bool wait_for_ready) { |
116 ExtensionToolbarModel* model = ExtensionToolbarModel::Get(profile); | 119 ExtensionToolbarModel* model = ExtensionToolbarModel::Get(profile); |
117 if (model) | 120 if (model) |
118 return model; | 121 return model; |
119 | 122 |
120 // No existing model means it's a new profile (since we, by default, don't | 123 // No existing model means it's a new profile (since we, by default, don't |
121 // create the ToolbarModel in testing). | 124 // create the ToolbarModel in testing). |
122 ExtensionToolbarModelFactory::GetInstance()->SetTestingFactory( | 125 ExtensionToolbarModelFactory::GetInstance()->SetTestingFactory( |
123 profile, &BuildToolbarModel); | 126 profile, &BuildToolbarModel); |
124 model = ExtensionToolbarModel::Get(profile); | 127 model = ExtensionToolbarModel::Get(profile); |
125 // Fake the extension system ready signal. | 128 if (wait_for_ready) { |
126 // HACK ALERT! In production, the ready task on ExtensionSystem (and most | 129 // Fake the extension system ready signal. |
127 // everything else on it, too) is shared between incognito and normal | 130 // HACK ALERT! In production, the ready task on ExtensionSystem (and most |
128 // profiles, but a TestExtensionSystem doesn't have the concept of "shared". | 131 // everything else on it, too) is shared between incognito and normal |
129 // Because of this, we have to set any new profile's TestExtensionSystem's | 132 // profiles, but a TestExtensionSystem doesn't have the concept of "shared". |
130 // ready task, too. | 133 // Because of this, we have to set any new profile's TestExtensionSystem's |
131 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile))->SetReady(); | 134 // ready task, too. |
132 // Run tasks posted to TestExtensionSystem. | 135 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile))-> |
133 base::RunLoop().RunUntilIdle(); | 136 SetReady(); |
| 137 // Run tasks posted to TestExtensionSystem. |
| 138 base::RunLoop().RunUntilIdle(); |
| 139 } |
134 | 140 |
135 return model; | 141 return model; |
136 } | 142 } |
137 | 143 |
138 // Create an extension. If |action_key| is non-NULL, it should point to either | 144 // Create an extension. If |action_key| is non-NULL, it should point to either |
139 // kBrowserAction or kPageAction, and the extension will have the associated | 145 // kBrowserAction or kPageAction, and the extension will have the associated |
140 // action. | 146 // action. |
141 scoped_refptr<const Extension> GetActionExtension(const std::string& name, | 147 scoped_refptr<const Extension> GetActionExtension(const std::string& name, |
142 const char* action_key) { | 148 const char* action_key) { |
143 DictionaryBuilder manifest; | 149 DictionaryBuilder manifest; |
(...skipping 13 matching lines...) Expand all Loading... |
157 class ExtensionToolbarModelTestObserver | 163 class ExtensionToolbarModelTestObserver |
158 : public ExtensionToolbarModel::Observer { | 164 : public ExtensionToolbarModel::Observer { |
159 public: | 165 public: |
160 explicit ExtensionToolbarModelTestObserver(ExtensionToolbarModel* model); | 166 explicit ExtensionToolbarModelTestObserver(ExtensionToolbarModel* model); |
161 ~ExtensionToolbarModelTestObserver() override; | 167 ~ExtensionToolbarModelTestObserver() override; |
162 | 168 |
163 size_t inserted_count() const { return inserted_count_; } | 169 size_t inserted_count() const { return inserted_count_; } |
164 size_t removed_count() const { return removed_count_; } | 170 size_t removed_count() const { return removed_count_; } |
165 size_t moved_count() const { return moved_count_; } | 171 size_t moved_count() const { return moved_count_; } |
166 int highlight_mode_count() const { return highlight_mode_count_; } | 172 int highlight_mode_count() const { return highlight_mode_count_; } |
| 173 size_t initialized_count() const { return initialized_count_; } |
167 size_t reorder_count() const { return reorder_count_; } | 174 size_t reorder_count() const { return reorder_count_; } |
168 | 175 |
169 private: | 176 private: |
170 // ExtensionToolbarModel::Observer: | 177 // ExtensionToolbarModel::Observer: |
171 void ToolbarExtensionAdded(const Extension* extension, int index) override { | 178 void ToolbarExtensionAdded(const Extension* extension, int index) override { |
172 ++inserted_count_; | 179 ++inserted_count_; |
173 } | 180 } |
174 | 181 |
175 void ToolbarExtensionRemoved(const Extension* extension) override { | 182 void ToolbarExtensionRemoved(const Extension* extension) override { |
176 ++removed_count_; | 183 ++removed_count_; |
(...skipping 10 matching lines...) Expand all Loading... |
187 return false; | 194 return false; |
188 } | 195 } |
189 | 196 |
190 void ToolbarVisibleCountChanged() override {} | 197 void ToolbarVisibleCountChanged() override {} |
191 | 198 |
192 void ToolbarHighlightModeChanged(bool is_highlighting) override { | 199 void ToolbarHighlightModeChanged(bool is_highlighting) override { |
193 // Add one if highlighting, subtract one if not. | 200 // Add one if highlighting, subtract one if not. |
194 highlight_mode_count_ += is_highlighting ? 1 : -1; | 201 highlight_mode_count_ += is_highlighting ? 1 : -1; |
195 } | 202 } |
196 | 203 |
197 void OnToolbarModelInitialized() override {} | 204 void OnToolbarModelInitialized() override { ++initialized_count_; } |
198 | 205 |
199 void OnToolbarReorderNecessary(content::WebContents* web_contents) override { | 206 void OnToolbarReorderNecessary(content::WebContents* web_contents) override { |
200 ++reorder_count_; | 207 ++reorder_count_; |
201 } | 208 } |
202 | 209 |
203 Browser* GetBrowser() override { return NULL; } | 210 Browser* GetBrowser() override { return NULL; } |
204 | 211 |
205 ExtensionToolbarModel* model_; | 212 ExtensionToolbarModel* model_; |
206 | 213 |
207 size_t inserted_count_; | 214 size_t inserted_count_; |
208 size_t removed_count_; | 215 size_t removed_count_; |
209 size_t moved_count_; | 216 size_t moved_count_; |
210 // Int because it could become negative (if something goes wrong). | 217 // Int because it could become negative (if something goes wrong). |
211 int highlight_mode_count_; | 218 int highlight_mode_count_; |
| 219 size_t initialized_count_; |
212 size_t reorder_count_; | 220 size_t reorder_count_; |
213 }; | 221 }; |
214 | 222 |
215 ExtensionToolbarModelTestObserver::ExtensionToolbarModelTestObserver( | 223 ExtensionToolbarModelTestObserver::ExtensionToolbarModelTestObserver( |
216 ExtensionToolbarModel* model) : model_(model), | 224 ExtensionToolbarModel* model) : model_(model), |
217 inserted_count_(0), | 225 inserted_count_(0), |
218 removed_count_(0), | 226 removed_count_(0), |
219 moved_count_(0), | 227 moved_count_(0), |
220 highlight_mode_count_(0), | 228 highlight_mode_count_(0), |
| 229 initialized_count_(0), |
221 reorder_count_(0) { | 230 reorder_count_(0) { |
222 model_->AddObserver(this); | 231 model_->AddObserver(this); |
223 } | 232 } |
224 | 233 |
225 ExtensionToolbarModelTestObserver::~ExtensionToolbarModelTestObserver() { | 234 ExtensionToolbarModelTestObserver::~ExtensionToolbarModelTestObserver() { |
226 model_->RemoveObserver(this); | 235 model_->RemoveObserver(this); |
227 } | 236 } |
228 | 237 |
229 } // namespace | 238 } // namespace |
230 | 239 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 scoped_refptr<const Extension> browser_action_c_; | 301 scoped_refptr<const Extension> browser_action_c_; |
293 | 302 |
294 // Sample extensions with different kinds of actions. | 303 // Sample extensions with different kinds of actions. |
295 scoped_refptr<const Extension> browser_action_extension_; | 304 scoped_refptr<const Extension> browser_action_extension_; |
296 scoped_refptr<const Extension> page_action_extension_; | 305 scoped_refptr<const Extension> page_action_extension_; |
297 scoped_refptr<const Extension> no_action_extension_; | 306 scoped_refptr<const Extension> no_action_extension_; |
298 }; | 307 }; |
299 | 308 |
300 void ExtensionToolbarModelUnitTest::Init() { | 309 void ExtensionToolbarModelUnitTest::Init() { |
301 InitializeEmptyExtensionService(); | 310 InitializeEmptyExtensionService(); |
302 toolbar_model_ = CreateToolbarModelForProfile(profile()); | 311 toolbar_model_ = CreateToolbarModelForProfile(profile(), true); |
303 model_observer_.reset(new ExtensionToolbarModelTestObserver(toolbar_model_)); | 312 model_observer_.reset(new ExtensionToolbarModelTestObserver(toolbar_model_)); |
304 } | 313 } |
305 | 314 |
306 void ExtensionToolbarModelUnitTest::TearDown() { | 315 void ExtensionToolbarModelUnitTest::TearDown() { |
307 model_observer_.reset(); | 316 model_observer_.reset(); |
308 ExtensionServiceTestBase::TearDown(); | 317 ExtensionServiceTestBase::TearDown(); |
309 } | 318 } |
310 | 319 |
311 testing::AssertionResult ExtensionToolbarModelUnitTest::AddExtension( | 320 testing::AssertionResult ExtensionToolbarModelUnitTest::AddExtension( |
312 const scoped_refptr<const Extension>& extension) { | 321 const scoped_refptr<const Extension>& extension) { |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 util::SetIsIncognitoEnabled(browser_action_c()->id(), profile(), true); | 889 util::SetIsIncognitoEnabled(browser_action_c()->id(), profile(), true); |
881 | 890 |
882 // Move C to the second index. | 891 // Move C to the second index. |
883 toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 1u); | 892 toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 1u); |
884 // Set visible count to 2 so that c is overflowed. State is A C [B]. | 893 // Set visible count to 2 so that c is overflowed. State is A C [B]. |
885 toolbar_model()->SetVisibleIconCount(2); | 894 toolbar_model()->SetVisibleIconCount(2); |
886 EXPECT_EQ(1u, observer()->moved_count()); | 895 EXPECT_EQ(1u, observer()->moved_count()); |
887 | 896 |
888 // Get an incognito profile and toolbar. | 897 // Get an incognito profile and toolbar. |
889 ExtensionToolbarModel* incognito_model = | 898 ExtensionToolbarModel* incognito_model = |
890 CreateToolbarModelForProfile(profile()->GetOffTheRecordProfile()); | 899 CreateToolbarModelForProfile(profile()->GetOffTheRecordProfile(), true); |
891 | 900 |
892 ExtensionToolbarModelTestObserver incognito_observer(incognito_model); | 901 ExtensionToolbarModelTestObserver incognito_observer(incognito_model); |
893 EXPECT_EQ(0u, incognito_observer.moved_count()); | 902 EXPECT_EQ(0u, incognito_observer.moved_count()); |
894 | 903 |
895 // We should have two items, C and B, and the order should be preserved from | 904 // We should have two items, C and B, and the order should be preserved from |
896 // the original model. | 905 // the original model. |
897 EXPECT_EQ(2u, incognito_model->toolbar_items().size()); | 906 EXPECT_EQ(2u, incognito_model->toolbar_items().size()); |
898 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u, incognito_model)); | 907 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u, incognito_model)); |
899 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u, incognito_model)); | 908 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u, incognito_model)); |
900 | 909 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 // The first model should have both extensions visible. | 994 // The first model should have both extensions visible. |
986 EXPECT_EQ(2u, toolbar_model()->toolbar_items().size()); | 995 EXPECT_EQ(2u, toolbar_model()->toolbar_items().size()); |
987 EXPECT_EQ(extension_a, GetExtensionAtIndex(0)->id()); | 996 EXPECT_EQ(extension_a, GetExtensionAtIndex(0)->id()); |
988 EXPECT_EQ(extension_b, GetExtensionAtIndex(1)->id()); | 997 EXPECT_EQ(extension_b, GetExtensionAtIndex(1)->id()); |
989 | 998 |
990 // Set the model to only show one extension, so the order is A [B]. | 999 // Set the model to only show one extension, so the order is A [B]. |
991 toolbar_model()->SetVisibleIconCount(1u); | 1000 toolbar_model()->SetVisibleIconCount(1u); |
992 | 1001 |
993 // Get an incognito profile and toolbar. | 1002 // Get an incognito profile and toolbar. |
994 ExtensionToolbarModel* incognito_model = | 1003 ExtensionToolbarModel* incognito_model = |
995 CreateToolbarModelForProfile(profile()->GetOffTheRecordProfile()); | 1004 CreateToolbarModelForProfile(profile()->GetOffTheRecordProfile(), true); |
996 ExtensionToolbarModelTestObserver incognito_observer(incognito_model); | 1005 ExtensionToolbarModelTestObserver incognito_observer(incognito_model); |
997 | 1006 |
998 // Right now, no extensions are enabled in incognito mode. | 1007 // Right now, no extensions are enabled in incognito mode. |
999 EXPECT_EQ(0u, incognito_model->toolbar_items().size()); | 1008 EXPECT_EQ(0u, incognito_model->toolbar_items().size()); |
1000 | 1009 |
1001 // Set extension b (which is overflowed) to be enabled in incognito. This | 1010 // Set extension b (which is overflowed) to be enabled in incognito. This |
1002 // results in b reloading, so wait for it. | 1011 // results in b reloading, so wait for it. |
1003 { | 1012 { |
1004 TestExtensionRegistryObserver observer(registry(), extension_b); | 1013 TestExtensionRegistryObserver observer(registry(), extension_b); |
1005 util::SetIsIncognitoEnabled(extension_b, profile(), true); | 1014 util::SetIsIncognitoEnabled(extension_b, profile(), true); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 extension_action_api->NotifyChange(action, web_contents, profile()); | 1277 extension_action_api->NotifyChange(action, web_contents, profile()); |
1269 tab_order = toolbar_model()->GetItemOrderForTab(web_contents); | 1278 tab_order = toolbar_model()->GetItemOrderForTab(web_contents); |
1270 ASSERT_EQ(3u, tab_order.size()); | 1279 ASSERT_EQ(3u, tab_order.size()); |
1271 EXPECT_EQ(page_action(), tab_order[0].get()); | 1280 EXPECT_EQ(page_action(), tab_order[0].get()); |
1272 EXPECT_EQ(browser_action(), tab_order[1].get()); | 1281 EXPECT_EQ(browser_action(), tab_order[1].get()); |
1273 EXPECT_EQ(no_action(), tab_order[2].get()); | 1282 EXPECT_EQ(no_action(), tab_order[2].get()); |
1274 EXPECT_EQ(1u, toolbar_model()->GetVisibleIconCountForTab(web_contents)); | 1283 EXPECT_EQ(1u, toolbar_model()->GetVisibleIconCountForTab(web_contents)); |
1275 EXPECT_EQ(3u, observer()->reorder_count()); | 1284 EXPECT_EQ(3u, observer()->reorder_count()); |
1276 } | 1285 } |
1277 | 1286 |
| 1287 // Test that observers receive no Added notifications until after the |
| 1288 // ExtensionSystem has initialized. |
| 1289 TEST_F(ExtensionToolbarModelUnitTest, ModelWaitsForExtensionSystemReady) { |
| 1290 InitializeEmptyExtensionService(); |
| 1291 ExtensionToolbarModel* toolbar_model = |
| 1292 CreateToolbarModelForProfile(profile(), false); |
| 1293 ExtensionToolbarModelTestObserver model_observer(toolbar_model); |
| 1294 EXPECT_TRUE(AddBrowserActionExtensions()); |
| 1295 |
| 1296 // Since the model hasn't been initialized (the ExtensionSystem::ready task |
| 1297 // hasn't been run), there should be no insertion notifications. |
| 1298 EXPECT_EQ(0u, model_observer.inserted_count()); |
| 1299 EXPECT_EQ(0u, model_observer.initialized_count()); |
| 1300 EXPECT_FALSE(toolbar_model->extensions_initialized()); |
| 1301 |
| 1302 // Run the ready task. |
| 1303 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile()))-> |
| 1304 SetReady(); |
| 1305 // Run tasks posted to TestExtensionSystem. |
| 1306 base::RunLoop().RunUntilIdle(); |
| 1307 |
| 1308 // We should still have no insertions, but should have an initialized count. |
| 1309 EXPECT_TRUE(toolbar_model->extensions_initialized()); |
| 1310 EXPECT_EQ(0u, model_observer.inserted_count()); |
| 1311 EXPECT_EQ(1u, model_observer.initialized_count()); |
| 1312 } |
| 1313 |
1278 } // namespace extensions | 1314 } // namespace extensions |
OLD | NEW |