ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / extensions / extension_toolbar_model_unittest.cc
blobc779b5558d597018d0df492b35a35e38939cf67e
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 "base/files/file_util.h"
6 #include "base/macros.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
11 #include "chrome/browser/extensions/extension_action_manager.h"
12 #include "chrome/browser/extensions/extension_action_test_util.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_service_test_base.h"
15 #include "chrome/browser/extensions/extension_toolbar_model.h"
16 #include "chrome/browser/extensions/extension_util.h"
17 #include "chrome/browser/extensions/test_extension_dir.h"
18 #include "chrome/browser/extensions/test_extension_system.h"
19 #include "chrome/browser/extensions/unpacked_installer.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/sessions/session_tab_helper.h"
22 #include "chrome/common/extensions/api/extension_action/action_info.h"
23 #include "components/crx_file/id_util.h"
24 #include "content/public/test/test_renderer_host.h"
25 #include "content/public/test/web_contents_tester.h"
26 #include "extensions/browser/extension_prefs.h"
27 #include "extensions/browser/extension_registry.h"
28 #include "extensions/browser/extension_system.h"
29 #include "extensions/browser/test_extension_registry_observer.h"
30 #include "extensions/common/extension.h"
31 #include "extensions/common/feature_switch.h"
33 #if defined(USE_AURA)
34 #include "ui/aura/env.h"
35 #endif
37 namespace extensions {
39 namespace {
41 // A simple observer that tracks the number of times certain events occur.
42 class ExtensionToolbarModelTestObserver
43 : public ExtensionToolbarModel::Observer {
44 public:
45 explicit ExtensionToolbarModelTestObserver(ExtensionToolbarModel* model);
46 ~ExtensionToolbarModelTestObserver() override;
48 size_t inserted_count() const { return inserted_count_; }
49 size_t removed_count() const { return removed_count_; }
50 size_t moved_count() const { return moved_count_; }
51 int highlight_mode_count() const { return highlight_mode_count_; }
52 size_t initialized_count() const { return initialized_count_; }
54 private:
55 // ExtensionToolbarModel::Observer:
56 void ToolbarExtensionAdded(const Extension* extension, int index) override {
57 ++inserted_count_;
60 void ToolbarExtensionRemoved(const Extension* extension) override {
61 ++removed_count_;
64 void ToolbarExtensionMoved(const Extension* extension, int index) override {
65 ++moved_count_;
68 void ToolbarExtensionUpdated(const Extension* extension) override {}
70 bool ShowExtensionActionPopup(const Extension* extension,
71 bool grant_active_tab) override {
72 return false;
75 void ToolbarVisibleCountChanged() override {}
77 void ToolbarHighlightModeChanged(bool is_highlighting) override {
78 // Add one if highlighting, subtract one if not.
79 highlight_mode_count_ += is_highlighting ? 1 : -1;
82 void OnToolbarModelInitialized() override { ++initialized_count_; }
84 Browser* GetBrowser() override { return NULL; }
86 ExtensionToolbarModel* model_;
88 size_t inserted_count_;
89 size_t removed_count_;
90 size_t moved_count_;
91 // Int because it could become negative (if something goes wrong).
92 int highlight_mode_count_;
93 size_t initialized_count_;
96 ExtensionToolbarModelTestObserver::ExtensionToolbarModelTestObserver(
97 ExtensionToolbarModel* model) : model_(model),
98 inserted_count_(0),
99 removed_count_(0),
100 moved_count_(0),
101 highlight_mode_count_(0),
102 initialized_count_(0) {
103 model_->AddObserver(this);
106 ExtensionToolbarModelTestObserver::~ExtensionToolbarModelTestObserver() {
107 model_->RemoveObserver(this);
110 } // namespace
112 class ExtensionToolbarModelUnitTest : public ExtensionServiceTestBase {
113 protected:
114 // Initialize the ExtensionService, ExtensionToolbarModel, and
115 // ExtensionSystem.
116 void Init();
118 void TearDown() override;
120 // Adds or removes the given |extension| and verify success.
121 testing::AssertionResult AddExtension(
122 const scoped_refptr<const Extension>& extension) WARN_UNUSED_RESULT;
123 testing::AssertionResult RemoveExtension(
124 const scoped_refptr<const Extension>& extension) WARN_UNUSED_RESULT;
126 // Adds three extensions, all with browser actions.
127 testing::AssertionResult AddBrowserActionExtensions() WARN_UNUSED_RESULT;
129 // Adds three extensions, one each for browser action, page action, and no
130 // action, and are added in that order.
131 testing::AssertionResult AddActionExtensions() WARN_UNUSED_RESULT;
133 // Returns the extension at the given index in the toolbar model, or NULL
134 // if one does not exist.
135 // If |model| is specified, it is used. Otherwise, this defaults to
136 // |toolbar_model_|.
137 const Extension* GetExtensionAtIndex(
138 size_t index, const ExtensionToolbarModel* model) const;
139 const Extension* GetExtensionAtIndex(size_t index) const;
141 ExtensionToolbarModel* toolbar_model() { return toolbar_model_; }
143 const ExtensionToolbarModelTestObserver* observer() const {
144 return model_observer_.get();
146 size_t num_toolbar_items() const {
147 return toolbar_model_->toolbar_items().size();
149 const Extension* browser_action_a() const { return browser_action_a_.get(); }
150 const Extension* browser_action_b() const { return browser_action_b_.get(); }
151 const Extension* browser_action_c() const { return browser_action_c_.get(); }
152 const Extension* browser_action() const {
153 return browser_action_extension_.get();
155 const Extension* page_action() const { return page_action_extension_.get(); }
156 const Extension* no_action() const { return no_action_extension_.get(); }
158 private:
159 // Verifies that all extensions in |extensions| are added successfully.
160 testing::AssertionResult AddAndVerifyExtensions(
161 const ExtensionList& extensions);
163 // The toolbar model associated with the testing profile.
164 ExtensionToolbarModel* toolbar_model_;
166 // The test observer to track events. Must come after toolbar_model_ so that
167 // it is destroyed and removes itself as an observer first.
168 scoped_ptr<ExtensionToolbarModelTestObserver> model_observer_;
170 // Sample extensions with only browser actions.
171 scoped_refptr<const Extension> browser_action_a_;
172 scoped_refptr<const Extension> browser_action_b_;
173 scoped_refptr<const Extension> browser_action_c_;
175 // Sample extensions with different kinds of actions.
176 scoped_refptr<const Extension> browser_action_extension_;
177 scoped_refptr<const Extension> page_action_extension_;
178 scoped_refptr<const Extension> no_action_extension_;
181 void ExtensionToolbarModelUnitTest::Init() {
182 InitializeEmptyExtensionService();
183 toolbar_model_ =
184 extension_action_test_util::CreateToolbarModelForProfile(profile());
185 model_observer_.reset(new ExtensionToolbarModelTestObserver(toolbar_model_));
188 void ExtensionToolbarModelUnitTest::TearDown() {
189 model_observer_.reset();
190 ExtensionServiceTestBase::TearDown();
193 testing::AssertionResult ExtensionToolbarModelUnitTest::AddExtension(
194 const scoped_refptr<const Extension>& extension) {
195 if (registry()->enabled_extensions().GetByID(extension->id())) {
196 return testing::AssertionFailure() << "Extension " << extension->name() <<
197 " already installed!";
199 service()->AddExtension(extension.get());
200 if (!registry()->enabled_extensions().GetByID(extension->id())) {
201 return testing::AssertionFailure() << "Failed to install extension: " <<
202 extension->name();
204 return testing::AssertionSuccess();
207 testing::AssertionResult ExtensionToolbarModelUnitTest::RemoveExtension(
208 const scoped_refptr<const Extension>& extension) {
209 if (!registry()->enabled_extensions().GetByID(extension->id())) {
210 return testing::AssertionFailure() << "Extension " << extension->name() <<
211 " not installed!";
213 service()->UnloadExtension(extension->id(),
214 UnloadedExtensionInfo::REASON_DISABLE);
215 if (registry()->enabled_extensions().GetByID(extension->id())) {
216 return testing::AssertionFailure() << "Failed to unload extension: " <<
217 extension->name();
219 return testing::AssertionSuccess();
222 testing::AssertionResult ExtensionToolbarModelUnitTest::AddActionExtensions() {
223 browser_action_extension_ = extension_action_test_util::CreateActionExtension(
224 "browser_action", extension_action_test_util::BROWSER_ACTION);
225 page_action_extension_ = extension_action_test_util::CreateActionExtension(
226 "page_action", extension_action_test_util::PAGE_ACTION);
227 no_action_extension_ = extension_action_test_util::CreateActionExtension(
228 "no_action", extension_action_test_util::NO_ACTION);
230 ExtensionList extensions;
231 extensions.push_back(browser_action_extension_);
232 extensions.push_back(page_action_extension_);
233 extensions.push_back(no_action_extension_);
235 return AddAndVerifyExtensions(extensions);
238 testing::AssertionResult
239 ExtensionToolbarModelUnitTest::AddBrowserActionExtensions() {
240 browser_action_a_ = extension_action_test_util::CreateActionExtension(
241 "browser_actionA", extension_action_test_util::BROWSER_ACTION);
242 browser_action_b_ = extension_action_test_util::CreateActionExtension(
243 "browser_actionB", extension_action_test_util::BROWSER_ACTION);
244 browser_action_c_ = extension_action_test_util::CreateActionExtension(
245 "browser_actionC", extension_action_test_util::BROWSER_ACTION);
247 ExtensionList extensions;
248 extensions.push_back(browser_action_a_);
249 extensions.push_back(browser_action_b_);
250 extensions.push_back(browser_action_c_);
252 return AddAndVerifyExtensions(extensions);
255 const Extension* ExtensionToolbarModelUnitTest::GetExtensionAtIndex(
256 size_t index, const ExtensionToolbarModel* model) const {
257 return index < model->toolbar_items().size()
258 ? model->toolbar_items()[index].get()
259 : NULL;
262 const Extension* ExtensionToolbarModelUnitTest::GetExtensionAtIndex(
263 size_t index) const {
264 return GetExtensionAtIndex(index, toolbar_model_);
267 testing::AssertionResult ExtensionToolbarModelUnitTest::AddAndVerifyExtensions(
268 const ExtensionList& extensions) {
269 for (ExtensionList::const_iterator iter = extensions.begin();
270 iter != extensions.end(); ++iter) {
271 if (!AddExtension(*iter)) {
272 return testing::AssertionFailure() << "Failed to install extension: " <<
273 (*iter)->name();
276 return testing::AssertionSuccess();
279 // A basic test for extensions with browser actions showing up in the toolbar.
280 TEST_F(ExtensionToolbarModelUnitTest, BasicExtensionToolbarModelTest) {
281 Init();
283 // Load an extension with no browser action.
284 scoped_refptr<const Extension> extension1 =
285 extension_action_test_util::CreateActionExtension(
286 "no_action", extension_action_test_util::NO_ACTION);
287 ASSERT_TRUE(AddExtension(extension1));
289 // This extension should not be in the model (has no browser action).
290 EXPECT_EQ(0u, observer()->inserted_count());
291 EXPECT_EQ(0u, num_toolbar_items());
292 EXPECT_EQ(NULL, GetExtensionAtIndex(0u));
294 // Load an extension with a browser action.
295 scoped_refptr<const Extension> extension2 =
296 extension_action_test_util::CreateActionExtension(
297 "browser_action", extension_action_test_util::BROWSER_ACTION);
298 ASSERT_TRUE(AddExtension(extension2));
300 // We should now find our extension in the model.
301 EXPECT_EQ(1u, observer()->inserted_count());
302 EXPECT_EQ(1u, num_toolbar_items());
303 EXPECT_EQ(extension2.get(), GetExtensionAtIndex(0u));
305 // Should be a no-op, but still fires the events.
306 toolbar_model()->MoveExtensionIcon(extension2->id(), 0);
307 EXPECT_EQ(1u, observer()->moved_count());
308 EXPECT_EQ(1u, num_toolbar_items());
309 EXPECT_EQ(extension2.get(), GetExtensionAtIndex(0u));
311 // Remove the extension and verify.
312 ASSERT_TRUE(RemoveExtension(extension2));
313 EXPECT_EQ(1u, observer()->removed_count());
314 EXPECT_EQ(0u, num_toolbar_items());
315 EXPECT_EQ(NULL, GetExtensionAtIndex(0u));
318 // Test various different reorderings, removals, and reinsertions.
319 TEST_F(ExtensionToolbarModelUnitTest, ExtensionToolbarReorderAndReinsert) {
320 Init();
322 // Add the three browser action extensions.
323 ASSERT_TRUE(AddBrowserActionExtensions());
325 // Verify the three extensions are in the model in the proper order.
326 EXPECT_EQ(3u, num_toolbar_items());
327 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
328 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
329 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
331 // Order is now A, B, C. Let's put C first.
332 toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 0);
333 EXPECT_EQ(1u, observer()->moved_count());
334 EXPECT_EQ(3u, num_toolbar_items());
335 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
336 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(1u));
337 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(2u));
339 // Order is now C, A, B. Let's put A last.
340 toolbar_model()->MoveExtensionIcon(browser_action_a()->id(), 2);
341 EXPECT_EQ(2u, observer()->moved_count());
342 EXPECT_EQ(3u, num_toolbar_items());
343 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
344 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
345 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(2u));
347 // Order is now C, B, A. Let's remove B.
348 ASSERT_TRUE(RemoveExtension(browser_action_b()));
349 EXPECT_EQ(1u, observer()->removed_count());
350 EXPECT_EQ(2u, num_toolbar_items());
351 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
352 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(1u));
354 // Load extension B again.
355 ASSERT_TRUE(AddExtension(browser_action_b()));
357 // Extension B loaded again.
358 EXPECT_EQ(4u, observer()->inserted_count());
359 EXPECT_EQ(3u, num_toolbar_items());
360 // Make sure it gets its old spot in the list.
361 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
363 // Unload B again.
364 ASSERT_TRUE(RemoveExtension(browser_action_b()));
365 EXPECT_EQ(2u, observer()->removed_count());
366 EXPECT_EQ(2u, num_toolbar_items());
368 // Order is now C, A. Flip it.
369 toolbar_model()->MoveExtensionIcon(browser_action_a()->id(), 0);
370 EXPECT_EQ(3u, observer()->moved_count());
371 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
372 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
374 // Move A to the location it already occupies.
375 toolbar_model()->MoveExtensionIcon(browser_action_a()->id(), 0);
376 EXPECT_EQ(4u, observer()->moved_count());
377 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
378 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
380 // Order is now A, C. Remove C.
381 ASSERT_TRUE(RemoveExtension(browser_action_c()));
382 EXPECT_EQ(3u, observer()->removed_count());
383 EXPECT_EQ(1u, num_toolbar_items());
384 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
386 // Load extension C again.
387 ASSERT_TRUE(AddExtension(browser_action_c()));
389 // Extension C loaded again.
390 EXPECT_EQ(5u, observer()->inserted_count());
391 EXPECT_EQ(2u, num_toolbar_items());
392 // Make sure it gets its old spot in the list (at the very end).
393 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
396 // Test that order persists after unloading and disabling, but not across
397 // uninstallation.
398 TEST_F(ExtensionToolbarModelUnitTest,
399 ExtensionToolbarUnloadDisableAndUninstall) {
400 Init();
402 // Add the three browser action extensions.
403 ASSERT_TRUE(AddBrowserActionExtensions());
405 // Verify the three extensions are in the model in the proper order: A, B, C.
406 EXPECT_EQ(3u, num_toolbar_items());
407 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
408 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
409 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
411 // Unload B, then C, then A, and then reload C, then A, then B.
412 ASSERT_TRUE(RemoveExtension(browser_action_b()));
413 ASSERT_TRUE(RemoveExtension(browser_action_c()));
414 ASSERT_TRUE(RemoveExtension(browser_action_a()));
415 EXPECT_EQ(0u, num_toolbar_items()); // Sanity check: all gone?
416 ASSERT_TRUE(AddExtension(browser_action_c()));
417 ASSERT_TRUE(AddExtension(browser_action_a()));
418 ASSERT_TRUE(AddExtension(browser_action_b()));
419 EXPECT_EQ(3u, num_toolbar_items()); // Sanity check: all back?
420 EXPECT_EQ(0u, observer()->moved_count());
422 // Even though we unloaded and reloaded in a different order, the original
423 // order (A, B, C) should be preserved.
424 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
425 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
426 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
428 // Disabling extensions should also preserve order.
429 service()->DisableExtension(browser_action_b()->id(),
430 Extension::DISABLE_USER_ACTION);
431 service()->DisableExtension(browser_action_c()->id(),
432 Extension::DISABLE_USER_ACTION);
433 service()->DisableExtension(browser_action_a()->id(),
434 Extension::DISABLE_USER_ACTION);
435 service()->EnableExtension(browser_action_c()->id());
436 service()->EnableExtension(browser_action_a()->id());
437 service()->EnableExtension(browser_action_b()->id());
439 // Make sure we still get the original A, B, C order.
440 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
441 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
442 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
444 // Move browser_action_b() to be first.
445 toolbar_model()->MoveExtensionIcon(browser_action_b()->id(), 0);
446 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0u));
448 // Uninstall Extension B.
449 service()->UninstallExtension(browser_action_b()->id(),
450 UNINSTALL_REASON_FOR_TESTING,
451 base::Bind(&base::DoNothing),
452 NULL); // Ignore error.
453 // List contains only A and C now. Validate that.
454 EXPECT_EQ(2u, num_toolbar_items());
455 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
456 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
458 ASSERT_TRUE(AddExtension(browser_action_b()));
460 // Make sure Extension B is _not_ first (its old position should have been
461 // forgotten at uninstall time). Order should be A, C, B.
462 EXPECT_EQ(3u, num_toolbar_items());
463 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
464 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
465 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(2u));
468 TEST_F(ExtensionToolbarModelUnitTest, ReorderOnPrefChange) {
469 Init();
471 // Add the three browser action extensions.
472 ASSERT_TRUE(AddBrowserActionExtensions());
473 EXPECT_EQ(3u, num_toolbar_items());
475 // Change the value of the toolbar preference.
476 ExtensionIdList new_order;
477 new_order.push_back(browser_action_c()->id());
478 new_order.push_back(browser_action_b()->id());
479 ExtensionPrefs::Get(profile())->SetToolbarOrder(new_order);
481 // Verify order is changed.
482 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
483 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
484 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(2u));
487 // Test that new extensions are always visible on installation and inserted at
488 // the "end" of the visible section.
489 TEST_F(ExtensionToolbarModelUnitTest, NewToolbarExtensionsAreVisible) {
490 Init();
492 // Three extensions with actions.
493 scoped_refptr<const Extension> extension_a =
494 extension_action_test_util::CreateActionExtension(
495 "a", extension_action_test_util::BROWSER_ACTION);
496 scoped_refptr<const Extension> extension_b =
497 extension_action_test_util::CreateActionExtension(
498 "b", extension_action_test_util::BROWSER_ACTION);
499 scoped_refptr<const Extension> extension_c =
500 extension_action_test_util::CreateActionExtension(
501 "c", extension_action_test_util::BROWSER_ACTION);
502 scoped_refptr<const Extension> extension_d =
503 extension_action_test_util::CreateActionExtension(
504 "d", extension_action_test_util::BROWSER_ACTION);
506 // We should start off without any extensions.
507 EXPECT_EQ(0u, num_toolbar_items());
508 EXPECT_EQ(0u, toolbar_model()->visible_icon_count());
510 // Add one extension. It should be visible.
511 service()->AddExtension(extension_a.get());
512 EXPECT_EQ(1u, num_toolbar_items());
513 EXPECT_EQ(1u, toolbar_model()->visible_icon_count());
514 EXPECT_EQ(extension_a.get(), GetExtensionAtIndex(0u));
516 // Hide all extensions.
517 toolbar_model()->SetVisibleIconCount(0);
518 EXPECT_EQ(0u, toolbar_model()->visible_icon_count());
520 // Add a new extension - it should be visible, so it should be in the first
521 // index. The other extension should remain hidden.
522 service()->AddExtension(extension_b.get());
523 EXPECT_EQ(2u, num_toolbar_items());
524 EXPECT_EQ(1u, toolbar_model()->visible_icon_count());
525 EXPECT_EQ(extension_b.get(), GetExtensionAtIndex(0u));
526 EXPECT_EQ(extension_a.get(), GetExtensionAtIndex(1u));
528 // Show all extensions.
529 toolbar_model()->SetVisibleIconCount(2);
530 EXPECT_EQ(2u, toolbar_model()->visible_icon_count());
531 EXPECT_TRUE(toolbar_model()->all_icons_visible());
533 // Add the third extension. Since all extensions are visible, it should go in
534 // the last index.
535 service()->AddExtension(extension_c.get());
536 EXPECT_EQ(3u, num_toolbar_items());
537 EXPECT_EQ(3u, toolbar_model()->visible_icon_count());
538 EXPECT_TRUE(toolbar_model()->all_icons_visible());
539 EXPECT_EQ(extension_b.get(), GetExtensionAtIndex(0u));
540 EXPECT_EQ(extension_a.get(), GetExtensionAtIndex(1u));
541 EXPECT_EQ(extension_c.get(), GetExtensionAtIndex(2u));
543 // Hide one extension (two remaining visible).
544 toolbar_model()->SetVisibleIconCount(2);
545 EXPECT_EQ(2u, toolbar_model()->visible_icon_count());
547 // Add a fourth extension. It should go at the end of the visible section and
548 // be visible, so it increases visible count by 1, and goes into the third
549 // index. The hidden extension should remain hidden.
550 service()->AddExtension(extension_d.get());
551 EXPECT_EQ(4u, num_toolbar_items());
552 EXPECT_EQ(3u, toolbar_model()->visible_icon_count());
553 EXPECT_EQ(extension_b.get(), GetExtensionAtIndex(0u));
554 EXPECT_EQ(extension_a.get(), GetExtensionAtIndex(1u));
555 EXPECT_EQ(extension_d.get(), GetExtensionAtIndex(2u));
556 EXPECT_EQ(extension_c.get(), GetExtensionAtIndex(3u));
559 TEST_F(ExtensionToolbarModelUnitTest, ExtensionToolbarHighlightMode) {
560 Init();
562 EXPECT_FALSE(toolbar_model()->HighlightExtensions(ExtensionIdList()));
563 EXPECT_EQ(0, observer()->highlight_mode_count());
565 // Add the three browser action extensions.
566 ASSERT_TRUE(AddBrowserActionExtensions());
567 EXPECT_EQ(3u, num_toolbar_items());
569 // Highlight one extension.
570 ExtensionIdList extension_ids;
571 extension_ids.push_back(browser_action_b()->id());
572 toolbar_model()->HighlightExtensions(extension_ids);
573 EXPECT_EQ(1, observer()->highlight_mode_count());
574 EXPECT_TRUE(toolbar_model()->is_highlighting());
576 EXPECT_EQ(1u, num_toolbar_items());
577 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0u));
579 // Stop highlighting.
580 toolbar_model()->StopHighlighting();
581 EXPECT_EQ(0, observer()->highlight_mode_count());
582 EXPECT_FALSE(toolbar_model()->is_highlighting());
584 // Verify that the extensions are back to normal.
585 EXPECT_EQ(3u, num_toolbar_items());
586 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
587 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
588 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
590 // Call stop highlighting a second time (shouldn't be notified).
591 toolbar_model()->StopHighlighting();
592 EXPECT_EQ(0, observer()->highlight_mode_count());
593 EXPECT_FALSE(toolbar_model()->is_highlighting());
595 // Highlight all extensions.
596 extension_ids.clear();
597 extension_ids.push_back(browser_action_a()->id());
598 extension_ids.push_back(browser_action_b()->id());
599 extension_ids.push_back(browser_action_c()->id());
600 toolbar_model()->HighlightExtensions(extension_ids);
601 EXPECT_EQ(1, observer()->highlight_mode_count());
602 EXPECT_EQ(3u, num_toolbar_items());
603 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
604 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
605 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
607 // Highlight only extension b (shrink the highlight list).
608 extension_ids.clear();
609 extension_ids.push_back(browser_action_b()->id());
610 toolbar_model()->HighlightExtensions(extension_ids);
611 EXPECT_EQ(2, observer()->highlight_mode_count());
612 EXPECT_EQ(1u, num_toolbar_items());
613 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0u));
615 // Highlight extensions a and b (grow the highlight list).
616 extension_ids.clear();
617 extension_ids.push_back(browser_action_a()->id());
618 extension_ids.push_back(browser_action_b()->id());
619 toolbar_model()->HighlightExtensions(extension_ids);
620 EXPECT_EQ(3, observer()->highlight_mode_count());
621 EXPECT_EQ(2u, num_toolbar_items());
622 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
623 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
625 // Highlight no extensions (empty the highlight list).
626 extension_ids.clear();
627 toolbar_model()->HighlightExtensions(extension_ids);
628 EXPECT_EQ(2, observer()->highlight_mode_count());
629 EXPECT_FALSE(toolbar_model()->is_highlighting());
630 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
631 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
632 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
635 TEST_F(ExtensionToolbarModelUnitTest, ExtensionToolbarHighlightModeRemove) {
636 Init();
638 // Add the three browser action extensions.
639 ASSERT_TRUE(AddBrowserActionExtensions());
640 EXPECT_EQ(3u, num_toolbar_items());
642 // Highlight two of the extensions.
643 ExtensionIdList extension_ids;
644 extension_ids.push_back(browser_action_a()->id());
645 extension_ids.push_back(browser_action_b()->id());
646 toolbar_model()->HighlightExtensions(extension_ids);
647 EXPECT_TRUE(toolbar_model()->is_highlighting());
648 EXPECT_EQ(1, observer()->highlight_mode_count());
649 EXPECT_EQ(2u, num_toolbar_items());
651 // Disable one of them - only one should remain highlighted.
652 service()->DisableExtension(browser_action_a()->id(),
653 Extension::DISABLE_USER_ACTION);
654 EXPECT_TRUE(toolbar_model()->is_highlighting());
655 EXPECT_EQ(1u, num_toolbar_items());
656 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0u));
658 // Uninstall the remaining highlighted extension. This should result in
659 // highlight mode exiting.
660 service()->UninstallExtension(browser_action_b()->id(),
661 UNINSTALL_REASON_FOR_TESTING,
662 base::Bind(&base::DoNothing),
663 NULL); // Ignore error.
664 EXPECT_FALSE(toolbar_model()->is_highlighting());
665 EXPECT_EQ(0, observer()->highlight_mode_count());
666 EXPECT_EQ(1u, num_toolbar_items());
667 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
669 // Test that removing an unhighlighted extension still works.
670 // Reinstall extension b, and then highlight extension c.
671 ASSERT_TRUE(AddExtension(browser_action_b()));
672 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
673 extension_ids.clear();
674 extension_ids.push_back(browser_action_c()->id());
675 toolbar_model()->HighlightExtensions(extension_ids);
676 EXPECT_EQ(1, observer()->highlight_mode_count());
677 EXPECT_TRUE(toolbar_model()->is_highlighting());
678 EXPECT_EQ(1u, num_toolbar_items());
679 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
681 // Uninstalling b should not have visible impact.
682 service()->UninstallExtension(browser_action_b()->id(),
683 UNINSTALL_REASON_FOR_TESTING,
684 base::Bind(&base::DoNothing),
685 NULL); // Ignore error.
686 EXPECT_TRUE(toolbar_model()->is_highlighting());
687 EXPECT_EQ(1, observer()->highlight_mode_count());
688 EXPECT_EQ(1u, num_toolbar_items());
689 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
691 // When we stop, only extension c should remain.
692 toolbar_model()->StopHighlighting();
693 EXPECT_FALSE(toolbar_model()->is_highlighting());
694 EXPECT_EQ(0, observer()->highlight_mode_count());
695 EXPECT_EQ(1u, num_toolbar_items());
696 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u));
699 TEST_F(ExtensionToolbarModelUnitTest, ExtensionToolbarHighlightModeAdd) {
700 Init();
702 // Add the three browser action extensions.
703 ASSERT_TRUE(AddBrowserActionExtensions());
704 EXPECT_EQ(3u, num_toolbar_items());
706 // Remove one (down to two).
707 ASSERT_TRUE(RemoveExtension(browser_action_c()));
709 // Highlight one of the two extensions.
710 ExtensionIdList extension_ids;
711 extension_ids.push_back(browser_action_a()->id());
712 toolbar_model()->HighlightExtensions(extension_ids);
713 EXPECT_TRUE(toolbar_model()->is_highlighting());
714 EXPECT_EQ(1u, num_toolbar_items());
715 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
717 // Adding a new extension should have no visible effect.
718 ASSERT_TRUE(AddExtension(browser_action_c()));
719 EXPECT_TRUE(toolbar_model()->is_highlighting());
720 EXPECT_EQ(1u, num_toolbar_items());
721 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
723 // When we stop highlighting, we should see the new extension show up.
724 toolbar_model()->StopHighlighting();
725 EXPECT_FALSE(toolbar_model()->is_highlighting());
726 EXPECT_EQ(3u, num_toolbar_items());
727 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
728 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
729 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
732 // Test that the extension toolbar maintains the proper size, even after a pref
733 // change.
734 TEST_F(ExtensionToolbarModelUnitTest, ExtensionToolbarSizeAfterPrefChange) {
735 Init();
737 // Add the three browser action extensions.
738 ASSERT_TRUE(AddBrowserActionExtensions());
739 EXPECT_EQ(3u, num_toolbar_items());
741 // Should be at max size.
742 EXPECT_TRUE(toolbar_model()->all_icons_visible());
743 EXPECT_EQ(num_toolbar_items(), toolbar_model()->visible_icon_count());
744 toolbar_model()->OnExtensionToolbarPrefChange();
745 // Should still be at max size.
746 EXPECT_TRUE(toolbar_model()->all_icons_visible());
747 EXPECT_EQ(num_toolbar_items(), toolbar_model()->visible_icon_count());
750 // Test that, in the absence of the extension-action-redesign switch, the
751 // model only contains extensions with browser actions.
752 TEST_F(ExtensionToolbarModelUnitTest, TestToolbarExtensionTypesNoSwitch) {
753 Init();
754 ASSERT_TRUE(AddActionExtensions());
756 EXPECT_EQ(1u, num_toolbar_items());
757 EXPECT_EQ(browser_action(), GetExtensionAtIndex(0u));
760 // Test that, with the extension-action-redesign switch, the model contains
761 // all types of extensions, except those which should not be displayed on the
762 // toolbar (like component extensions).
763 TEST_F(ExtensionToolbarModelUnitTest, TestToolbarExtensionTypesSwitch) {
764 FeatureSwitch::ScopedOverride enable_redesign(
765 FeatureSwitch::extension_action_redesign(), true);
766 Init();
767 ASSERT_TRUE(AddActionExtensions());
769 // With the switch on, extensions with page actions and no action should also
770 // be displayed in the toolbar.
771 EXPECT_EQ(3u, num_toolbar_items());
772 EXPECT_EQ(browser_action(), GetExtensionAtIndex(0u));
773 EXPECT_EQ(page_action(), GetExtensionAtIndex(1u));
774 EXPECT_EQ(no_action(), GetExtensionAtIndex(2u));
777 // Test that hiding actions on the toolbar results in their removal from the
778 // model when the redesign switch is not enabled.
779 TEST_F(ExtensionToolbarModelUnitTest,
780 ExtensionToolbarActionsVisibilityNoSwitch) {
781 Init();
783 ASSERT_TRUE(AddBrowserActionExtensions());
784 // Sanity check: Order should start as A B C.
785 EXPECT_EQ(3u, num_toolbar_items());
786 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
787 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
788 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
790 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
792 // By default, all actions should be visible.
793 EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
794 prefs, browser_action_a()->id()));
795 EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
796 prefs, browser_action_b()->id()));
797 EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
798 prefs, browser_action_c()->id()));
800 // Hiding an action should result in its removal from the toolbar.
801 ExtensionActionAPI::SetBrowserActionVisibility(
802 prefs, browser_action_b()->id(), false);
803 EXPECT_FALSE(ExtensionActionAPI::GetBrowserActionVisibility(
804 prefs, browser_action_b()->id()));
805 // Thus, there should now only be two items on the toolbar - A and C.
806 EXPECT_EQ(2u, num_toolbar_items());
807 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
808 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
810 // Resetting the visibility to 'true' should result in the extension being
811 // added back at its original position.
812 ExtensionActionAPI::SetBrowserActionVisibility(
813 prefs, browser_action_b()->id(), true);
814 EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
815 prefs, browser_action_b()->id()));
816 // So the toolbar order should be A B C.
817 EXPECT_EQ(3u, num_toolbar_items());
818 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
819 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u));
820 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2u));
823 TEST_F(ExtensionToolbarModelUnitTest, ExtensionToolbarIncognitoModeTest) {
824 Init();
825 ASSERT_TRUE(AddBrowserActionExtensions());
827 // Give two extensions incognito access.
828 // Note: We use ExtensionPrefs::SetIsIncognitoEnabled instead of
829 // util::SetIsIncognitoEnabled because the latter tries to reload the
830 // extension, which requries a filepath associated with the extension (and,
831 // for this test, reloading the extension is irrelevant to us).
832 ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(profile());
833 extension_prefs->SetIsIncognitoEnabled(browser_action_b()->id(), true);
834 extension_prefs->SetIsIncognitoEnabled(browser_action_c()->id(), true);
836 util::SetIsIncognitoEnabled(browser_action_b()->id(), profile(), true);
837 util::SetIsIncognitoEnabled(browser_action_c()->id(), profile(), true);
839 // Move C to the second index.
840 toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 1u);
841 // Set visible count to 2 so that c is overflowed. State is A C [B].
842 toolbar_model()->SetVisibleIconCount(2);
843 EXPECT_EQ(1u, observer()->moved_count());
845 // Get an incognito profile and toolbar.
846 ExtensionToolbarModel* incognito_model =
847 extension_action_test_util::CreateToolbarModelForProfile(
848 profile()->GetOffTheRecordProfile());
850 ExtensionToolbarModelTestObserver incognito_observer(incognito_model);
851 EXPECT_EQ(0u, incognito_observer.moved_count());
853 // We should have two items, C and B, and the order should be preserved from
854 // the original model.
855 EXPECT_EQ(2u, incognito_model->toolbar_items().size());
856 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(0u, incognito_model));
857 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1u, incognito_model));
859 // Extensions in the overflow menu in the regular toolbar should remain in
860 // overflow in the incognito toolbar. So, we should have C [B].
861 EXPECT_EQ(1u, incognito_model->visible_icon_count());
862 // The regular model should still have two icons visible.
863 EXPECT_EQ(2u, toolbar_model()->visible_icon_count());
865 // Changing the incognito model size should not affect the regular model.
866 incognito_model->SetVisibleIconCount(0);
867 EXPECT_EQ(0u, incognito_model->visible_icon_count());
868 EXPECT_EQ(2u, toolbar_model()->visible_icon_count());
870 // Expanding the incognito model to 2 should register as "all icons"
871 // since it is all of the incognito-enabled extensions.
872 incognito_model->SetVisibleIconCount(2u);
873 EXPECT_EQ(2u, incognito_model->visible_icon_count());
874 EXPECT_TRUE(incognito_model->all_icons_visible());
876 // Moving icons in the incognito toolbar should not affect the regular
877 // toolbar. Incognito currently has C B...
878 incognito_model->MoveExtensionIcon(browser_action_b()->id(), 0u);
879 // So now it should be B C...
880 EXPECT_EQ(1u, incognito_observer.moved_count());
881 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0u, incognito_model));
882 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u, incognito_model));
883 // ... and the regular toolbar should be unaffected.
884 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0u));
885 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1u));
886 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(2u));
888 // Similarly, the observer for the regular model should not have received
889 // any updates.
890 EXPECT_EQ(1u, observer()->moved_count());
892 // And performing moves on the regular model should have no effect on the
893 // incognito model or its observers.
894 toolbar_model()->MoveExtensionIcon(browser_action_c()->id(), 2u);
895 EXPECT_EQ(2u, observer()->moved_count());
896 EXPECT_EQ(1u, incognito_observer.moved_count());
899 // Test that enabling extensions incognito with an active incognito profile
900 // works.
901 TEST_F(ExtensionToolbarModelUnitTest,
902 ExtensionToolbarIncognitoEnableExtension) {
903 Init();
905 const char* kManifest =
907 " \"name\": \"%s\","
908 " \"version\": \"1.0\","
909 " \"manifest_version\": 2,"
910 " \"browser_action\": {}"
911 "}";
913 // For this test, we need to have "real" extension files, because we need to
914 // be able to reload them during the incognito process. Since the toolbar
915 // needs to be notified of the reload, we need it this time (as opposed to
916 // above, where we simply set the prefs before the incognito bar was
917 // created.
918 TestExtensionDir dir1;
919 dir1.WriteManifest(base::StringPrintf(kManifest, "incognito1"));
920 TestExtensionDir dir2;
921 dir2.WriteManifest(base::StringPrintf(kManifest, "incognito2"));
923 TestExtensionDir* dirs[] = { &dir1, &dir2 };
924 const Extension* extensions[] = { nullptr, nullptr };
925 for (size_t i = 0; i < arraysize(dirs); ++i) {
926 // The extension id will be calculated from the file path; we need this to
927 // wait for the extension to load.
928 base::FilePath path_for_id =
929 base::MakeAbsoluteFilePath(dirs[i]->unpacked_path());
930 std::string id = crx_file::id_util::GenerateIdForPath(path_for_id);
931 TestExtensionRegistryObserver observer(registry(), id);
932 UnpackedInstaller::Create(service())->Load(dirs[i]->unpacked_path());
933 observer.WaitForExtensionLoaded();
934 extensions[i] = registry()->enabled_extensions().GetByID(id);
935 ASSERT_TRUE(extensions[i]);
938 // For readability, alias to A and B. Since we'll be reloading these
939 // extensions, we also can't rely on pointers.
940 std::string extension_a = extensions[0]->id();
941 std::string extension_b = extensions[1]->id();
943 // The first model should have both extensions visible.
944 EXPECT_EQ(2u, toolbar_model()->toolbar_items().size());
945 EXPECT_EQ(extension_a, GetExtensionAtIndex(0)->id());
946 EXPECT_EQ(extension_b, GetExtensionAtIndex(1)->id());
948 // Set the model to only show one extension, so the order is A [B].
949 toolbar_model()->SetVisibleIconCount(1u);
951 // Get an incognito profile and toolbar.
952 ExtensionToolbarModel* incognito_model =
953 extension_action_test_util::CreateToolbarModelForProfile(
954 profile()->GetOffTheRecordProfile());
955 ExtensionToolbarModelTestObserver incognito_observer(incognito_model);
957 // Right now, no extensions are enabled in incognito mode.
958 EXPECT_EQ(0u, incognito_model->toolbar_items().size());
960 // Set extension b (which is overflowed) to be enabled in incognito. This
961 // results in b reloading, so wait for it.
963 TestExtensionRegistryObserver observer(registry(), extension_b);
964 util::SetIsIncognitoEnabled(extension_b, profile(), true);
965 observer.WaitForExtensionLoaded();
968 // Now, we should have one icon in the incognito bar. But, since B is
969 // overflowed in the main bar, it shouldn't be visible.
970 EXPECT_EQ(1u, incognito_model->toolbar_items().size());
971 EXPECT_EQ(extension_b, GetExtensionAtIndex(0u, incognito_model)->id());
972 EXPECT_EQ(0u, incognito_model->visible_icon_count());
974 // Also enable extension a for incognito (again, wait for the reload).
976 TestExtensionRegistryObserver observer(registry(), extension_a);
977 util::SetIsIncognitoEnabled(extension_a, profile(), true);
978 observer.WaitForExtensionLoaded();
981 // Now, both extensions should be enabled in incognito mode. In addition, the
982 // incognito toolbar should have expanded to show extension a (since it isn't
983 // overflowed in the main bar).
984 EXPECT_EQ(2u, incognito_model->toolbar_items().size());
985 EXPECT_EQ(extension_a, GetExtensionAtIndex(0u, incognito_model)->id());
986 EXPECT_EQ(extension_b, GetExtensionAtIndex(1u, incognito_model)->id());
987 EXPECT_EQ(1u, incognito_model->visible_icon_count());
990 // Test that hiding actions on the toolbar results in sending them to the
991 // overflow menu when the redesign switch is enabled.
992 TEST_F(ExtensionToolbarModelUnitTest,
993 ExtensionToolbarActionsVisibilityWithSwitch) {
994 FeatureSwitch::ScopedOverride enable_redesign(
995 FeatureSwitch::extension_action_redesign(), true);
996 Init();
998 // We choose to use all types of extensions here, since the misnamed
999 // BrowserActionVisibility is now for toolbar visibility.
1000 ASSERT_TRUE(AddActionExtensions());
1002 // For readability, alias extensions A B C.
1003 const Extension* extension_a = browser_action();
1004 const Extension* extension_b = page_action();
1005 const Extension* extension_c = no_action();
1007 // Sanity check: Order should start as A B C, with all three visible.
1008 EXPECT_EQ(3u, num_toolbar_items());
1009 EXPECT_TRUE(toolbar_model()->all_icons_visible());
1010 EXPECT_EQ(extension_a, GetExtensionAtIndex(0u));
1011 EXPECT_EQ(extension_b, GetExtensionAtIndex(1u));
1012 EXPECT_EQ(extension_c, GetExtensionAtIndex(2u));
1014 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1016 // By default, all actions should be visible.
1017 EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
1018 prefs, extension_a->id()));
1019 EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
1020 prefs, extension_c->id()));
1021 EXPECT_TRUE(ExtensionActionAPI::GetBrowserActionVisibility(
1022 prefs, extension_b->id()));
1024 // Hiding an action should result in it being sent to the overflow menu.
1025 ExtensionActionAPI::SetBrowserActionVisibility(
1026 prefs, extension_b->id(), false);
1028 // Thus, the order should be A C B, with B in the overflow.
1029 EXPECT_EQ(3u, num_toolbar_items());
1030 EXPECT_EQ(2u, toolbar_model()->visible_icon_count());
1031 EXPECT_EQ(extension_a, GetExtensionAtIndex(0u));
1032 EXPECT_EQ(extension_c, GetExtensionAtIndex(1u));
1033 EXPECT_EQ(extension_b, GetExtensionAtIndex(2u));
1035 // Hiding an extension's action should result in it being sent to the overflow
1036 // as well, but as the _first_ extension in the overflow.
1037 ExtensionActionAPI::SetBrowserActionVisibility(
1038 prefs, extension_a->id(), false);
1039 // Thus, the order should be C A B, with A and B in the overflow.
1040 EXPECT_EQ(3u, num_toolbar_items());
1041 EXPECT_EQ(1u, toolbar_model()->visible_icon_count());
1042 EXPECT_EQ(extension_c, GetExtensionAtIndex(0u));
1043 EXPECT_EQ(extension_a, GetExtensionAtIndex(1u));
1044 EXPECT_EQ(extension_b, GetExtensionAtIndex(2u));
1046 // Resetting A's visibility to true should send it back to the visible icons
1047 // (and should grow visible icons by 1), but it should be added to the end of
1048 // the visible icon list (not to its original position).
1049 ExtensionActionAPI::SetBrowserActionVisibility(
1050 prefs, extension_a->id(), true);
1051 // So order is C A B, with only B in the overflow.
1052 EXPECT_EQ(3u, num_toolbar_items());
1053 EXPECT_EQ(2u, toolbar_model()->visible_icon_count());
1054 EXPECT_EQ(extension_c, GetExtensionAtIndex(0u));
1055 EXPECT_EQ(extension_a, GetExtensionAtIndex(1u));
1056 EXPECT_EQ(extension_b, GetExtensionAtIndex(2u));
1058 // Resetting B to be visible should make the order C A B, with no overflow.
1059 ExtensionActionAPI::SetBrowserActionVisibility(
1060 prefs, extension_b->id(), true);
1061 EXPECT_EQ(3u, num_toolbar_items());
1062 EXPECT_TRUE(toolbar_model()->all_icons_visible());
1063 EXPECT_EQ(extension_c, GetExtensionAtIndex(0u));
1064 EXPECT_EQ(extension_a, GetExtensionAtIndex(1u));
1065 EXPECT_EQ(extension_b, GetExtensionAtIndex(2u));
1068 // Test that observers receive no Added notifications until after the
1069 // ExtensionSystem has initialized.
1070 TEST_F(ExtensionToolbarModelUnitTest, ModelWaitsForExtensionSystemReady) {
1071 InitializeEmptyExtensionService();
1072 ExtensionToolbarModel* toolbar_model =
1073 extension_action_test_util::
1074 CreateToolbarModelForProfileWithoutWaitingForReady(profile());
1075 ExtensionToolbarModelTestObserver model_observer(toolbar_model);
1076 EXPECT_TRUE(AddBrowserActionExtensions());
1078 // Since the model hasn't been initialized (the ExtensionSystem::ready task
1079 // hasn't been run), there should be no insertion notifications.
1080 EXPECT_EQ(0u, model_observer.inserted_count());
1081 EXPECT_EQ(0u, model_observer.initialized_count());
1082 EXPECT_FALSE(toolbar_model->extensions_initialized());
1084 // Run the ready task.
1085 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile()))->
1086 SetReady();
1087 // Run tasks posted to TestExtensionSystem.
1088 base::RunLoop().RunUntilIdle();
1090 // We should still have no insertions, but should have an initialized count.
1091 EXPECT_TRUE(toolbar_model->extensions_initialized());
1092 EXPECT_EQ(0u, model_observer.inserted_count());
1093 EXPECT_EQ(1u, model_observer.initialized_count());
1096 // Check that the toolbar model correctly clears and reorders when it detects
1097 // a preference change.
1098 TEST_F(ExtensionToolbarModelUnitTest, ToolbarModelPrefChange) {
1099 Init();
1101 ASSERT_TRUE(AddBrowserActionExtensions());
1103 // We should start in the basic A B C order.
1104 ASSERT_TRUE(browser_action_a());
1105 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(0));
1106 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(1));
1107 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(2));
1108 // Record the difference between the inserted and removed counts. The actual
1109 // value of the counts is not important, but we need to be sure that if we
1110 // call to remove any, we also add them back.
1111 size_t inserted_and_removed_difference =
1112 observer()->inserted_count() - observer()->removed_count();
1114 // Assign a new order, B C A, and write it in the prefs.
1115 ExtensionIdList new_order;
1116 new_order.push_back(browser_action_b()->id());
1117 new_order.push_back(browser_action_c()->id());
1118 new_order.push_back(browser_action_a()->id());
1119 ExtensionPrefs::Get(profile())->SetToolbarOrder(new_order);
1121 // Ensure everything has time to run.
1122 base::RunLoop().RunUntilIdle();
1124 // The new order should be reflected in the model.
1125 EXPECT_EQ(browser_action_b(), GetExtensionAtIndex(0));
1126 EXPECT_EQ(browser_action_c(), GetExtensionAtIndex(1));
1127 EXPECT_EQ(browser_action_a(), GetExtensionAtIndex(2));
1128 EXPECT_EQ(inserted_and_removed_difference,
1129 observer()->inserted_count() - observer()->removed_count());
1132 } // namespace extensions