OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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/ui/views/aura/launcher/launcher_updater.h" | |
6 | |
7 #include <map> | |
8 #include <string> | |
9 | |
10 #include "ash/launcher/launcher_model.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
13 #include "chrome/browser/ui/views/aura/launcher/chrome_launcher_delegate.h" | |
14 #include "chrome/browser/tabs/tab_strip_model.h" | |
15 #include "chrome/browser/tabs/test_tab_strip_model_delegate.h" | |
16 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | |
17 #include "chrome/test/base/testing_profile.h" | |
18 #include "content/browser/tab_contents/test_tab_contents.h" | |
19 #include "content/test/test_browser_thread.h" | |
20 #include "testing/gtest/include/gtest/gtest.h" | |
21 #include "third_party/skia/include/core/SkBitmap.h" | |
22 #include "ui/aura/window.h" | |
23 | |
24 namespace { | |
25 | |
26 // Test implementation of AppIconLoader. | |
27 class AppIconLoaderImpl : public ChromeLauncherDelegate::AppIconLoader { | |
28 public: | |
29 AppIconLoaderImpl() : fetch_count_(0) {} | |
30 virtual ~AppIconLoaderImpl() {} | |
31 | |
32 // Sets the id for the specified tab. The id is removed if Remove() is | |
33 // invoked. | |
34 void SetAppID(TabContentsWrapper* tab, const std::string& id) { | |
35 tab_id_map_[tab] = id; | |
36 } | |
37 | |
38 // Returns true if there is an id registered for |tab|. | |
39 bool HasAppID(TabContentsWrapper* tab) const { | |
40 return tab_id_map_.find(tab) != tab_id_map_.end(); | |
41 } | |
42 | |
43 // Returns the number of times FetchImage() has been invoked and resets the | |
44 // count to 0. | |
45 int GetAndClearFetchCount() { | |
46 int value = fetch_count_; | |
47 fetch_count_ = 0; | |
48 return value; | |
49 } | |
50 | |
51 // AppIconLoader implementation: | |
52 virtual std::string GetAppID(TabContentsWrapper* tab) OVERRIDE { | |
53 return tab_id_map_.find(tab) != tab_id_map_.end() ? tab_id_map_[tab] : | |
54 std::string(); | |
55 } | |
56 | |
57 virtual bool IsValidID(const std::string& id) OVERRIDE { | |
58 for (TabToStringMap::const_iterator i = tab_id_map_.begin(); | |
59 i != tab_id_map_.end(); ++i) { | |
60 if (i->second == id) | |
61 return true; | |
62 } | |
63 return false; | |
64 } | |
65 | |
66 virtual void FetchImage(const std::string& id) OVERRIDE { | |
67 fetch_count_++; | |
68 } | |
69 | |
70 private: | |
71 typedef std::map<TabContentsWrapper*, std::string> TabToStringMap; | |
72 | |
73 TabToStringMap tab_id_map_; | |
74 | |
75 int fetch_count_; | |
76 | |
77 DISALLOW_COPY_AND_ASSIGN(AppIconLoaderImpl); | |
78 }; | |
79 | |
80 // Contains all the objects needed to create a LauncherUpdater. | |
81 struct State { | |
82 State(Profile* profile, | |
83 ChromeLauncherDelegate* launcher_delegate, | |
84 const std::string& app_id, | |
85 LauncherUpdater::Type launcher_type) | |
86 : window(NULL), | |
87 tab_strip(&tab_strip_delegate, profile), | |
88 updater(&window, &tab_strip, launcher_delegate, launcher_type, | |
89 app_id) { | |
90 updater.Init(); | |
91 } | |
92 | |
93 aura::Window window; | |
94 TestTabStripModelDelegate tab_strip_delegate; | |
95 TabStripModel tab_strip; | |
96 LauncherUpdater updater; | |
97 | |
98 private: | |
99 DISALLOW_COPY_AND_ASSIGN(State); | |
100 }; | |
101 | |
102 } // namespace | |
103 | |
104 class LauncherUpdaterTest : public ChromeRenderViewHostTestHarness { | |
105 public: | |
106 LauncherUpdaterTest() | |
107 : browser_thread_(content::BrowserThread::UI, &message_loop_) { | |
108 } | |
109 | |
110 virtual void SetUp() OVERRIDE { | |
111 ChromeRenderViewHostTestHarness::SetUp(); | |
112 launcher_model_.reset(new ash::LauncherModel); | |
113 launcher_delegate_.reset( | |
114 new ChromeLauncherDelegate(profile(), launcher_model_.get())); | |
115 app_icon_loader_ = new AppIconLoaderImpl; | |
116 launcher_delegate_->SetAppIconLoaderForTest(app_icon_loader_); | |
117 launcher_delegate_->Init(); | |
118 } | |
119 | |
120 protected: | |
121 LauncherUpdater* GetUpdaterByID(ash::LauncherID id) const { | |
122 return launcher_delegate_->id_to_item_map_[id].updater; | |
123 } | |
124 | |
125 const std::string& GetAppID(ash::LauncherID id) const { | |
126 return launcher_delegate_->id_to_item_map_[id].app_id; | |
127 } | |
128 | |
129 void ResetAppIconLoader() { | |
130 launcher_delegate_->SetAppIconLoaderForTest(app_icon_loader_); | |
131 } | |
132 | |
133 void UnpinAppsWithID(const std::string& app_id) { | |
134 launcher_delegate_->UnpinAppsWithID(app_id); | |
135 } | |
136 | |
137 scoped_ptr<ash::LauncherModel> launcher_model_; | |
138 scoped_ptr<ChromeLauncherDelegate> launcher_delegate_; | |
139 | |
140 // Owned by LauncherUpdater. | |
141 AppIconLoaderImpl* app_icon_loader_; | |
142 | |
143 private: | |
144 content::TestBrowserThread browser_thread_; | |
145 | |
146 DISALLOW_COPY_AND_ASSIGN(LauncherUpdaterTest); | |
147 }; | |
148 | |
149 // Verifies a new launcher item is added for TYPE_TABBED. | |
150 TEST_F(LauncherUpdaterTest, TabbedSetup) { | |
151 size_t initial_size = launcher_model_->items().size(); | |
152 { | |
153 TabContentsWrapper wrapper(CreateTestTabContents()); | |
154 State state(profile(), launcher_delegate_.get(), std::string(), | |
155 LauncherUpdater::TYPE_TABBED); | |
156 // Since the type is tabbed and there is nothing in the tabstrip an item | |
157 // should not have been added. | |
158 EXPECT_EQ(initial_size, launcher_model_->items().size()); | |
159 | |
160 // Add a tab. | |
161 state.tab_strip.InsertTabContentsAt(0, &wrapper, TabStripModel::ADD_NONE); | |
162 | |
163 // There should be one more item. | |
164 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
165 // New item should be added at the end. | |
166 EXPECT_EQ(ash::TYPE_TABBED, launcher_model_->items()[initial_size].type); | |
167 } | |
168 // Deleting the LauncherUpdater should have removed the item. | |
169 ASSERT_EQ(initial_size, launcher_model_->items().size()); | |
170 | |
171 // Do the same, but this time add the tab first. | |
172 { | |
173 TabContentsWrapper wrapper(CreateTestTabContents()); | |
174 | |
175 TestTabStripModelDelegate tab_strip_delegate; | |
176 TabStripModel tab_strip(&tab_strip_delegate, profile()); | |
177 tab_strip.InsertTabContentsAt(0, &wrapper, TabStripModel::ADD_NONE); | |
178 LauncherUpdater updater(NULL, &tab_strip, launcher_delegate_.get(), | |
179 LauncherUpdater::TYPE_TABBED, std::string()); | |
180 updater.Init(); | |
181 | |
182 // There should be one more item. | |
183 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
184 // New item should be added at the end. | |
185 EXPECT_EQ(ash::TYPE_TABBED, launcher_model_->items()[initial_size].type); | |
186 } | |
187 } | |
188 | |
189 // Verifies a new launcher item is added for TYPE_APP. | |
190 TEST_F(LauncherUpdaterTest, AppSetup) { | |
191 size_t initial_size = launcher_model_->items().size(); | |
192 { | |
193 State state(profile(), launcher_delegate_.get(), std::string(), | |
194 LauncherUpdater::TYPE_APP); | |
195 // There should be one more item. | |
196 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
197 // New item should be added at the end. | |
198 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
199 } | |
200 // Deleting the LauncherUpdater should have removed the item. | |
201 ASSERT_EQ(initial_size, launcher_model_->items().size()); | |
202 } | |
203 | |
204 // Various assertions when adding/removing a tab that has an app associated with | |
205 // it. | |
206 TEST_F(LauncherUpdaterTest, TabbedWithApp) { | |
207 size_t initial_size = launcher_model_->items().size(); | |
208 { | |
209 TabContentsWrapper initial_tab(CreateTestTabContents()); | |
210 State state(profile(), launcher_delegate_.get(), std::string(), | |
211 LauncherUpdater::TYPE_TABBED); | |
212 // Add a tab. | |
213 state.tab_strip.InsertTabContentsAt(0, &initial_tab, | |
214 TabStripModel::ADD_NONE); | |
215 | |
216 // There should be one more item. | |
217 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
218 // New item should be added at the end. | |
219 EXPECT_EQ(ash::TYPE_TABBED, launcher_model_->items()[initial_size].type); | |
220 ash::LauncherID tabbed_id = launcher_model_->items()[initial_size].id; | |
221 | |
222 // Add another tab, configure it so that the launcher thinks it's an app. | |
223 TabContentsWrapper app_tab(CreateTestTabContents()); | |
224 app_icon_loader_->SetAppID(&app_tab, "1"); | |
225 state.tab_strip.InsertTabContentsAt(1, &app_tab, TabStripModel::ADD_NONE); | |
226 | |
227 // There should be one more item. | |
228 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
229 // New item should be added at the end. | |
230 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size + 1].type); | |
231 | |
232 // Remove the first tab, this should trigger removing the tabbed item. | |
233 state.tab_strip.DetachTabContentsAt(0); | |
234 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
235 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size + 1].type); | |
236 EXPECT_EQ(-1, launcher_model_->ItemIndexByID(tabbed_id)); | |
237 | |
238 // Add back the tab, which triggers creating the tabbed item. | |
239 state.tab_strip.InsertTabContentsAt(0, &initial_tab, | |
240 TabStripModel::ADD_NONE); | |
241 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
242 EXPECT_EQ(ash::TYPE_TABBED, | |
243 launcher_model_->items()[initial_size].type); | |
244 | |
245 } | |
246 // Deleting the LauncherUpdater should have removed the item. | |
247 ASSERT_EQ(initial_size, launcher_model_->items().size()); | |
248 } | |
249 | |
250 TEST_F(LauncherUpdaterTest, TabbedWithAppOnCreate) { | |
251 size_t initial_size = launcher_model_->items().size(); | |
252 aura::Window window(NULL); | |
253 TestTabStripModelDelegate tab_strip_delegate; | |
254 TabStripModel tab_strip(&tab_strip_delegate, profile()); | |
255 TabContentsWrapper app_tab(CreateTestTabContents()); | |
256 app_icon_loader_->SetAppID(&app_tab, "1"); | |
257 tab_strip.InsertTabContentsAt(0, &app_tab, TabStripModel::ADD_NONE); | |
258 LauncherUpdater updater(&window, &tab_strip, launcher_delegate_.get(), | |
259 LauncherUpdater::TYPE_TABBED, std::string()); | |
260 updater.Init(); | |
261 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
262 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
263 } | |
264 | |
265 // Verifies transitioning from a normal tab to app tab and back works. | |
266 TEST_F(LauncherUpdaterTest, ChangeToApp) { | |
267 size_t initial_size = launcher_model_->items().size(); | |
268 { | |
269 TabContentsWrapper initial_tab(CreateTestTabContents()); | |
270 State state(profile(), launcher_delegate_.get(), std::string(), | |
271 LauncherUpdater::TYPE_TABBED); | |
272 // Add a tab. | |
273 state.tab_strip.InsertTabContentsAt(0, &initial_tab, | |
274 TabStripModel::ADD_NONE); | |
275 | |
276 // There should be one more item. | |
277 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
278 // New item should be added at the end. | |
279 EXPECT_EQ(ash::TYPE_TABBED, launcher_model_->items()[initial_size].type); | |
280 ash::LauncherID tabbed_id = launcher_model_->items()[initial_size].id; | |
281 | |
282 app_icon_loader_->SetAppID(&initial_tab, "1"); | |
283 // Triggers LauncherUpdater seeing the tab changed to an app. | |
284 state.updater.TabChangedAt(&initial_tab, 0, TabStripModelObserver::ALL); | |
285 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
286 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
287 EXPECT_EQ(tabbed_id, launcher_model_->items()[initial_size].id); | |
288 | |
289 // Change back to a non-app and make sure the tabbed item is added back. | |
290 app_icon_loader_->SetAppID(&initial_tab, std::string()); | |
291 state.updater.TabChangedAt(&initial_tab, 0, TabStripModelObserver::ALL); | |
292 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
293 EXPECT_EQ(ash::TYPE_TABBED, launcher_model_->items()[initial_size].type); | |
294 EXPECT_EQ(tabbed_id, launcher_model_->items()[initial_size].id); | |
295 } | |
296 // Deleting the LauncherUpdater should have removed the item. | |
297 ASSERT_EQ(initial_size, launcher_model_->items().size()); | |
298 } | |
299 | |
300 // Verifies AppIconLoader is queried appropriately. | |
301 TEST_F(LauncherUpdaterTest, QueryAppIconLoader) { | |
302 size_t initial_size = launcher_model_->items().size(); | |
303 { | |
304 TabContentsWrapper initial_tab(CreateTestTabContents()); | |
305 State state(profile(), launcher_delegate_.get(), std::string(), | |
306 LauncherUpdater::TYPE_TABBED); | |
307 // Configure the tab as an app. | |
308 app_icon_loader_->SetAppID(&initial_tab, "1"); | |
309 // Add a tab. | |
310 state.tab_strip.InsertTabContentsAt(0, &initial_tab, | |
311 TabStripModel::ADD_NONE); | |
312 // AppIconLoader should have been queried. | |
313 EXPECT_GT(app_icon_loader_->GetAndClearFetchCount(), 0); | |
314 // Remove the tab. | |
315 state.tab_strip.DetachTabContentsAt(0); | |
316 } | |
317 // Deleting the LauncherUpdater should have removed the item. | |
318 ASSERT_EQ(initial_size, launcher_model_->items().size()); | |
319 } | |
320 | |
321 // Verifies SetAppImage works. | |
322 TEST_F(LauncherUpdaterTest, SetAppImage) { | |
323 size_t initial_size = launcher_model_->items().size(); | |
324 TabContentsWrapper initial_tab(CreateTestTabContents()); | |
325 State state(profile(), launcher_delegate_.get(), std::string(), | |
326 LauncherUpdater::TYPE_TABBED); | |
327 // Configure the tab as an app. | |
328 app_icon_loader_->SetAppID(&initial_tab, "1"); | |
329 // Add a tab. | |
330 state.tab_strip.InsertTabContentsAt(0, &initial_tab, | |
331 TabStripModel::ADD_NONE); | |
332 SkBitmap image; | |
333 image.setConfig(SkBitmap::kARGB_8888_Config, 2, 3); | |
334 image.allocPixels(); | |
335 launcher_delegate_->SetAppImage("1", &image); | |
336 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
337 EXPECT_EQ(2, launcher_model_->items()[initial_size].image.width()); | |
338 EXPECT_EQ(3, launcher_model_->items()[initial_size].image.height()); | |
339 } | |
340 | |
341 // Verifies app tabs are added right after the existing tabbed item. | |
342 TEST_F(LauncherUpdaterTest, AddAppAfterTabbed) { | |
343 size_t initial_size = launcher_model_->items().size(); | |
344 TabContentsWrapper tab1(CreateTestTabContents()); | |
345 State state1(profile(), launcher_delegate_.get(), std::string(), | |
346 LauncherUpdater::TYPE_TABBED); | |
347 // Add a tab. | |
348 state1.tab_strip.InsertTabContentsAt(0, &tab1, TabStripModel::ADD_NONE); | |
349 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
350 ash::LauncherID tabbed_id = launcher_model_->items()[initial_size].id; | |
351 | |
352 // Create another LauncherUpdater. | |
353 State state2(profile(), launcher_delegate_.get(), std::string(), | |
354 LauncherUpdater::TYPE_APP); | |
355 | |
356 // Should be two extra items. | |
357 EXPECT_EQ(initial_size + 2, launcher_model_->items().size()); | |
358 | |
359 // Add an app tab to state1, it should go after the item for state1 but | |
360 // before the item for state2. | |
361 int next_id = launcher_model_->next_id(); | |
362 TabContentsWrapper app_tab(CreateTestTabContents()); | |
363 app_icon_loader_->SetAppID(&app_tab, "1"); | |
364 state1.tab_strip.InsertTabContentsAt(1, &app_tab, TabStripModel::ADD_NONE); | |
365 | |
366 ASSERT_EQ(initial_size + 3, launcher_model_->items().size()); | |
367 EXPECT_EQ(next_id, launcher_model_->items()[initial_size + 1].id); | |
368 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size + 1].type); | |
369 | |
370 // Remove the non-app tab. | |
371 state1.tab_strip.DetachTabContentsAt(0); | |
372 // Should have removed one item. | |
373 EXPECT_EQ(initial_size + 2, launcher_model_->items().size()); | |
374 EXPECT_EQ(-1, launcher_model_->ItemIndexByID(tabbed_id)); | |
375 next_id = launcher_model_->next_id(); | |
376 // Add the non-app tab back. It should go to the original position (but get a | |
377 // new id). | |
378 state1.tab_strip.InsertTabContentsAt(0, &tab1, TabStripModel::ADD_NONE); | |
379 ASSERT_EQ(initial_size + 3, launcher_model_->items().size()); | |
380 EXPECT_EQ(next_id, launcher_model_->items()[initial_size].id); | |
381 } | |
382 | |
383 // Verifies GetWindowAndTabByID works. | |
384 TEST_F(LauncherUpdaterTest, GetUpdaterByID) { | |
385 size_t initial_size = launcher_model_->items().size(); | |
386 TabContentsWrapper tab1(CreateTestTabContents()); | |
387 TabContentsWrapper tab2(CreateTestTabContents()); | |
388 TabContentsWrapper tab3(CreateTestTabContents()); | |
389 | |
390 // Create 3 states: | |
391 // . tabbed with an app tab and normal tab. | |
392 // . tabbed with a normal tab. | |
393 // . app. | |
394 State state1(profile(), launcher_delegate_.get(), std::string(), | |
395 LauncherUpdater::TYPE_TABBED); | |
396 state1.tab_strip.InsertTabContentsAt(0, &tab1, TabStripModel::ADD_NONE); | |
397 app_icon_loader_->SetAppID(&tab2, "1"); | |
398 state1.tab_strip.InsertTabContentsAt(0, &tab2, TabStripModel::ADD_NONE); | |
399 State state2(profile(), launcher_delegate_.get(), std::string(), | |
400 LauncherUpdater::TYPE_TABBED); | |
401 state2.tab_strip.InsertTabContentsAt(0, &tab3, TabStripModel::ADD_NONE); | |
402 State state3(profile(), launcher_delegate_.get(), std::string(), | |
403 LauncherUpdater::TYPE_APP); | |
404 ASSERT_EQ(initial_size + 4, launcher_model_->items().size()); | |
405 | |
406 // Tabbed item from first state. | |
407 ash::LauncherID id = launcher_model_->items()[initial_size].id; | |
408 LauncherUpdater* updater = GetUpdaterByID(id); | |
409 EXPECT_EQ(&(state1.updater), updater); | |
410 ASSERT_TRUE(updater); | |
411 EXPECT_TRUE(updater->GetTab(id) == NULL); | |
412 | |
413 // App item from first state. | |
414 id = launcher_model_->items()[initial_size + 1].id; | |
415 updater = GetUpdaterByID(id); | |
416 EXPECT_EQ(&(state1.updater), updater); | |
417 ASSERT_TRUE(updater); | |
418 EXPECT_TRUE(updater->GetTab(id) == &tab2); | |
419 | |
420 // Tabbed item from second state. | |
421 id = launcher_model_->items()[initial_size + 2].id; | |
422 updater = GetUpdaterByID(id); | |
423 EXPECT_EQ(&(state2.updater), updater); | |
424 ASSERT_TRUE(updater); | |
425 EXPECT_TRUE(updater->GetTab(id) == NULL); | |
426 | |
427 // App item. | |
428 id = launcher_model_->items()[initial_size + 3].id; | |
429 updater = GetUpdaterByID(id); | |
430 EXPECT_EQ(&(state3.updater), updater); | |
431 ASSERT_TRUE(updater); | |
432 EXPECT_TRUE(updater->GetTab(id) == NULL); | |
433 } | |
434 | |
435 // Various assertions around pinning. In particular verifies destroying a | |
436 // LauncherUpdater doesn't remove the entry for a pinned app. | |
437 TEST_F(LauncherUpdaterTest, Pin) { | |
438 size_t initial_size = launcher_model_->items().size(); | |
439 TabContentsWrapper tab1(CreateTestTabContents()); | |
440 TabContentsWrapper tab2(CreateTestTabContents()); | |
441 TabContentsWrapper tab3(CreateTestTabContents()); | |
442 | |
443 ash::LauncherID id; | |
444 { | |
445 State state1(profile(), launcher_delegate_.get(), std::string(), | |
446 LauncherUpdater::TYPE_TABBED); | |
447 app_icon_loader_->SetAppID(&tab1, "1"); | |
448 state1.tab_strip.InsertTabContentsAt(0, &tab1, TabStripModel::ADD_NONE); | |
449 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
450 id = launcher_model_->items()[initial_size].id; | |
451 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
452 // Shouldn't be pinned. | |
453 EXPECT_FALSE(launcher_delegate_->IsPinned(id)); | |
454 launcher_delegate_->Pin(id); | |
455 EXPECT_TRUE(launcher_delegate_->IsPinned(id)); | |
456 } | |
457 | |
458 // Should still have the item. | |
459 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
460 EXPECT_TRUE(launcher_delegate_->IsPinned(id)); | |
461 EXPECT_TRUE(GetUpdaterByID(id) == NULL); | |
462 | |
463 // Create another app tab, it shouldn't get the same id. | |
464 { | |
465 State state1(profile(), launcher_delegate_.get(), std::string(), | |
466 LauncherUpdater::TYPE_TABBED); | |
467 app_icon_loader_->SetAppID(&tab2, "2"); | |
468 state1.tab_strip.InsertTabContentsAt(0, &tab2, TabStripModel::ADD_NONE); | |
469 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
470 ash::LauncherID new_id = launcher_model_->items()[initial_size + 1].id; | |
471 EXPECT_NE(id, new_id); | |
472 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size + 1].type); | |
473 // Shouldn't be pinned. | |
474 EXPECT_FALSE(launcher_delegate_->IsPinned(new_id)); | |
475 // But existing one should still be pinned. | |
476 EXPECT_TRUE(launcher_delegate_->IsPinned(id)); | |
477 } | |
478 | |
479 // Add it back and make sure we don't get another entry. | |
480 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
481 { | |
482 State state1(profile(), launcher_delegate_.get(), std::string(), | |
483 LauncherUpdater::TYPE_TABBED); | |
484 app_icon_loader_->SetAppID(&tab1, "1"); | |
485 state1.tab_strip.InsertTabContentsAt(0, &tab1, TabStripModel::ADD_NONE); | |
486 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
487 ash::LauncherID new_id = launcher_model_->items()[initial_size].id; | |
488 EXPECT_EQ(id, new_id); | |
489 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
490 EXPECT_TRUE(launcher_delegate_->IsPinned(id)); | |
491 EXPECT_EQ(&(state1.updater), GetUpdaterByID(id)); | |
492 | |
493 // Add another tab. | |
494 state1.tab_strip.InsertTabContentsAt(0, &tab3, TabStripModel::ADD_NONE); | |
495 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
496 new_id = launcher_model_->items()[initial_size].id; | |
497 EXPECT_NE(id, new_id); | |
498 EXPECT_EQ(ash::TYPE_TABBED, launcher_model_->items()[initial_size].type); | |
499 EXPECT_EQ(&(state1.updater), GetUpdaterByID(new_id)); | |
500 } | |
501 | |
502 // Add it back and make sure we don't get another entry. | |
503 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
504 { | |
505 State state1(profile(), launcher_delegate_.get(), std::string(), | |
506 LauncherUpdater::TYPE_TABBED); | |
507 state1.tab_strip.InsertTabContentsAt(0, &tab3, TabStripModel::ADD_NONE); | |
508 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
509 ash::LauncherID new_id = launcher_model_->items()[initial_size + 1].id; | |
510 EXPECT_NE(id, new_id); | |
511 EXPECT_EQ(ash::TYPE_TABBED, | |
512 launcher_model_->items()[initial_size + 1].type); | |
513 EXPECT_TRUE(GetUpdaterByID(id) == NULL); | |
514 EXPECT_EQ(&(state1.updater), GetUpdaterByID(new_id)); | |
515 | |
516 // Add the app tab. | |
517 state1.tab_strip.InsertTabContentsAt(0, &tab1, TabStripModel::ADD_NONE); | |
518 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
519 new_id = launcher_model_->items()[initial_size].id; | |
520 EXPECT_EQ(id, new_id); | |
521 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
522 EXPECT_EQ(&(state1.updater), GetUpdaterByID(new_id)); | |
523 } | |
524 } | |
525 | |
526 // Verifies pinned apps are persisted and restored. | |
527 TEST_F(LauncherUpdaterTest, PersistPinned) { | |
528 size_t initial_size = launcher_model_->items().size(); | |
529 TabContentsWrapper tab1(CreateTestTabContents()); | |
530 | |
531 app_icon_loader_->SetAppID(&tab1, "1"); | |
532 app_icon_loader_->SetAppID(NULL, "2"); | |
533 { | |
534 State state1(profile(), launcher_delegate_.get(), std::string(), | |
535 LauncherUpdater::TYPE_TABBED); | |
536 state1.tab_strip.InsertTabContentsAt(0, &tab1, TabStripModel::ADD_NONE); | |
537 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
538 ash::LauncherID id = launcher_model_->items()[initial_size].id; | |
539 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
540 // Shouldn't be pinned. | |
541 EXPECT_FALSE(launcher_delegate_->IsPinned(id)); | |
542 launcher_delegate_->Pin(id); | |
543 EXPECT_TRUE(launcher_delegate_->IsPinned(id)); | |
544 | |
545 // Create an app window. | |
546 State state2(profile(), launcher_delegate_.get(), "2", | |
547 LauncherUpdater::TYPE_APP); | |
548 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
549 ash::LauncherID id2 = launcher_model_->items()[initial_size + 1].id; | |
550 EXPECT_NE(id, id2); | |
551 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size + 1].type); | |
552 launcher_delegate_->Pin(id2); | |
553 EXPECT_TRUE(launcher_delegate_->IsPinned(id2)); | |
554 } | |
555 | |
556 launcher_delegate_.reset(NULL); | |
557 ASSERT_EQ(initial_size, launcher_model_->items().size()); | |
558 | |
559 launcher_delegate_.reset( | |
560 new ChromeLauncherDelegate(profile(), launcher_model_.get())); | |
561 app_icon_loader_ = new AppIconLoaderImpl; | |
562 app_icon_loader_->SetAppID(&tab1, "1"); | |
563 app_icon_loader_->SetAppID(NULL, "2"); | |
564 ResetAppIconLoader(); | |
565 launcher_delegate_->Init(); | |
566 ASSERT_EQ(initial_size + 2, launcher_model_->items().size()); | |
567 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size].type); | |
568 ash::LauncherID id = launcher_model_->items()[initial_size].id; | |
569 EXPECT_EQ("1", GetAppID(id)); | |
570 EXPECT_EQ(ChromeLauncherDelegate::APP_TYPE_TAB, | |
571 launcher_delegate_->GetAppType(id)); | |
572 EXPECT_TRUE(launcher_delegate_->IsPinned(id)); | |
573 EXPECT_EQ(ash::TYPE_APP, launcher_model_->items()[initial_size + 1].type); | |
574 ash::LauncherID id2 = launcher_model_->items()[initial_size + 1].id; | |
575 EXPECT_EQ("2", GetAppID(id2)); | |
576 EXPECT_EQ(ChromeLauncherDelegate::APP_TYPE_WINDOW, | |
577 launcher_delegate_->GetAppType(id2)); | |
578 EXPECT_TRUE(launcher_delegate_->IsPinned(id2)); | |
579 | |
580 UnpinAppsWithID("1"); | |
581 ASSERT_EQ(initial_size + 1, launcher_model_->items().size()); | |
582 ash::LauncherID id3 = launcher_model_->items()[initial_size].id; | |
583 EXPECT_EQ(id2, id3); | |
584 } | |
OLD | NEW |