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