app_shell: Add version number in user agent
[chromium-blink-merge.git] / chrome / browser / ui / toolbar / back_forward_menu_model_unittest.cc
blob04ccc492200829a350a4974413fabb0ae14159e7
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.
5 #include "chrome/browser/ui/toolbar/back_forward_menu_model.h"
7 #include "base/path_service.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/favicon/favicon_service_factory.h"
13 #include "chrome/browser/history/history_service.h"
14 #include "chrome/browser/history/history_service_factory.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_tabstrip.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/url_constants.h"
20 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
21 #include "chrome/test/base/test_browser_window.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "content/public/browser/navigation_controller.h"
24 #include "content/public/browser/navigation_entry.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/test/web_contents_tester.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "third_party/skia/include/core/SkBitmap.h"
29 #include "ui/gfx/codec/png_codec.h"
31 using base::ASCIIToUTF16;
32 using content::WebContentsTester;
34 namespace {
36 // Creates a bitmap of the specified color.
37 SkBitmap CreateBitmap(SkColor color) {
38 SkBitmap bitmap;
39 bitmap.allocN32Pixels(16, 16);
40 bitmap.eraseColor(color);
41 return bitmap;
44 class FaviconDelegate : public ui::MenuModelDelegate {
45 public:
46 FaviconDelegate() : was_called_(false) {}
48 virtual void OnIconChanged(int model_index) OVERRIDE {
49 was_called_ = true;
50 base::MessageLoop::current()->Quit();
53 bool was_called() const { return was_called_; }
55 private:
56 bool was_called_;
58 DISALLOW_COPY_AND_ASSIGN(FaviconDelegate);
61 } // namespace
63 class BackFwdMenuModelTest : public ChromeRenderViewHostTestHarness {
64 public:
65 void ValidateModel(BackForwardMenuModel* model, int history_items,
66 int chapter_stops) {
67 int h = std::min(BackForwardMenuModel::kMaxHistoryItems, history_items);
68 int c = std::min(BackForwardMenuModel::kMaxChapterStops, chapter_stops);
69 EXPECT_EQ(h, model->GetHistoryItemCount());
70 EXPECT_EQ(c, model->GetChapterStopCount(h));
71 if (h > 0)
72 h += 2; // Separator and View History link.
73 if (c > 0)
74 ++c;
75 EXPECT_EQ(h + c, model->GetItemCount());
78 void LoadURLAndUpdateState(const char* url, const char* title) {
79 NavigateAndCommit(GURL(url));
80 controller().GetLastCommittedEntry()->SetTitle(base::UTF8ToUTF16(title));
83 // Navigate back or forward the given amount and commits the entry (which
84 // will be pending after we ask to navigate there).
85 void NavigateToOffset(int offset) {
86 controller().GoToOffset(offset);
87 WebContentsTester::For(web_contents())->CommitPendingNavigation();
90 // Same as NavigateToOffset but goes to an absolute index.
91 void NavigateToIndex(int index) {
92 controller().GoToIndex(index);
93 WebContentsTester::For(web_contents())->CommitPendingNavigation();
96 // Goes back/forward and commits the load.
97 void GoBack() {
98 controller().GoBack();
99 WebContentsTester::For(web_contents())->CommitPendingNavigation();
101 void GoForward() {
102 controller().GoForward();
103 WebContentsTester::For(web_contents())->CommitPendingNavigation();
107 TEST_F(BackFwdMenuModelTest, BasicCase) {
108 scoped_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
109 NULL, BackForwardMenuModel::BACKWARD_MENU));
110 back_model->set_test_web_contents(web_contents());
112 scoped_ptr<BackForwardMenuModel> forward_model(new BackForwardMenuModel(
113 NULL, BackForwardMenuModel::FORWARD_MENU));
114 forward_model->set_test_web_contents(web_contents());
116 EXPECT_EQ(0, back_model->GetItemCount());
117 EXPECT_EQ(0, forward_model->GetItemCount());
118 EXPECT_FALSE(back_model->ItemHasCommand(1));
120 // Seed the controller with a few URLs
121 LoadURLAndUpdateState("http://www.a.com/1", "A1");
122 LoadURLAndUpdateState("http://www.a.com/2", "A2");
123 LoadURLAndUpdateState("http://www.a.com/3", "A3");
124 LoadURLAndUpdateState("http://www.b.com/1", "B1");
125 LoadURLAndUpdateState("http://www.b.com/2", "B2");
126 LoadURLAndUpdateState("http://www.c.com/1", "C1");
127 LoadURLAndUpdateState("http://www.c.com/2", "C2");
128 LoadURLAndUpdateState("http://www.c.com/3", "C3");
130 // There're two more items here: a separator and a "Show Full History".
131 EXPECT_EQ(9, back_model->GetItemCount());
132 EXPECT_EQ(0, forward_model->GetItemCount());
133 EXPECT_EQ(ASCIIToUTF16("C2"), back_model->GetLabelAt(0));
134 EXPECT_EQ(ASCIIToUTF16("A1"), back_model->GetLabelAt(6));
135 EXPECT_EQ(back_model->GetShowFullHistoryLabel(),
136 back_model->GetLabelAt(8));
138 EXPECT_TRUE(back_model->ItemHasCommand(0));
139 EXPECT_TRUE(back_model->ItemHasCommand(6));
140 EXPECT_TRUE(back_model->IsSeparator(7));
141 EXPECT_TRUE(back_model->ItemHasCommand(8));
142 EXPECT_FALSE(back_model->ItemHasCommand(9));
143 EXPECT_FALSE(back_model->ItemHasCommand(9));
145 NavigateToOffset(-7);
147 EXPECT_EQ(0, back_model->GetItemCount());
148 EXPECT_EQ(9, forward_model->GetItemCount());
149 EXPECT_EQ(ASCIIToUTF16("A2"), forward_model->GetLabelAt(0));
150 EXPECT_EQ(ASCIIToUTF16("C3"), forward_model->GetLabelAt(6));
151 EXPECT_EQ(forward_model->GetShowFullHistoryLabel(),
152 forward_model->GetLabelAt(8));
154 EXPECT_TRUE(forward_model->ItemHasCommand(0));
155 EXPECT_TRUE(forward_model->ItemHasCommand(6));
156 EXPECT_TRUE(forward_model->IsSeparator(7));
157 EXPECT_TRUE(forward_model->ItemHasCommand(8));
158 EXPECT_FALSE(forward_model->ItemHasCommand(7));
159 EXPECT_FALSE(forward_model->ItemHasCommand(9));
161 NavigateToOffset(4);
163 EXPECT_EQ(6, back_model->GetItemCount());
164 EXPECT_EQ(5, forward_model->GetItemCount());
165 EXPECT_EQ(ASCIIToUTF16("B1"), back_model->GetLabelAt(0));
166 EXPECT_EQ(ASCIIToUTF16("A1"), back_model->GetLabelAt(3));
167 EXPECT_EQ(back_model->GetShowFullHistoryLabel(),
168 back_model->GetLabelAt(5));
169 EXPECT_EQ(ASCIIToUTF16("C1"), forward_model->GetLabelAt(0));
170 EXPECT_EQ(ASCIIToUTF16("C3"), forward_model->GetLabelAt(2));
171 EXPECT_EQ(forward_model->GetShowFullHistoryLabel(),
172 forward_model->GetLabelAt(4));
175 TEST_F(BackFwdMenuModelTest, MaxItemsTest) {
176 scoped_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
177 NULL, BackForwardMenuModel::BACKWARD_MENU));
178 back_model->set_test_web_contents(web_contents());
180 scoped_ptr<BackForwardMenuModel> forward_model(new BackForwardMenuModel(
181 NULL, BackForwardMenuModel::FORWARD_MENU));
182 forward_model->set_test_web_contents(web_contents());
184 // Seed the controller with 32 URLs
185 LoadURLAndUpdateState("http://www.a.com/1", "A1");
186 LoadURLAndUpdateState("http://www.a.com/2", "A2");
187 LoadURLAndUpdateState("http://www.a.com/3", "A3");
188 LoadURLAndUpdateState("http://www.b.com/1", "B1");
189 LoadURLAndUpdateState("http://www.b.com/2", "B2");
190 LoadURLAndUpdateState("http://www.b.com/3", "B3");
191 LoadURLAndUpdateState("http://www.c.com/1", "C1");
192 LoadURLAndUpdateState("http://www.c.com/2", "C2");
193 LoadURLAndUpdateState("http://www.c.com/3", "C3");
194 LoadURLAndUpdateState("http://www.d.com/1", "D1");
195 LoadURLAndUpdateState("http://www.d.com/2", "D2");
196 LoadURLAndUpdateState("http://www.d.com/3", "D3");
197 LoadURLAndUpdateState("http://www.e.com/1", "E1");
198 LoadURLAndUpdateState("http://www.e.com/2", "E2");
199 LoadURLAndUpdateState("http://www.e.com/3", "E3");
200 LoadURLAndUpdateState("http://www.f.com/1", "F1");
201 LoadURLAndUpdateState("http://www.f.com/2", "F2");
202 LoadURLAndUpdateState("http://www.f.com/3", "F3");
203 LoadURLAndUpdateState("http://www.g.com/1", "G1");
204 LoadURLAndUpdateState("http://www.g.com/2", "G2");
205 LoadURLAndUpdateState("http://www.g.com/3", "G3");
206 LoadURLAndUpdateState("http://www.h.com/1", "H1");
207 LoadURLAndUpdateState("http://www.h.com/2", "H2");
208 LoadURLAndUpdateState("http://www.h.com/3", "H3");
209 LoadURLAndUpdateState("http://www.i.com/1", "I1");
210 LoadURLAndUpdateState("http://www.i.com/2", "I2");
211 LoadURLAndUpdateState("http://www.i.com/3", "I3");
212 LoadURLAndUpdateState("http://www.j.com/1", "J1");
213 LoadURLAndUpdateState("http://www.j.com/2", "J2");
214 LoadURLAndUpdateState("http://www.j.com/3", "J3");
215 LoadURLAndUpdateState("http://www.k.com/1", "K1");
216 LoadURLAndUpdateState("http://www.k.com/2", "K2");
218 // Also there're two more for a separator and a "Show Full History".
219 int chapter_stop_offset = 6;
220 EXPECT_EQ(BackForwardMenuModel::kMaxHistoryItems + 2 + chapter_stop_offset,
221 back_model->GetItemCount());
222 EXPECT_EQ(0, forward_model->GetItemCount());
223 EXPECT_EQ(ASCIIToUTF16("K1"), back_model->GetLabelAt(0));
224 EXPECT_EQ(back_model->GetShowFullHistoryLabel(),
225 back_model->GetLabelAt(BackForwardMenuModel::kMaxHistoryItems + 1 +
226 chapter_stop_offset));
228 // Test for out of bounds (beyond Show Full History).
229 EXPECT_FALSE(back_model->ItemHasCommand(
230 BackForwardMenuModel::kMaxHistoryItems + chapter_stop_offset + 2));
232 EXPECT_TRUE(back_model->ItemHasCommand(
233 BackForwardMenuModel::kMaxHistoryItems - 1));
234 EXPECT_TRUE(back_model->IsSeparator(
235 BackForwardMenuModel::kMaxHistoryItems));
237 NavigateToIndex(0);
239 EXPECT_EQ(BackForwardMenuModel::kMaxHistoryItems + 2 + chapter_stop_offset,
240 forward_model->GetItemCount());
241 EXPECT_EQ(0, back_model->GetItemCount());
242 EXPECT_EQ(ASCIIToUTF16("A2"), forward_model->GetLabelAt(0));
243 EXPECT_EQ(forward_model->GetShowFullHistoryLabel(),
244 forward_model->GetLabelAt(BackForwardMenuModel::kMaxHistoryItems + 1 +
245 chapter_stop_offset));
247 // Out of bounds
248 EXPECT_FALSE(forward_model->ItemHasCommand(
249 BackForwardMenuModel::kMaxHistoryItems + 2 + chapter_stop_offset));
251 EXPECT_TRUE(forward_model->ItemHasCommand(
252 BackForwardMenuModel::kMaxHistoryItems - 1));
253 EXPECT_TRUE(forward_model->IsSeparator(
254 BackForwardMenuModel::kMaxHistoryItems));
257 TEST_F(BackFwdMenuModelTest, ChapterStops) {
258 scoped_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
259 NULL, BackForwardMenuModel::BACKWARD_MENU));
260 back_model->set_test_web_contents(web_contents());
262 scoped_ptr<BackForwardMenuModel> forward_model(new BackForwardMenuModel(
263 NULL, BackForwardMenuModel::FORWARD_MENU));
264 forward_model->set_test_web_contents(web_contents());
266 // Seed the controller with 32 URLs.
267 int i = 0;
268 LoadURLAndUpdateState("http://www.a.com/1", "A1");
269 ValidateModel(back_model.get(), i++, 0);
270 LoadURLAndUpdateState("http://www.a.com/2", "A2");
271 ValidateModel(back_model.get(), i++, 0);
272 LoadURLAndUpdateState("http://www.a.com/3", "A3");
273 ValidateModel(back_model.get(), i++, 0);
274 LoadURLAndUpdateState("http://www.b.com/1", "B1");
275 ValidateModel(back_model.get(), i++, 0);
276 LoadURLAndUpdateState("http://www.b.com/2", "B2");
277 ValidateModel(back_model.get(), i++, 0);
278 // i = 5
279 LoadURLAndUpdateState("http://www.b.com/3", "B3");
280 ValidateModel(back_model.get(), i++, 0);
281 LoadURLAndUpdateState("http://www.c.com/1", "C1");
282 ValidateModel(back_model.get(), i++, 0);
283 LoadURLAndUpdateState("http://www.c.com/2", "C2");
284 ValidateModel(back_model.get(), i++, 0);
285 LoadURLAndUpdateState("http://www.c.com/3", "C3");
286 ValidateModel(back_model.get(), i++, 0);
287 LoadURLAndUpdateState("http://www.d.com/1", "D1");
288 ValidateModel(back_model.get(), i++, 0);
289 // i = 10
290 LoadURLAndUpdateState("http://www.d.com/2", "D2");
291 ValidateModel(back_model.get(), i++, 0);
292 LoadURLAndUpdateState("http://www.d.com/3", "D3");
293 ValidateModel(back_model.get(), i++, 0);
294 LoadURLAndUpdateState("http://www.e.com/1", "E1");
295 ValidateModel(back_model.get(), i++, 0);
296 LoadURLAndUpdateState("http://www.e.com/2", "E2");
297 ValidateModel(back_model.get(), i++, 0);
298 LoadURLAndUpdateState("http://www.e.com/3", "E3");
299 ValidateModel(back_model.get(), i++, 0);
300 // i = 15
301 LoadURLAndUpdateState("http://www.f.com/1", "F1");
302 ValidateModel(back_model.get(), i++, 1);
303 LoadURLAndUpdateState("http://www.f.com/2", "F2");
304 ValidateModel(back_model.get(), i++, 1);
305 LoadURLAndUpdateState("http://www.f.com/3", "F3");
306 ValidateModel(back_model.get(), i++, 1);
307 LoadURLAndUpdateState("http://www.g.com/1", "G1");
308 ValidateModel(back_model.get(), i++, 2);
309 LoadURLAndUpdateState("http://www.g.com/2", "G2");
310 ValidateModel(back_model.get(), i++, 2);
311 // i = 20
312 LoadURLAndUpdateState("http://www.g.com/3", "G3");
313 ValidateModel(back_model.get(), i++, 2);
314 LoadURLAndUpdateState("http://www.h.com/1", "H1");
315 ValidateModel(back_model.get(), i++, 3);
316 LoadURLAndUpdateState("http://www.h.com/2", "H2");
317 ValidateModel(back_model.get(), i++, 3);
318 LoadURLAndUpdateState("http://www.h.com/3", "H3");
319 ValidateModel(back_model.get(), i++, 3);
320 LoadURLAndUpdateState("http://www.i.com/1", "I1");
321 ValidateModel(back_model.get(), i++, 4);
322 // i = 25
323 LoadURLAndUpdateState("http://www.i.com/2", "I2");
324 ValidateModel(back_model.get(), i++, 4);
325 LoadURLAndUpdateState("http://www.i.com/3", "I3");
326 ValidateModel(back_model.get(), i++, 4);
327 LoadURLAndUpdateState("http://www.j.com/1", "J1");
328 ValidateModel(back_model.get(), i++, 5);
329 LoadURLAndUpdateState("http://www.j.com/2", "J2");
330 ValidateModel(back_model.get(), i++, 5);
331 LoadURLAndUpdateState("http://www.j.com/3", "J3");
332 ValidateModel(back_model.get(), i++, 5);
333 // i = 30
334 LoadURLAndUpdateState("http://www.k.com/1", "K1");
335 ValidateModel(back_model.get(), i++, 6);
336 LoadURLAndUpdateState("http://www.k.com/2", "K2");
337 ValidateModel(back_model.get(), i++, 6);
338 // i = 32
339 LoadURLAndUpdateState("http://www.k.com/3", "K3");
340 ValidateModel(back_model.get(), i++, 6);
342 // A chapter stop is defined as the last page the user
343 // browsed to within the same domain.
345 // Check to see if the chapter stops have the right labels.
346 int index = BackForwardMenuModel::kMaxHistoryItems;
347 // Empty string indicates item is a separator.
348 EXPECT_EQ(base::string16(), back_model->GetLabelAt(index++));
349 EXPECT_EQ(ASCIIToUTF16("F3"), back_model->GetLabelAt(index++));
350 EXPECT_EQ(ASCIIToUTF16("E3"), back_model->GetLabelAt(index++));
351 EXPECT_EQ(ASCIIToUTF16("D3"), back_model->GetLabelAt(index++));
352 EXPECT_EQ(ASCIIToUTF16("C3"), back_model->GetLabelAt(index++));
353 // The menu should only show a maximum of 5 chapter stops.
354 EXPECT_EQ(ASCIIToUTF16("B3"), back_model->GetLabelAt(index));
355 // Empty string indicates item is a separator.
356 EXPECT_EQ(base::string16(), back_model->GetLabelAt(index + 1));
357 EXPECT_EQ(back_model->GetShowFullHistoryLabel(),
358 back_model->GetLabelAt(index + 2));
360 // If we go back two we should still see the same chapter stop at the end.
361 GoBack();
362 EXPECT_EQ(ASCIIToUTF16("B3"), back_model->GetLabelAt(index));
363 GoBack();
364 EXPECT_EQ(ASCIIToUTF16("B3"), back_model->GetLabelAt(index));
365 // But if we go back again, it should change.
366 GoBack();
367 EXPECT_EQ(ASCIIToUTF16("A3"), back_model->GetLabelAt(index));
368 GoBack();
369 EXPECT_EQ(ASCIIToUTF16("A3"), back_model->GetLabelAt(index));
370 GoBack();
371 EXPECT_EQ(ASCIIToUTF16("A3"), back_model->GetLabelAt(index));
372 GoBack();
373 // It is now a separator.
374 EXPECT_EQ(base::string16(), back_model->GetLabelAt(index));
375 // Undo our position change.
376 NavigateToOffset(6);
378 // Go back enough to make sure no chapter stops should appear.
379 NavigateToOffset(-BackForwardMenuModel::kMaxHistoryItems);
380 ValidateModel(forward_model.get(), BackForwardMenuModel::kMaxHistoryItems, 0);
381 // Go forward (still no chapter stop)
382 GoForward();
383 ValidateModel(forward_model.get(),
384 BackForwardMenuModel::kMaxHistoryItems - 1, 0);
385 // Go back two (one chapter stop should show up)
386 GoBack();
387 GoBack();
388 ValidateModel(forward_model.get(),
389 BackForwardMenuModel::kMaxHistoryItems, 1);
391 // Go to beginning.
392 NavigateToIndex(0);
394 // Check to see if the chapter stops have the right labels.
395 index = BackForwardMenuModel::kMaxHistoryItems;
396 // Empty string indicates item is a separator.
397 EXPECT_EQ(base::string16(), forward_model->GetLabelAt(index++));
398 EXPECT_EQ(ASCIIToUTF16("E3"), forward_model->GetLabelAt(index++));
399 EXPECT_EQ(ASCIIToUTF16("F3"), forward_model->GetLabelAt(index++));
400 EXPECT_EQ(ASCIIToUTF16("G3"), forward_model->GetLabelAt(index++));
401 EXPECT_EQ(ASCIIToUTF16("H3"), forward_model->GetLabelAt(index++));
402 // The menu should only show a maximum of 5 chapter stops.
403 EXPECT_EQ(ASCIIToUTF16("I3"), forward_model->GetLabelAt(index));
404 // Empty string indicates item is a separator.
405 EXPECT_EQ(base::string16(), forward_model->GetLabelAt(index + 1));
406 EXPECT_EQ(forward_model->GetShowFullHistoryLabel(),
407 forward_model->GetLabelAt(index + 2));
409 // If we advance one we should still see the same chapter stop at the end.
410 GoForward();
411 EXPECT_EQ(ASCIIToUTF16("I3"), forward_model->GetLabelAt(index));
412 // But if we advance one again, it should change.
413 GoForward();
414 EXPECT_EQ(ASCIIToUTF16("J3"), forward_model->GetLabelAt(index));
415 GoForward();
416 EXPECT_EQ(ASCIIToUTF16("J3"), forward_model->GetLabelAt(index));
417 GoForward();
418 EXPECT_EQ(ASCIIToUTF16("J3"), forward_model->GetLabelAt(index));
419 GoForward();
420 EXPECT_EQ(ASCIIToUTF16("K3"), forward_model->GetLabelAt(index));
422 // Now test the boundary cases by using the chapter stop function directly.
423 // Out of bounds, first too far right (incrementing), then too far left.
424 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(33, false));
425 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(-1, true));
426 // Test being at end and going right, then at beginning going left.
427 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(32, true));
428 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(0, false));
429 // Test success: beginning going right and end going left.
430 EXPECT_EQ(2, back_model->GetIndexOfNextChapterStop(0, true));
431 EXPECT_EQ(29, back_model->GetIndexOfNextChapterStop(32, false));
432 // Now see when the chapter stops begin to show up.
433 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(1, false));
434 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(2, false));
435 EXPECT_EQ(2, back_model->GetIndexOfNextChapterStop(3, false));
436 // Now see when the chapter stops end.
437 EXPECT_EQ(32, back_model->GetIndexOfNextChapterStop(30, true));
438 EXPECT_EQ(32, back_model->GetIndexOfNextChapterStop(31, true));
439 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(32, true));
441 // Bug found during review (two different sites, but first wasn't considered
442 // a chapter-stop).
443 // Go to A1;
444 NavigateToIndex(0);
445 LoadURLAndUpdateState("http://www.b.com/1", "B1");
446 EXPECT_EQ(0, back_model->GetIndexOfNextChapterStop(1, false));
447 EXPECT_EQ(1, back_model->GetIndexOfNextChapterStop(0, true));
449 // Now see if it counts 'www.x.com' and 'mail.x.com' as same domain, which
450 // it should.
451 // Go to A1.
452 NavigateToIndex(0);
453 LoadURLAndUpdateState("http://mail.a.com/2", "A2-mai");
454 LoadURLAndUpdateState("http://www.b.com/1", "B1");
455 LoadURLAndUpdateState("http://mail.b.com/2", "B2-mai");
456 LoadURLAndUpdateState("http://new.site.com", "new");
457 EXPECT_EQ(1, back_model->GetIndexOfNextChapterStop(0, true));
458 EXPECT_EQ(3, back_model->GetIndexOfNextChapterStop(1, true));
459 EXPECT_EQ(3, back_model->GetIndexOfNextChapterStop(2, true));
460 EXPECT_EQ(4, back_model->GetIndexOfNextChapterStop(3, true));
461 // And try backwards as well.
462 EXPECT_EQ(3, back_model->GetIndexOfNextChapterStop(4, false));
463 EXPECT_EQ(1, back_model->GetIndexOfNextChapterStop(3, false));
464 EXPECT_EQ(1, back_model->GetIndexOfNextChapterStop(2, false));
465 EXPECT_EQ(-1, back_model->GetIndexOfNextChapterStop(1, false));
468 TEST_F(BackFwdMenuModelTest, EscapeLabel) {
469 scoped_ptr<BackForwardMenuModel> back_model(new BackForwardMenuModel(
470 NULL, BackForwardMenuModel::BACKWARD_MENU));
471 back_model->set_test_web_contents(web_contents());
473 EXPECT_EQ(0, back_model->GetItemCount());
474 EXPECT_FALSE(back_model->ItemHasCommand(1));
476 LoadURLAndUpdateState("http://www.a.com/1", "A B");
477 LoadURLAndUpdateState("http://www.a.com/1", "A & B");
478 LoadURLAndUpdateState("http://www.a.com/2", "A && B");
479 LoadURLAndUpdateState("http://www.a.com/2", "A &&& B");
480 LoadURLAndUpdateState("http://www.a.com/3", "");
482 EXPECT_EQ(6, back_model->GetItemCount());
484 // On Mac ui::MenuModel::GetLabelAt should return unescaped strings.
485 #if defined(OS_MACOSX)
486 EXPECT_EQ(ASCIIToUTF16("A B"), back_model->GetLabelAt(3));
487 EXPECT_EQ(ASCIIToUTF16("A & B"), back_model->GetLabelAt(2));
488 EXPECT_EQ(ASCIIToUTF16("A && B"), back_model->GetLabelAt(1));
489 EXPECT_EQ(ASCIIToUTF16("A &&& B"), back_model->GetLabelAt(0));
490 #else
491 EXPECT_EQ(ASCIIToUTF16("A B"), back_model->GetLabelAt(3));
492 EXPECT_EQ(ASCIIToUTF16("A && B"), back_model->GetLabelAt(2));
493 EXPECT_EQ(ASCIIToUTF16("A &&&& B"), back_model->GetLabelAt(1));
494 EXPECT_EQ(ASCIIToUTF16("A &&&&&& B"), back_model->GetLabelAt(0));
495 #endif // defined(OS_MACOSX)
498 // Test asynchronous loading of favicon from history service.
499 TEST_F(BackFwdMenuModelTest, FaviconLoadTest) {
500 ASSERT_TRUE(profile()->CreateHistoryService(true, false));
501 profile()->CreateFaviconService();
502 Browser::CreateParams native_params(profile(), chrome::GetActiveDesktop());
503 scoped_ptr<Browser> browser(
504 chrome::CreateBrowserWithTestWindowForParams(&native_params));
505 FaviconDelegate favicon_delegate;
507 BackForwardMenuModel back_model(
508 browser.get(), BackForwardMenuModel::BACKWARD_MENU);
509 back_model.set_test_web_contents(controller().GetWebContents());
510 back_model.SetMenuModelDelegate(&favicon_delegate);
512 SkBitmap new_icon_bitmap(CreateBitmap(SK_ColorRED));
514 GURL url1 = GURL("http://www.a.com/1");
515 GURL url2 = GURL("http://www.a.com/2");
516 GURL url1_favicon("http://www.a.com/1/favicon.ico");
518 NavigateAndCommit(url1);
519 // Navigate to a new URL so that url1 will be in the BackForwardMenuModel.
520 NavigateAndCommit(url2);
522 // Set the desired favicon for url1.
523 HistoryServiceFactory::GetForProfile(
524 profile(), Profile::EXPLICIT_ACCESS)->AddPage(
525 url1, base::Time::Now(), history::SOURCE_BROWSED);
526 FaviconServiceFactory::GetForProfile(profile(), Profile::EXPLICIT_ACCESS)
527 ->SetFavicons(url1,
528 url1_favicon,
529 favicon_base::FAVICON,
530 gfx::Image::CreateFrom1xBitmap(new_icon_bitmap));
532 // Will return the current icon (default) but start an anync call
533 // to retrieve the favicon from the favicon service.
534 gfx::Image default_icon;
535 back_model.GetIconAt(0, &default_icon);
537 // Make the favicon service run GetFavIconForURL,
538 // FaviconDelegate.OnIconChanged will be called.
539 base::MessageLoop::current()->Run();
541 // Verify that the callback executed.
542 EXPECT_TRUE(favicon_delegate.was_called());
544 // Verify the bitmaps match.
545 gfx::Image valid_icon;
546 // This time we will get the new favicon returned.
547 back_model.GetIconAt(0, &valid_icon);
549 SkBitmap default_icon_bitmap = *default_icon.ToSkBitmap();
550 SkBitmap valid_icon_bitmap = *valid_icon.ToSkBitmap();
552 SkAutoLockPixels a(new_icon_bitmap);
553 SkAutoLockPixels b(valid_icon_bitmap);
554 SkAutoLockPixels c(default_icon_bitmap);
555 // Verify we did not get the default favicon.
556 EXPECT_NE(0, memcmp(default_icon_bitmap.getPixels(),
557 valid_icon_bitmap.getPixels(),
558 default_icon_bitmap.getSize()));
559 // Verify we did get the expected favicon.
560 EXPECT_EQ(0, memcmp(new_icon_bitmap.getPixels(),
561 valid_icon_bitmap.getPixels(),
562 new_icon_bitmap.getSize()));
564 // Make sure the browser deconstructor doesn't have problems.
565 browser->tab_strip_model()->CloseAllTabs();
566 // This is required to prevent the message loop from hanging.
567 profile()->DestroyHistoryService();