• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2010 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/extension_browsertest.h"
6 #include "chrome/browser/extensions/extension_service.h"
7 #include "chrome/browser/extensions/extension_toolbar_model.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/common/chrome_switches.h"
11 #include "chrome/test/in_process_browser_test.h"
12 
13 // An InProcessBrowserTest for testing the ExtensionToolbarModel.
14 // TODO(erikkay) It's unfortunate that this needs to be an in-proc browser test.
15 // It would be nice to refactor things so that ExtensionService could run
16 // without so much of the browser in place.
17 class ExtensionToolbarModelTest : public ExtensionBrowserTest,
18                                   public ExtensionToolbarModel::Observer {
19  public:
SetUp()20   virtual void SetUp() {
21     inserted_count_ = 0;
22     removed_count_ = 0;
23     moved_count_ = 0;
24 
25     ExtensionBrowserTest::SetUp();
26   }
27 
CreateBrowser(Profile * profile)28   virtual Browser* CreateBrowser(Profile* profile) {
29     Browser* b = InProcessBrowserTest::CreateBrowser(profile);
30     ExtensionService* service = b->profile()->GetExtensionService();
31     model_ = service->toolbar_model();
32     model_->AddObserver(this);
33     return b;
34   }
35 
CleanUpOnMainThread()36   virtual void CleanUpOnMainThread() {
37     model_->RemoveObserver(this);
38   }
39 
BrowserActionAdded(const Extension * extension,int index)40   virtual void BrowserActionAdded(const Extension* extension, int index) {
41     inserted_count_++;
42   }
43 
BrowserActionRemoved(const Extension * extension)44   virtual void BrowserActionRemoved(const Extension* extension) {
45     removed_count_++;
46   }
47 
BrowserActionMoved(const Extension * extension,int index)48   virtual void BrowserActionMoved(const Extension* extension, int index) {
49     moved_count_++;
50   }
51 
ExtensionAt(int index)52   const Extension* ExtensionAt(int index) {
53     for (ExtensionList::iterator i = model_->begin(); i < model_->end(); ++i) {
54       if (index-- == 0)
55         return *i;
56     }
57     return NULL;
58   }
59 
60  protected:
61   ExtensionToolbarModel* model_;
62 
63   int inserted_count_;
64   int removed_count_;
65   int moved_count_;
66 };
67 
IN_PROC_BROWSER_TEST_F(ExtensionToolbarModelTest,Basic)68 IN_PROC_BROWSER_TEST_F(ExtensionToolbarModelTest, Basic) {
69   CommandLine::ForCurrentProcess()->AppendSwitch(
70       switches::kEnableExperimentalExtensionApis);
71 
72   // Load an extension with no browser action.
73   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
74                                           .AppendASCII("browser_action")
75                                           .AppendASCII("none")));
76 
77   // This extension should not be in the model (has no browser action).
78   EXPECT_EQ(0, inserted_count_);
79   EXPECT_EQ(0u, model_->size());
80   ASSERT_EQ(NULL, ExtensionAt(0));
81 
82   // Load an extension with a browser action.
83   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("api_test")
84                                           .AppendASCII("browser_action")
85                                           .AppendASCII("basics")));
86 
87   // We should now find our extension in the model.
88   EXPECT_EQ(1, inserted_count_);
89   EXPECT_EQ(1u, model_->size());
90   const Extension* extension = ExtensionAt(0);
91   ASSERT_TRUE(NULL != extension);
92   EXPECT_STREQ("A browser action with no icon that makes the page red",
93                extension->name().c_str());
94 
95   // Should be a no-op, but still fires the events.
96   model_->MoveBrowserAction(extension, 0);
97   EXPECT_EQ(1, moved_count_);
98   EXPECT_EQ(1u, model_->size());
99   const Extension* extension2 = ExtensionAt(0);
100   EXPECT_EQ(extension, extension2);
101 
102   UnloadExtension(extension->id());
103   EXPECT_EQ(1, removed_count_);
104   EXPECT_EQ(0u, model_->size());
105   EXPECT_EQ(NULL, ExtensionAt(0));
106 }
107 
IN_PROC_BROWSER_TEST_F(ExtensionToolbarModelTest,ReorderAndReinsert)108 IN_PROC_BROWSER_TEST_F(ExtensionToolbarModelTest, ReorderAndReinsert) {
109   CommandLine::ForCurrentProcess()->AppendSwitch(
110       switches::kEnableExperimentalExtensionApis);
111 
112   // Load an extension with a browser action.
113   FilePath extension_a_path(test_data_dir_.AppendASCII("api_test")
114                                           .AppendASCII("browser_action")
115                                           .AppendASCII("basics"));
116   ASSERT_TRUE(LoadExtension(extension_a_path));
117 
118   // First extension loaded.
119   EXPECT_EQ(1, inserted_count_);
120   EXPECT_EQ(1u, model_->size());
121   const Extension* extensionA = ExtensionAt(0);
122   ASSERT_TRUE(NULL != extensionA);
123   EXPECT_STREQ("A browser action with no icon that makes the page red",
124                extensionA->name().c_str());
125 
126   // Load another extension with a browser action.
127   FilePath extension_b_path(test_data_dir_.AppendASCII("api_test")
128                                           .AppendASCII("browser_action")
129                                           .AppendASCII("popup"));
130   ASSERT_TRUE(LoadExtension(extension_b_path));
131 
132   // Second extension loaded.
133   EXPECT_EQ(2, inserted_count_);
134   EXPECT_EQ(2u, model_->size());
135   const Extension* extensionB = ExtensionAt(1);
136   ASSERT_TRUE(NULL != extensionB);
137   EXPECT_STREQ("Popup tester", extensionB->name().c_str());
138 
139   // Load yet another extension with a browser action.
140   FilePath extension_c_path(test_data_dir_.AppendASCII("api_test")
141                                           .AppendASCII("browser_action")
142                                           .AppendASCII("remove_popup"));
143   ASSERT_TRUE(LoadExtension(extension_c_path));
144 
145   // Third extension loaded.
146   EXPECT_EQ(3, inserted_count_);
147   EXPECT_EQ(3u, model_->size());
148   const Extension* extensionC = ExtensionAt(2);
149   ASSERT_TRUE(NULL != extensionC);
150   EXPECT_STREQ("A page action which removes a popup.",
151                extensionC->name().c_str());
152 
153   // Order is now A, B, C. Let's put C first.
154   model_->MoveBrowserAction(extensionC, 0);
155   EXPECT_EQ(1, moved_count_);
156   EXPECT_EQ(3u, model_->size());
157   EXPECT_EQ(extensionC, ExtensionAt(0));
158   EXPECT_EQ(extensionA, ExtensionAt(1));
159   EXPECT_EQ(extensionB, ExtensionAt(2));
160   EXPECT_EQ(NULL, ExtensionAt(3));
161 
162   // Order is now C, A, B. Let's put A last.
163   model_->MoveBrowserAction(extensionA, 2);
164   EXPECT_EQ(2, moved_count_);
165   EXPECT_EQ(3u, model_->size());
166   EXPECT_EQ(extensionC, ExtensionAt(0));
167   EXPECT_EQ(extensionB, ExtensionAt(1));
168   EXPECT_EQ(extensionA, ExtensionAt(2));
169   EXPECT_EQ(NULL, ExtensionAt(3));
170 
171   // Order is now C, B, A. Let's remove B.
172   std::string idB = extensionB->id();
173   UnloadExtension(idB);
174   EXPECT_EQ(1, removed_count_);
175   EXPECT_EQ(2u, model_->size());
176   EXPECT_EQ(extensionC, ExtensionAt(0));
177   EXPECT_EQ(extensionA, ExtensionAt(1));
178   EXPECT_EQ(NULL, ExtensionAt(2));
179 
180   // Load extension B again.
181   ASSERT_TRUE(LoadExtension(extension_b_path));
182 
183   // Extension B loaded again.
184   EXPECT_EQ(4, inserted_count_);
185   EXPECT_EQ(3u, model_->size());
186   // Make sure it gets its old spot in the list. We should get the same
187   // extension again, otherwise the order has changed.
188   ASSERT_STREQ(idB.c_str(), ExtensionAt(1)->id().c_str());
189 
190   // Unload B again.
191   UnloadExtension(idB);
192   EXPECT_EQ(2, removed_count_);
193   EXPECT_EQ(2u, model_->size());
194   EXPECT_EQ(extensionC, ExtensionAt(0));
195   EXPECT_EQ(extensionA, ExtensionAt(1));
196   EXPECT_EQ(NULL, ExtensionAt(2));
197 
198   // Order is now C, A. Flip it.
199   model_->MoveBrowserAction(extensionA, 0);
200   EXPECT_EQ(3, moved_count_);
201   EXPECT_EQ(2u, model_->size());
202   EXPECT_EQ(extensionA, ExtensionAt(0));
203   EXPECT_EQ(extensionC, ExtensionAt(1));
204   EXPECT_EQ(NULL, ExtensionAt(2));
205 
206   // Move A to the location it already occupies.
207   model_->MoveBrowserAction(extensionA, 0);
208   EXPECT_EQ(4, moved_count_);
209   EXPECT_EQ(2u, model_->size());
210   EXPECT_EQ(extensionA, ExtensionAt(0));
211   EXPECT_EQ(extensionC, ExtensionAt(1));
212   EXPECT_EQ(NULL, ExtensionAt(2));
213 
214   // Order is now A, C. Remove C.
215   std::string idC = extensionC->id();
216   UnloadExtension(idC);
217   EXPECT_EQ(3, removed_count_);
218   EXPECT_EQ(1u, model_->size());
219   EXPECT_EQ(extensionA, ExtensionAt(0));
220   EXPECT_EQ(NULL, ExtensionAt(1));
221 
222   // Load extension C again.
223   ASSERT_TRUE(LoadExtension(extension_c_path));
224 
225   // Extension C loaded again.
226   EXPECT_EQ(5, inserted_count_);
227   EXPECT_EQ(2u, model_->size());
228   // Make sure it gets its old spot in the list (at the very end).
229   ASSERT_STREQ(idC.c_str(), ExtensionAt(1)->id().c_str());
230 }
231