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