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