navigation_controller_impl_unittest.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_controller_impl.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/frame_host/navigator.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/site_instance_impl.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/frame_messages.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/page_state.h"
292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/common/url_constants.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/mock_render_process_host.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_notification_tracker.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/test/test_utils.h"
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/test/test_render_view_host.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/test_web_contents.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "skia/ext/platform_canvas.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates an image with a 1x1 SkBitmap of the specified |color|.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image CreateImage(SkColor color) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.allocPixels();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.eraseColor(color);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Image::CreateFrom1xBitmap(bitmap);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if images |a| and |b| have the same pixel data.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DoImagesMatch(const gfx::Image& a, const gfx::Image& b) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume that if the 1x bitmaps match, the images match.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap a_bitmap = a.AsBitmap();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap b_bitmap = b.AsBitmap();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (a_bitmap.width() != b_bitmap.width() ||
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      a_bitmap.height() != b_bitmap.height()) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels a_bitmap_lock(a_bitmap);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels b_bitmap_lock(b_bitmap);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return memcmp(a_bitmap.getPixels(),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                b_bitmap.getPixels(),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                a_bitmap.getSize()) == 0;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MockScreenshotManager : public content::NavigationEntryScreenshotManager {
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit MockScreenshotManager(content::NavigationControllerImpl* owner)
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : content::NavigationEntryScreenshotManager(owner),
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        encoding_screenshot_in_progress_(false) {
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MockScreenshotManager() {
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void TakeScreenshotFor(content::NavigationEntryImpl* entry) {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SkBitmap bitmap;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bitmap.allocPixels();
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bitmap.eraseRGB(0, 0, 0);
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    encoding_screenshot_in_progress_ = true;
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WaitUntilScreenshotIsReady();
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int GetScreenshotCount() {
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return content::NavigationEntryScreenshotManager::GetScreenshotCount();
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WaitUntilScreenshotIsReady() {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!encoding_screenshot_in_progress_)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_runner_ = new content::MessageLoopRunner;
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_runner_->Run();
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Overridden from content::NavigationEntryScreenshotManager:
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TakeScreenshotImpl(
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RenderViewHost* host,
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::NavigationEntryImpl* entry) OVERRIDE {
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnScreenshotSet(content::NavigationEntryImpl* entry) OVERRIDE {
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    encoding_screenshot_in_progress_ = false;
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NavigationEntryScreenshotManager::OnScreenshotSet(entry);
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (message_loop_runner_.get())
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message_loop_runner_->Quit();
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool encoding_screenshot_in_progress_;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockScreenshotManager);
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TimeSmoother tests ----------------------------------------------------------
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With no duplicates, GetSmoothedTime should be the identity
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, Basic) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 1; i < 1000; ++i) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time t = base::Time::FromInternalValue(i);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(t, smoother.GetSmoothedTime(t));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With a single duplicate and timestamps thereafter increasing by one
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// microsecond, the smoothed time should always be one behind.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, SingleDuplicate) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time t = base::Time::FromInternalValue(1);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(t, smoother.GetSmoothedTime(t));
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 1; i < 1000; ++i) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t = base::Time::FromInternalValue(i + 1);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    t = base::Time::FromInternalValue(i);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With k duplicates and timestamps thereafter increasing by one
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// microsecond, the smoothed time should always be k behind.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, ManyDuplicates) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kNumDuplicates = 100;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time t = base::Time::FromInternalValue(1);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 0; i < kNumDuplicates; ++i) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t = base::Time::FromInternalValue(i + 1);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 1; i < 1000; ++i) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t =
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Time::FromInternalValue(i + kNumDuplicates);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    t = base::Time::FromInternalValue(i);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the clock jumps far back enough after a run of duplicates, it
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should immediately jump to that value.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, ClockBackwardsJump) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kNumDuplicates = 100;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time t = base::Time::FromInternalValue(1000);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 0; i < kNumDuplicates; ++i) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t = base::Time::FromInternalValue(i + 1000);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t = base::Time::FromInternalValue(500);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(t, smoother.GetSmoothedTime(t));
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NavigationControllerTest ----------------------------------------------------
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class NavigationControllerTest
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : public RenderViewHostImplTestHarness,
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      public WebContentsObserver {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerTest() : navigation_entry_committed_counter_(0) {
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RenderViewHostImplTestHarness::SetUp();
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WebContents* web_contents = RenderViewHostImplTestHarness::web_contents();
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(web_contents);  // The WebContents should be created by now.
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WebContentsObserver::Observe(web_contents);
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // WebContentsObserver:
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void DidStartNavigationToPendingEntry(
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const GURL& url,
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NavigationController::ReloadType reload_type) OVERRIDE {
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    navigated_url_ = url;
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void NavigationEntryCommitted(
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const LoadCommittedDetails& load_details) OVERRIDE {
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_++;
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const GURL& navigated_url() const {
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return navigated_url_;
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller_impl() {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<NavigationControllerImpl&>(controller());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GURL navigated_url_;
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t navigation_entry_committed_counter_;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RegisterForAllNavNotifications(TestNotificationTracker* tracker,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NavigationController* controller) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tracker->ListenFor(NOTIFICATION_NAV_LIST_PRUNED,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     Source<NavigationController>(controller));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tracker->ListenFor(NOTIFICATION_NAV_ENTRY_CHANGED,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     Source<NavigationController>(controller));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SiteInstance* GetSiteInstanceFromEntry(NavigationEntry* entry) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NavigationEntryImpl::FromNavigationEntry(entry)->site_instance();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestWebContentsDelegate : public WebContentsDelegate {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestWebContentsDelegate() :
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      navigation_state_change_count_(0) {}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int navigation_state_change_count() {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return navigation_state_change_count_;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep track of whether the tab has notified us of a navigation state change.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NavigationStateChanged(const WebContents* source,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      unsigned changed_flags) OVERRIDE {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    navigation_state_change_count_++;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The number of times NavigationStateChanged has been called.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int navigation_state_change_count_;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Defaults) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetLastCommittedEntry());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), -1);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 0);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, GoToOffset) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumUrls = 5;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> urls(kNumUrls);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumUrls; ++i) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    urls[i] = GURL(base::StringPrintf("http://www.a.com/%d", i));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, urls[0]);
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(urls[0], controller.GetVisibleEntry()->GetVirtualURL());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(1));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 1; i <= 4; ++i) {
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(i, urls[i]);
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(urls[i], controller.GetVisibleEntry()->GetVirtualURL());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(controller.CanGoToOffset(-i));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(-(i + 1)));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(1));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have loaded 5 pages, and are currently at the last-loaded page.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int url_index = 4;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Tests {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_MIDDLE_PAGE = -2,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_FORWARDS = 1,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_BACKWARDS = -1,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_BEGINNING = -2,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_END = 4,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUM_TESTS = 5,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int test_offsets[NUM_TESTS] = {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_MIDDLE_PAGE,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_FORWARDS,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_BACKWARDS,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_BEGINNING,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_END
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int test = 0; test < NUM_TESTS; ++test) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int offset = test_offsets[test];
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.GoToOffset(offset);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_index += offset;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that the GoToOffset will land on the expected page.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(urls[url_index], controller.GetPendingEntry()->GetVirtualURL());
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(url_index, urls[url_index]);
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that we can go to any valid offset into the history.
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < urls.size(); ++j)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(controller.CanGoToOffset(j - url_index));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that we can't go beyond the beginning or end of the history.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(-(url_index + 1)));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(urls.size() - url_index));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creating a pending notification should not have issued any of the
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications we're listening for.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be pending.
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 0);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), -1);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetLastCommittedEntry());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(controller.GetPendingEntry());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntry(), controller.GetVisibleEntry());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), -1);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Neither the timestamp nor the status code should have been set yet.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry()->GetTimestamp().is_null());
362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntry()->GetHttpStatusCode());
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have gotten no notifications from the preceeding checks.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be committed.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 0);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should have been set.
3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry()->GetTimestamp().is_null());
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load another...
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be pending.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(controller.GetPendingEntry());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntry(), controller.GetVisibleEntry());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): maybe this should really be true?
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 0);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry()->GetTimestamp().is_null());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the beforeunload ack for the cross-site transition, and then the
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // commit.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendShouldCloseACK(true);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<TestRenderViewHost*>(
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents()->GetPendingRenderViewHost())->SendNavigate(1, url2);
409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be committed.
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 1);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry()->GetTimestamp().is_null());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time GetFixedTime(base::Time time) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return time;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLSameTime) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the clock to always return a timestamp of 1.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.SetGetTimestampCallbackForTest(
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GetFixedTime, base::Time::FromInternalValue(1)));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load another...
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the beforeunload ack for the cross-site transition, and then the
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // commit.
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendShouldCloseACK(true);
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The two loads should now be committed.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(controller.GetEntryCount(), 2);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamps should be distinct despite the clock returning the
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same value.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(0)->GetTimestamp().ToInternalValue());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(1)->GetTimestamp().ToInternalValue());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CheckNavigationEntryMatchLoadParams(
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NavigationController::LoadURLParams& load_params,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NavigationEntryImpl* entry) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.url, entry->GetURL());
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.referrer.url, entry->GetReferrer().url);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.referrer.policy, entry->GetReferrer().policy);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.transition_type, entry->GetTransitionType());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.extra_headers, entry->extra_headers());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.is_renderer_initiated, entry->is_renderer_initiated());
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.base_url_for_data_url, entry->GetBaseURLForDataURL());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!load_params.virtual_url_for_data_url.is_empty()) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(load_params.virtual_url_for_data_url, entry->GetVirtualURL());
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NavigationController::UA_OVERRIDE_INHERIT !=
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_params.override_user_agent) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool should_override = (NavigationController::UA_OVERRIDE_TRUE ==
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        load_params.override_user_agent);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(should_override, entry->GetIsOverridingUserAgent());
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.browser_initiated_post_data,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry->GetBrowserInitiatedPostData());
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.transferred_global_request_id,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry->transferred_global_request_id());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLWithParams) {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_params(GURL("http://foo"));
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.referrer =
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Referrer(GURL("http://referrer"), blink::WebReferrerPolicyDefault);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.transition_type = PAGE_TRANSITION_GENERATED;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.extra_headers = "content-type: text/plain";
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.load_type = NavigationController::LOAD_TYPE_DEFAULT;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.is_renderer_initiated = true;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
5102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  load_params.transferred_global_request_id = GlobalRequestID(2, 3);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_params);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry =
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetPendingEntry());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should not have been set yet.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetTimestamp().is_null());
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckNavigationEntryMatchLoadParams(load_params, entry);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLWithExtraParams_Data) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_params(
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("data:text/html,dataurl"));
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.load_type = NavigationController::LOAD_TYPE_DATA;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.base_url_for_data_url = GURL("http://foo");
5312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  load_params.virtual_url_for_data_url = GURL(kAboutBlankURL);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_params);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry =
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetPendingEntry());
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckNavigationEntryMatchLoadParams(load_params, entry);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLWithExtraParams_HttpPost) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_params(GURL("https://posturl"));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.transition_type = PAGE_TRANSITION_TYPED;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.load_type =
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationController::LOAD_TYPE_BROWSER_INITIATED_HTTP_POST;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char* raw_data =
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const unsigned char*>("d\n\0a2");
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int length = 5;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> post_data_vector(raw_data, raw_data+length);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> data =
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&post_data_vector);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.browser_initiated_post_data = data.get();
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_params);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry =
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetPendingEntry());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckNavigationEntryMatchLoadParams(load_params, entry);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when the same page is loaded again.  Should not create a
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// new session history entry. This is what happens when you press enter in the
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URL bar to reload: a pending entry is created and then it is discarded when
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the load commits (because WebCore didn't actually make a new entry).
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_SamePage) {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp();
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(timestamp.is_null());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not have produced a new session history entry.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should have been updated.
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Change this EXPECT_GE (and other similar ones) to
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // EXPECT_GT once we guarantee that timestamps are unique.
6094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GE(controller.GetVisibleEntry()->GetTimestamp(), timestamp);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Load the same page twice, once as a GET and once as a POST.
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// We should update the post state on the NavigationEntry.
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_SamePage_DifferentMethod) {
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestNotificationTracker notifications;
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo1");
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.page_id = 0;
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.url = url1;
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.transition = PAGE_TRANSITION_TYPED;
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.is_post = true;
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.post_id = 123;
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.page_state = PageState::CreateForTesting(url1, false, 0, 0);
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithParams(&params);
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The post data should be visible.
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationEntry* entry = controller.GetVisibleEntry();
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(entry);
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(entry->GetHasPostData());
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(entry->GetPostID(), 123);
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should not have produced a new session history entry.
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(controller.GetVisibleEntry(), entry);
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The post data should have been cleared due to the GET.
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(entry->GetHasPostData());
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(entry->GetPostID(), 0);
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests loading a URL but discarding it before the load commits.
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_Discarded) {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp();
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(timestamp.is_null());
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.DiscardNonCommittedEntries();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not have produced a new session history entry.
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp should not have changed.
6824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(timestamp, controller.GetVisibleEntry()->GetTimestamp());
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigations that come in unrequested. This happens when the user
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigates from the web page, and here we test that there is no pending entry.
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_NoPending) {
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make an existing committed entry.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://eh");
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do a new navigation without making a pending one.
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://see");
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(99, kNewURL);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
7104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigating to a new URL when there is a new pending navigation that is
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not the one that just loaded. This will happen if the user types in a URL to
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// somewhere slow, and then navigates the current page before the typed URL
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// commits.
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_NewPending) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make an existing committed entry.
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://eh");
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a pending entry to somewhere new.
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL2("http://bee");
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the beforeunload but before it commits, do a new navigation.
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_rvh()->SendShouldCloseACK(true);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://see");
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<TestRenderViewHost*>(
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      contents()->GetPendingRenderViewHost())->SendNavigate(3, kNewURL);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
7484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigating to a new URL when there is a pending back/forward
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation. This will happen if the user hits back, but before that commits,
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// they navigate somewhere new.
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_ExistingPending) {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make some history.
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://foo/eh");
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL2("http://foo/bee");
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kExistingURL2);
771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending back/forward navigation. The zeroth entry should be
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pending.
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntryIndex());
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before that commits, do a new navigation.
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://foo/see");
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, kNewURL);
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
7924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests navigating to a new URL when there is a pending back/forward
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// navigation to a cross-process, privileged URL. This will happen if the user
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// hits back, but before that commits, they navigate somewhere new.
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_PrivilegedPending) {
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestNotificationTracker notifications;
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First make some history, starting with a privileged URL.
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kExistingURL1("http://privileged");
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pretend it has bindings so we can tell if we incorrectly copy it.
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test_rvh()->AllowBindings(2);
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate cross-process to a second URL.
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kExistingURL2("http://foo/eh");
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test_rvh()->SendShouldCloseACK(true);
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestRenderViewHost* foo_rvh = static_cast<TestRenderViewHost*>(
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents()->GetPendingRenderViewHost());
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  foo_rvh->SendNavigate(1, kExistingURL2);
821868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now make a pending back/forward navigation to a privileged entry.
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The zeroth entry should be pending.
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoBack();
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  foo_rvh->SendShouldCloseACK(true);
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntryIndex());
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, NavigationEntryImpl::FromNavigationEntry(
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                controller.GetPendingEntry())->bindings());
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Before that commits, do a new navigation.
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kNewURL("http://foo/bee");
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadCommittedDetails details;
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  foo_rvh->SendNavigate(3, kNewURL);
8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // just made should be committed.
841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                controller.GetLastCommittedEntry())->bindings());
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigating to an existing URL when there is a pending new navigation.
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will happen if the user enters a URL, but before that commits, the
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current page fires history.back().
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_BackPreemptsPending) {
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make some history.
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://foo/eh");
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExistingURL1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL2("http://foo/bee");
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kExistingURL2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kExistingURL2);
870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending new navigation.
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://foo/see");
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before that commits, a back navigation from the renderer commits.
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the back navigation we
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kExistingURL1, controller.GetVisibleEntry()->GetURL());
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests an ignored navigation when there is a pending new navigation.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will happen if the user enters a URL, but before that commits, the
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current blank page reloads.  See http://crbug.com/77507.
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) {
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a WebContentsDelegate to listen for state changes.
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetDelegate());
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(delegate.get());
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Without any navigations, the renderer starts at about:blank.
9072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const GURL kExistingURL(kAboutBlankURL);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending new navigation.
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://eh");
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->navigation_state_change_count());
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before that commits, a document.write and location.reload can cause the
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // renderer to send a FrameNavigate with page_id -1.
9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(-1, kExistingURL);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should clear the pending entry and notify of a navigation state
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change, so that we do not keep displaying kNewURL.
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate->navigation_state_change_count());
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(NULL);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the pending entry state is correct after an abort.
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We do not want to clear the pending entry, so that the user doesn't
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// lose a typed URL.  (See http://crbug.com/9682.)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) {
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a WebContentsDelegate to listen for state changes.
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetDelegate());
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(delegate.get());
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Start with a pending new navigation.
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://eh");
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kNewURL, Referrer(), PAGE_TRANSITION_TYPED, std::string());
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->navigation_state_change_count());
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It may abort before committing, if it's a download or due to a stop or
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a new navigation from the user.
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidFailProvisionalLoadWithError_Params params;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.frame_id = 1;
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_main_frame = true;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.error_code = net::ERR_ABORTED;
962a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  params.error_description = base::string16();
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = kNewURL;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.showing_repost_interstitial = false;
9655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->OnMessageReceived(
9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FrameHostMsg_DidFailProvisionalLoadWithError(0,  // routing_id
9675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                   params));
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should not clear the pending entry or notify of a navigation state
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change, so that we keep displaying kNewURL (until the user clears it).
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->navigation_state_change_count());
975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationEntry* pending_entry = controller.GetPendingEntry();
976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Ensure that a reload keeps the same pending entry.
978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.Reload(true);
979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
980868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(pending_entry, controller.GetPendingEntry());
982868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(NULL);
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the pending URL is not visible during a renderer-initiated
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// redirect and abort.  See http://crbug.com/83031.
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) {
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // First make an existing committed entry.
995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kExistingURL("http://foo/eh");
996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURL(kExistingURL, content::Referrer(),
997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                     content::PAGE_TRANSITION_TYPED, std::string());
9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL);
999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
1001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a WebContentsDelegate to listen for state changes.
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetDelegate());
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(delegate.get());
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending new navigation, initiated by the renderer.
1008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kNewURL("http://foo/bee");
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(kNewURL);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.transition_type = PAGE_TRANSITION_TYPED;
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
1016868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
1017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, delegate->navigation_state_change_count());
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The visible entry should be the last committed URL, not the pending one.
1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL());
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the navigation redirects.
1023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kRedirectURL("http://foo/see");
10245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->OnMessageReceived(
10255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FrameHostMsg_DidRedirectProvisionalLoad(0,  // routing_id
10265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              -1,  // pending page_id
10275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              kNewURL,  // old url
10285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              kRedirectURL));  // new url
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't want to change the NavigationEntry's url, in case it cancels.
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prevents regression of http://crbug.com/77786.
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetPendingEntry()->GetURL());
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It may abort before committing, if it's a download or due to a stop or
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a new navigation from the user.
10365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidFailProvisionalLoadWithError_Params params;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.frame_id = 1;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_main_frame = true;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.error_code = net::ERR_ABORTED;
1040a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  params.error_description = base::string16();
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = kRedirectURL;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.showing_repost_interstitial = false;
10435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->OnMessageReceived(
10445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FrameHostMsg_DidFailProvisionalLoadWithError(0,  // routing_id
10455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                   params));
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Because the pending entry is renderer initiated and not visible, we
104858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // clear it when it fails.
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
105058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
1051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
1052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, delegate->navigation_state_change_count());
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The visible entry should be the last committed URL, not the pending one,
1055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // so that no spoof is possible.
1056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL());
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(NULL);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that NavigationEntries track which bindings their RenderViewHost had
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// at the time they committed.  http://crbug.com/173672.
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_WithBindings) {
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestNotificationTracker notifications;
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url1("http://foo1");
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://foo2");
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to a first, unprivileged URL.
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::kInvalidBindings,
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                controller.GetPendingEntry())->bindings());
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Commit.
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestRenderViewHost* orig_rvh = static_cast<TestRenderViewHost*>(test_rvh());
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  orig_rvh->SendNavigate(0, url1);
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Manually increase the number of active views in the SiteInstance
10867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // that orig_rvh belongs to, to prevent it from being destroyed when
10877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // it gets swapped out, so that we can reuse orig_rvh when the
10887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // controller goes back.
10897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static_cast<SiteInstanceImpl*>(orig_rvh->GetSiteInstance())->
10907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
10917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to a second URL, simulate the beforeunload ack for the cross-site
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // transition, and set bindings on the pending RenderViewHost to simulate a
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // privileged url.
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  orig_rvh->SendShouldCloseACK(true);
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->GetPendingRenderViewHost()->AllowBindings(1);
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static_cast<TestRenderViewHost*>(
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      contents()->GetPendingRenderViewHost())->SendNavigate(1, url2);
11005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  orig_rvh->OnSwappedOut(false);
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second load should be committed, and bindings should be remembered.
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, NavigationEntryImpl::FromNavigationEntry(
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Going back, the first entry should still appear unprivileged.
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoBack();
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  orig_rvh->SendNavigate(0, url1);
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Reload) {
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
11265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
11294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
11305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title"));
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.Reload(true);
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp();
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(timestamp.is_null());
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The reload is pending.
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the title has been cleared (will be redrawn just after reload).
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoids a stale cached title when the new page being reloaded has no title.
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See http://crbug.com/96041.
11484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty());
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the reload is committed.
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should have been updated.
11644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
11654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GE(controller.GetVisibleEntry()->GetTimestamp(), timestamp);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when a reload navigation produces a new page.
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Reload_GeneratesNewPage) {
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
11785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.Reload(true);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the reload is committed.
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This test ensures that when a guest renderer reloads, the reload goes through
12005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// without ending up in the "we have a wrong process for the URL" branch in
12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// NavigationControllerImpl::ReloadInternal.
12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, ReloadWithGuest) {
12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo1");
12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
12075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
12095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make the entry believe its RenderProcessHost is a guest.
12115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationEntryImpl* entry1 =
12125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetVisibleEntry());
12135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reinterpret_cast<MockRenderProcessHost*>(
12145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      entry1->site_instance()->GetProcess())->SetIsGuest(true);
12155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // And reload.
12175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.Reload(true);
12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The reload is pending. Check that the NavigationEntry didn't get replaced
12205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // because of having the wrong process.
12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
12225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
12235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
12245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationEntryImpl* entry2 =
12265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry());
12275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(entry1, entry2);
12285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)  // http://crbug.com/157428
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) {
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL original_url("http://foo1");
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL final_url("http://foo2");
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load up the original URL, but get redirected.
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      original_url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithOriginalRequestURL(
12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      0, final_url, original_url);
1245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NavigationEntry should save both the original URL and the final
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // redirected URL.
12504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(
12514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      original_url, controller.GetVisibleEntry()->GetOriginalRequestURL());
12524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(final_url, controller.GetVisibleEntry()->GetURL());
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reload using the original URL.
12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title"));
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.ReloadOriginalRequestURL(false);
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The reload is pending.  The request should point to the original URL.
12604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(original_url, navigated_url());
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the title has been cleared (will be redrawn just after reload).
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoids a stale cached title when the new page being reloaded has no title.
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See http://crbug.com/96041.
12724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty());
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send that the navigation has proceeded; say it got redirected again.
12755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, final_url);
1276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the reload is committed.
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(OS_ANDROID)
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Test that certain non-persisted NavigationEntryImpl values get reset after
12921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// commit.
12931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(NavigationControllerTest, ResetEntryValuesAfterCommit) {
12941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
12951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const GURL url1("http://foo1");
12961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
12971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
12981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Set up some sample values.
12991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const unsigned char* raw_data =
13001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      reinterpret_cast<const unsigned char*>("post\n\n\0data");
13011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int length = 11;
13021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<unsigned char> post_data_vector(raw_data, raw_data+length);
13031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> post_data =
13041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&post_data_vector);
13051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GlobalRequestID transfer_id(3, 4);
13061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<GURL> redirects;
13071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  redirects.push_back(GURL("http://foo2"));
13081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Set non-persisted values on the pending entry.
13101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NavigationEntryImpl* pending_entry =
13111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry());
13121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->SetBrowserInitiatedPostData(post_data.get());
13131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_is_renderer_initiated(true);
13141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_transferred_global_request_id(transfer_id);
13151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_should_replace_entry(true);
13161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_redirect_chain(redirects);
13171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_should_clear_history_list(true);
13181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(post_data.get(), pending_entry->GetBrowserInitiatedPostData());
13191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(pending_entry->is_renderer_initiated());
13201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(transfer_id, pending_entry->transferred_global_request_id());
13211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(pending_entry->should_replace_entry());
13221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(1U, pending_entry->redirect_chain().size());
13231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(pending_entry->should_clear_history_list());
13241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
13261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Certain values that are only used for pending entries get reset after
13281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // commit.
13291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NavigationEntryImpl* committed_entry =
13301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
13311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          controller.GetLastCommittedEntry());
13321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->GetBrowserInitiatedPostData());
13331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->is_renderer_initiated());
13341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(GlobalRequestID(-1, -1),
13351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            committed_entry->transferred_global_request_id());
13361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->should_replace_entry());
13371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(0U, committed_entry->redirect_chain().size());
13381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->should_clear_history_list());
13391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
13401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when we navigate back successfully
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back) {
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
13485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
13535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should now have a pending navigation to go back.
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-1));
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(1));
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(2));  // Cannot go foward 2 steps.
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 1 should be on or after that of entry 0.
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(),
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(0)->GetTimestamp());
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
1378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The back navigation completed successfully.
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-1));
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(1));
13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(2));  // Cannot go foward 2 steps.
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 0 should be on or after that of entry 1
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (since we went back to it).
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(),
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(1)->GetTimestamp());
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when a back navigation produces a new page.
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back_GeneratesNewPage) {
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
14115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
14165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should now have a pending navigation to go back.
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
1433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The back navigation resulted in a completely new navigation.
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): perhaps this behavior will be confusing to users?
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 3);
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 2);
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Receives a back message when there is a new pending navigation entry.
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back_NewPending) {
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://foo1");
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://foo2");
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl3("http://foo3");
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigate two places so we have some back history.
14585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
1459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // controller.LoadURL(kUrl2, PAGE_TRANSITION_TYPED);
14635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
1464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start a new pending navigation and go back before it commits.
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(kUrl3, Referrer(), PAGE_TRANSITION_TYPED, std::string());
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl3, controller.GetPendingEntry()->GetURL());
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The pending navigation should now be the "back" item and the new one
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be gone.
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntryIndex());
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl1, controller.GetPendingEntry()->GetURL());
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Receives a back message when there is a different renavigation already
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pending.
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back_OtherBackPending) {
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://foo/1");
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://foo/2");
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl3("http://foo/3");
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigate three places so we have some back history.
14885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
14895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
14905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, kUrl3);
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // With nothing pending, say we get a navigation to the second entry.
14935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We know all the entries have the same site instance, so we can just grab
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a random one for looking up other entries.
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* site_instance =
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetLastCommittedEntry())->site_instance();
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // That second URL should be the last committed and it should have gotten the
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new title.
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl2, controller.GetEntryWithPageID(site_instance, 1)->GetURL());
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go forward to the last item again and say it was committed.
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
15095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, kUrl3);
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start going back one to the second page. It will be pending.
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetPendingEntryIndex());
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not synthesize a totally new back event to the first page. This will not
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // match the pending one.
15185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The committed navigation should clear the pending entry.
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But the navigated entry should be the last committed.
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl1, controller.GetLastCommittedEntry()->GetURL());
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when we navigate forward successfully.
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Forward) {
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
15465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should now have a pending navigation to go forward.
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 1);
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(-1));
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-2));  // Cannot go back 2 steps.
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(1));
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 0 should be on or after that of entry 1
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (since we went back to it).
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(),
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(1)->GetTimestamp());
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The forward navigation completed successfully.
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(-1));
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-2));  // Cannot go back 2 steps.
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(1));
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 1 should be on or after that of entry 0
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (since we went forward to it).
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(),
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(0)->GetTimestamp());
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when a forward navigation produces a new page.
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Forward_GeneratesNewPage) {
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
16105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should now have a pending navigation to go forward.
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 1);
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
1627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
1629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(notifications.Check1AndReset(NOTIFICATION_NAV_LIST_PRUNED));
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Two consequent navigation for the same URL entered in should be considered
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as SAME_PAGE navigation even when we are redirected to some other page.
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Redirect) {
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");  // Redirection target
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
16545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
1655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second request
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
16634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_SERVER_REDIRECT;
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo1"));
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo2"));
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
167490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
16795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.type == NAVIGATION_TYPE_SAME_PAGE);
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
16894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to Redirect above, but the first URL is requested by POST,
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the second URL is requested by GET. NavigationEntry::has_post_data_
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// must be cleared. http://crbug.com/21245
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, PostThenRedirect) {
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");  // Redirection target
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request as POST
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
17084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.GetVisibleEntry()->SetHasPostData(true);
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
17115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
1712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second request
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_SERVER_REDIRECT;
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo1"));
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo2"));
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
173190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
17365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.type == NAVIGATION_TYPE_SAME_PAGE);
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
17464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
17474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry()->GetHasPostData());
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A redirect right off the bat should be a NEW_PAGE.
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ImmediateRedirect) {
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");  // Redirection target
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_SERVER_REDIRECT;
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo1"));
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo2"));
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
177890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
17835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.type == NAVIGATION_TYPE_NEW_PAGE);
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
17934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigation via link click within a subframe. A new navigation entry
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be created.
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, NewSubframe) {
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
18075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
18125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME;
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
181990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
18225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, details.previous_url);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.is_in_page);
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.is_main_frame);
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The new entry should be appended.
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // New entry should refer to the new page, but the old URL (entries only
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reflect the toplevel URL).
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, details.entry->GetURL());
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(params.page_id, details.entry->GetPageID());
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some pages create a popup, then write an iframe into it. This causes a
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subframe navigation without having any committed entry. Such navigations
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// just get thrown on the ground, but we shouldn't crash.
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, SubframeOnEmptyPage) {
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigation controller currently has no entries.
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://foo2");
18485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url;
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
185590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
18585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(test_rvh(), params, &details));
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Auto subframes are ones the page loads automatically like ads. They should
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not create new navigation entries.
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, AutoSubframe) {
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
18705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
18755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
188290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigating should do nothing.
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
18865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(test_rvh(), params, &details));
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should still be only one entry.
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigation and then going back to a subframe navigation.
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, BackSubframe) {
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Main page.
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
19015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First manual subframe navigation.
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
19075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_MANUAL_SUBFRAME;
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
191490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should generate a new entry.
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
19185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second manual subframe navigation should also make a new entry.
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 2;
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url3;
19275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back one.
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
19375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back one more.
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url1;
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
19495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
1950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LinkClick) {
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not have produced a new session history entry.
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, InPage) {
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Main page.
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo");
19915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure main page navigation to same url respects the was_within_same_page
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hint provided in the params.
19975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params self_params;
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.page_id = 0;
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.url = url1;
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.transition = PAGE_TRANSITION_LINK;
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.should_update_history = false;
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.gesture = NavigationGestureUser;
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.is_post = false;
200490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  self_params.page_state = PageState::CreateFromURL(url1);
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.was_within_same_page = true;
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
20085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), self_params,
20095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
2010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.did_replace_entry);
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fragment navigation to a new page_id.
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo#a");
20185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_LINK;
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
202590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
2026bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  params.was_within_same_page = true;
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should generate a new entry.
20295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
2030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.did_replace_entry);
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back one.
20375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params back_params(params);
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  back_params.url = url1;
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  back_params.page_id = 0;
20415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), back_params,
20425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
2043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
2045bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(details.is_in_page);
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
20484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(back_params.url, controller.GetVisibleEntry()->GetURL());
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go forward
20515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params forward_params(params);
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  forward_params.url = url2;
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  forward_params.page_id = 1;
20555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), forward_params,
20565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
2057868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(forward_params.url,
20634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            controller.GetVisibleEntry()->GetURL());
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go back and forward again. This is to work around a bug where we would
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compare the incoming URL with the last committed entry rather than the
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one identified by an existing page ID. This would result in the second URL
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // losing the reference fragment when you navigate away from it and then back.
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
20705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), back_params,
20715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
20735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), forward_params,
20745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(forward_params.url,
20764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            controller.GetVisibleEntry()->GetURL());
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, navigate to an unrelated URL to make sure in_page is not sticky.
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://bar");
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 2;
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url3;
2082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
2084868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.is_in_page);
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, InPage_Replace) {
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Main page.
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo");
20985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
2099868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigation.
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo#a");
21045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;  // Same page_id
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_LINK;
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
211190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should NOT generate a new entry, nor prune the list.
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
21155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
2116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.did_replace_entry);
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests for http://crbug.com/40395
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulates this:
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   <script>
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     window.location.replace("#a");
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     window.location='http://foo3/';
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   </script>
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) {
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an initial page.
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo/");
21375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(0, url);
2138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a new page.
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo2/");
21455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(1, url);
2146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate within the page.
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo2/#a");
21535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FrameHostMsg_DidCommitProvisionalLoad_Params params;
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.page_id = 1;  // Same page_id
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.url = url;
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.transition = PAGE_TRANSITION_LINK;
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.redirects.push_back(url);
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.should_update_history = true;
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.gesture = NavigationGestureUnknown;
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.is_post = false;
216190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    params.page_state = PageState::CreateFromURL(url);
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This should NOT generate a new entry, nor prune the list.
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadCommittedDetails details;
21655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
2166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(details.is_in_page);
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(details.did_replace_entry);
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, controller.GetEntryCount());
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Perform a client redirect to a new page.
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo3/");
21765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FrameHostMsg_DidCommitProvisionalLoad_Params params;
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.page_id = 2;  // New page_id
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.url = url;
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.transition = PAGE_TRANSITION_CLIENT_REDIRECT;
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.redirects.push_back(GURL("http://foo2/#a"));
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.redirects.push_back(url);
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.should_update_history = true;
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.gesture = NavigationGestureUnknown;
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.is_post = false;
218590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    params.page_state = PageState::CreateFromURL(url);
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This SHOULD generate a new entry.
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadCommittedDetails details;
21895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(controller.RendererDidNavigate(test_rvh(), params, &details));
2190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(details.is_in_page);
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3, controller.GetEntryCount());
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that BACK brings us back to http://foo2/.
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo2/");
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.GoBack();
22005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(1, url);
2201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
22034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NotificationObserver implementation used in verifying we've received the
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTIFICATION_NAV_LIST_PRUNED method.
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrunedListener : public NotificationObserver {
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PrunedListener(NavigationControllerImpl* controller)
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : notification_count_(0) {
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(this, NOTIFICATION_NAV_LIST_PRUNED,
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   Source<NavigationController>(controller));
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const NotificationSource& source,
22192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const NotificationDetails& details) OVERRIDE {
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == NOTIFICATION_NAV_LIST_PRUNED) {
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notification_count_++;
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      details_ = *(Details<PrunedDetails>(details).ptr());
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of times NAV_LIST_PRUNED has been observed.
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int notification_count_;
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Details from the last NAV_LIST_PRUNED.
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrunedDetails details_;
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationRegistrar registrar_;
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PrunedListener);
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we limit the number of navigation entries created correctly.
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) {
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t original_count = NavigationControllerImpl::max_entry_count();
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxEntryCount = 5;
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount);
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int url_index;
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load up to the max count, all entries should be there.
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (url_index = 0; url_index < kMaxEntryCount; url_index++) {
22492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GURL url(base::StringPrintf("http://www.a.com/%d", url_index));
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.LoadURL(
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
22525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(url_index, url);
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Created a PrunedListener to observe prune notifications.
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrunedListener listener(&controller);
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate some more.
22612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url(base::StringPrintf("http://www.a.com/%d", url_index));
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
22645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(url_index, url);
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_index++;
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have got a pruned navigation.
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.notification_count_);
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(listener.details_.from_front);
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.details_.count);
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We expect http://www.a.com/0 to be gone.
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(),
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GURL("http:////www.a.com/1"));
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More navigations.
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
22792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    url = GURL(base::StringPrintf("http:////www.a.com/%d", url_index));
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.LoadURL(
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, Referrer(), PAGE_TRANSITION_TYPED, std::string());
22825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(url_index, url);
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_index++;
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(),
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GURL("http:////www.a.com/4"));
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(original_count);
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can do a restore and navigate to the restored entries and
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything is updated properly. This can be tricky since there is no
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SiteInstance for the entries created initially.
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, RestoreNavigate) {
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a NavigationController with a restored set of tabs.
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://foo");
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<NavigationEntry*> entries;
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry(
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_RELOAD, false, std::string(),
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_context());
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->SetPageID(0);
23035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry->SetTitle(base::ASCIIToUTF16("Title"));
230490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  entry->SetPageState(PageState::CreateFromEncodedData("state"));
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Time timestamp = base::Time::Now();
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->SetTimestamp(timestamp);
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries.push_back(entry);
23082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>(
23092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContents::Create(WebContents::CreateParams(browser_context()))));
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& our_controller = our_contents->GetController();
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.Restore(
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &entries);
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, entries.size());
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before navigating to the restored entry, it should have a restore_type
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and no SiteInstance.
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, our_controller.GetEntryCount());
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY,
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(NavigationEntryImpl::FromNavigationEntry(
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After navigating, we should have one entry, and it should be "pending".
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should now have a SiteInstance and no restore_type.
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.GoToIndex(0);
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(our_controller.GetEntryAtIndex(0),
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            our_controller.GetPendingEntry());
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetEntryAtIndex(0)->GetPageID());
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                (our_controller.GetEntryAtIndex(0))->restore_type());
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NavigationEntryImpl::FromNavigationEntry(
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp should remain the same before the navigation finishes.
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(timestamp, our_controller.GetEntryAtIndex(0)->GetTimestamp());
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Say we navigated to that entry.
23435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url;
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_LINK;
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
235090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
23525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  our_controller.RendererDidNavigate(our_contents->GetRenderViewHost(), params,
23535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     &details);
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be no longer any pending entry and one committed one. This
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // means that we were able to locate the entry, assign its site instance, and
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // commit it properly.
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetLastCommittedEntryIndex());
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(our_controller.GetPendingEntry());
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url,
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetLastCommittedEntry())->site_instance()->
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    GetSiteURL());
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp should have been updated.
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(our_controller.GetEntryAtIndex(0)->GetTimestamp(), timestamp);
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can still navigate to a restored entry after a different
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation fails and clears the pending entry.  http://crbug.com/90085
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) {
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a NavigationController with a restored set of tabs.
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://foo");
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<NavigationEntry*> entries;
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry(
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), PAGE_TRANSITION_RELOAD, false, std::string(),
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_context());
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->SetPageID(0);
23835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry->SetTitle(base::ASCIIToUTF16("Title"));
238490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  entry->SetPageState(PageState::CreateFromEncodedData("state"));
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries.push_back(entry);
23862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>(
23872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContents::Create(WebContents::CreateParams(browser_context()))));
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& our_controller = our_contents->GetController();
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.Restore(
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, entries.size());
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before navigating to the restored entry, it should have a restore_type
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and no SiteInstance.
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY,
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(NavigationEntryImpl::FromNavigationEntry(
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After navigating, we should have one entry, and it should be "pending".
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should now have a SiteInstance and no restore_type.
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.GoToIndex(0);
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(our_controller.GetEntryAtIndex(0),
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            our_controller.GetPendingEntry());
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetEntryAtIndex(0)->GetPageID());
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NavigationEntryImpl::FromNavigationEntry(
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This pending navigation may have caused a different navigation to fail,
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which causes the pending entry to be cleared.
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestRenderViewHost* rvh =
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestRenderViewHost*>(our_contents->GetRenderViewHost());
24185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidFailProvisionalLoadWithError_Params fail_load_params;
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.frame_id = 1;
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.is_main_frame = true;
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.error_code = net::ERR_ABORTED;
2422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  fail_load_params.error_description = base::string16();
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.url = url;
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.showing_repost_interstitial = false;
24255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->OnMessageReceived(
24265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FrameHostMsg_DidFailProvisionalLoadWithError(0,  // routing_id
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  fail_load_params));
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the pending restored entry commits.
24305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url;
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_LINK;
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
243790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
24395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  our_controller.RendererDidNavigate(rvh, params, &details);
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be no pending entry and one committed one.
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetLastCommittedEntryIndex());
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(our_controller.GetPendingEntry());
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url,
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetLastCommittedEntry())->site_instance()->
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    GetSiteURL());
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that the page type and stuff is correct after an interstitial.
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Interstitial) {
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigate somewhere normal.
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo");
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
24615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now navigate somewhere with an interstitial.
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://bar");
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_page_type(PAGE_TYPE_INTERSTITIAL);
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the interstitial will be displayed and the load will still
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be pending. If the user continues, the load will commit.
24725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The page should be a normal page again.
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PAGE_TYPE_NORMAL,
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetLastCommittedEntry()->GetPageType());
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, RemoveEntry) {
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url4("http://foo/4");
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url5("http://foo/5");
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL pending_url("http://foo/pending");
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL default_url("http://foo/default");
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
24925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
24955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url3, Referrer(), PAGE_TRANSITION_TYPED, std::string());
24985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url4, Referrer(), PAGE_TRANSITION_TYPED, std::string());
25015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url4);
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url5, Referrer(), PAGE_TRANSITION_TYPED, std::string());
25045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(4, url5);
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to remove the last entry.  Will fail because it is the current entry.
2507a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, controller.GetEntryCount());
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2511a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Go back, but don't commit yet. Check that we can't delete the current
2512a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // and pending entries.
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
2514a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
2515a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 2));
2516a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2517a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Now commit and delete the last entry.
25185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url4);
2519a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_TRUE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, controller.GetEntryCount());
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove an entry which is not the last committed one.
2525a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_TRUE(controller.RemoveEntryAtIndex(0));
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the 2 remaining entries.
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.RemoveEntryAtIndex(1);
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.RemoveEntryAtIndex(0);
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should leave us with only the last committed entry.
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the transient entry, making sure it goes away with all navigations.
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, TransientEntry) {
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
25492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url3_ref("http://foo/3#bar");
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url4("http://foo/4");
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL transient_url("http://foo/transient");
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url0, Referrer(), PAGE_TRANSITION_TYPED, std::string());
25555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url0);
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
25585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url1);
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notifications.Reset();
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding a transient with no pending entry.
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* transient_entry = new NavigationEntryImpl;
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
25652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not have received any notifications.
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check our state.
25714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 3);
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 1);
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate.
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
25845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url2);
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have navigated, transient entry should be gone.
25874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 3);
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient again, then navigate with no pending entry this time.
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
25932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
25944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
25955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url3);
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transient entry should be gone.
25974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL());
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 4);
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiate a navigation, add a transient then commit navigation.
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url4, Referrer(), PAGE_TRANSITION_TYPED, std::string());
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(4, url4);
26084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL());
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 5);
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go back.  This should simply remove the transient.
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transient entry should be gone.
26204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL());
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 5);
26225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url3);
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go to an entry before the current one.
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoToIndex(1);
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The navigation should have been initiated, transient entry should be gone.
26314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
26324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Visible entry does not update for history navigations until commit.
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL());
26355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url1);
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go to an entry after the current one.
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoToIndex(3);
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The navigation should have been initiated, transient entry should be gone.
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because of the transient entry that is removed, going to index 3 makes us
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // land on url2 (which is visible after the commit).
26474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
26495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url2);
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go forward.
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have navigated, transient entry should be gone.
26604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
26614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url3, controller.GetPendingEntry()->GetURL());
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
26635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url3);
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL());
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add a transient and do an in-page navigation, replacing the current entry.
26672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transient_entry->SetURL(transient_url);
26692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url3_ref);
26722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Transient entry should be gone.
26734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
26744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url3_ref, controller.GetVisibleEntry()->GetURL());
26752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the URLs are correct.
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 5);
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0);
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(1)->GetURL(), url1);
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(2)->GetURL(), url2);
26812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(3)->GetURL(), url3_ref);
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(4)->GetURL(), url4);
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Reload initiates a new navigation to a transient entry's URL.
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ReloadTransient) {
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL transient_url("http://foo/transient");
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load |url0|, and start a pending navigation to |url1|.
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url0, Referrer(), PAGE_TRANSITION_TYPED, std::string());
26955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url0);
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1, Referrer(), PAGE_TRANSITION_TYPED, std::string());
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A transient entry is added, interrupting the navigation.
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* transient_entry = new NavigationEntryImpl;
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
27022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetTransientEntry());
27044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The page is reloaded, which should remove the pending entry for |url1| and
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the transient entry for |transient_url|, and start a navigation to
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |transient_url|.
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.Reload(true);
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
27124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(controller.GetEntryCount(), 1);
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0);
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load of |transient_url| completes.
27175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, transient_url);
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(controller.GetEntryCount(), 2);
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0);
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(1)->GetURL(), transient_url);
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2723ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Ensure that renderer initiated pending entries get replaced, so that we
2724ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// don't show a stale virtual URL when a navigation commits.
2725ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// See http://crbug.com/266922.
2726ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
2727ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  NavigationControllerImpl& controller = controller_impl();
2728a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Navigator* navigator =
2729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      contents()->GetFrameTree()->root()->navigator();
2730ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2731ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const GURL url1("nonexistent:12121");
2732ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const GURL url1_fixed("http://nonexistent:12121/");
2733ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const GURL url2("http://foo");
2734ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2735ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We create pending entries for renderer-initiated navigations so that we
2736ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // can show them in new tabs when it is safe.
2737a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1);
2738ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2739ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Simulate what happens if a BrowserURLHandler rewrites the URL, causing
2740ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // the virtual URL to differ from the URL.
2741ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  controller.GetPendingEntry()->SetURL(url1_fixed);
2742ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  controller.GetPendingEntry()->SetVirtualURL(url1);
2743ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2744ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1_fixed, controller.GetPendingEntry()->GetURL());
2745ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1, controller.GetPendingEntry()->GetVirtualURL());
2746ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(
2747ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
2748ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          is_renderer_initiated());
2749ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // If the user clicks another link, we should replace the pending entry.
2751a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url2);
2752ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
2753ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetPendingEntry()->GetVirtualURL());
2754ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2755ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Once it commits, the URL and virtual URL should reflect the actual page.
27565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
2757ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
2758ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetVirtualURL());
2759ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2760ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We should not replace the pending entry for an error URL.
2761a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1);
2762ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
2763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  navigator->DidStartProvisionalLoad(
2764a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      main_test_rfh(), 1, -1, true, GURL(kUnreachableWebDataURL));
2765ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
27668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
27678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We should remember if the pending entry will replace the current one.
27688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // http://crbug.com/308444.
2769a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url1);
27708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
27718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      set_should_replace_entry(true);
2772a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), 1, -1, true, url2);
27738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_TRUE(
27748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
27758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          should_replace_entry());
2776a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(nasko): Until OnNavigate is moved to RenderFrameHost, we need
2777a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to go through the RenderViewHost. The TestRenderViewHost routes navigations
2778a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to the main frame.
27795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
27808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
2781ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
2782ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the URLs for renderer-initiated navigations are not displayed to
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the user until the navigation commits, to prevent URL spoof attacks.
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/99016.
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, DontShowRendererURLUntilCommit) {
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For typed navigations (browser-initiated), both pending and visible entries
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should update before commit.
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(url0, Referrer(), PAGE_TRANSITION_TYPED, std::string());
27974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url0, controller.GetPendingEntry()->GetURL());
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, controller.GetVisibleEntry()->GetURL());
27995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url0);
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For link clicks (renderer-initiated navigations), the pending entry should
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // update before commit but the visible should not.
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(url1);
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, controller.GetVisibleEntry()->GetURL());
28074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_renderer_initiated());
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // After commit, both visible should be updated, there should be no pending
28134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // entry, and we should no longer treat the entry as renderer-initiated.
28145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url1);
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
28164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetLastCommittedEntry())->is_renderer_initiated());
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notifications.Reset();
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Tests that the URLs for renderer-initiated navigations in new tabs are
2825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// displayed to the user before commit, as long as the initial about:blank
2826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// page has not been modified.  If so, we must revert to showing about:blank.
2827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// See http://crbug.com/9682.
2828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, ShowRendererURLInNewTabUntilModified) {
2829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
2830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestNotificationTracker notifications;
2831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
2832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url("http://foo");
2834868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // For renderer-initiated navigations in new tabs (with no committed entries),
2836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we show the pending entry's URL as long as the about:blank page is not
2837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // modified.
2838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(url);
2839868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url_params.transition_type = PAGE_TRANSITION_LINK;
2840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
2841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
2842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
28434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
2844868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(
2845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
2846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          is_renderer_initiated());
2847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.IsInitialNavigation());
2848868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(test_rvh()->has_accessed_initial_document());
2849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2850868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // There should be no title yet.
2851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(contents()->GetTitle().empty());
2852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2853868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If something else modifies the contents of the about:blank page, then
2854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we must revert to showing about:blank to avoid a URL spoof.
2855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  test_rvh()->OnMessageReceived(
2856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        ViewHostMsg_DidAccessInitialDocument(0));
2857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(test_rvh()->has_accessed_initial_document());
2858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry());
28594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
2860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notifications.Reset();
2862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, DontShowRendererURLInNewTabAfterCommit) {
2865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
2866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestNotificationTracker notifications;
2867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
2868868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2869868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo/eh");
2870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo/bee");
2871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // For renderer-initiated navigations in new tabs (with no committed entries),
2873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we show the pending entry's URL as long as the about:blank page is not
2874868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // modified.
2875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(url1);
2876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url_params.transition_type = PAGE_TRANSITION_LINK;
2877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
2878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
2879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
2880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(
2881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
2882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          is_renderer_initiated());
2883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.IsInitialNavigation());
2884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(test_rvh()->has_accessed_initial_document());
2885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Simulate a commit and then starting a new pending navigation.
28875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
2888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationController::LoadURLParams load_url2_params(url2);
2889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url2_params.transition_type = PAGE_TRANSITION_LINK;
2890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url2_params.is_renderer_initiated = true;
2891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURLWithParams(load_url2_params);
2892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We should not consider this an initial navigation, and thus should
2894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // not show the pending URL.
2895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(test_rvh()->has_accessed_initial_document());
2896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(controller.IsInitialNavigation());
2897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.GetVisibleEntry());
2898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
2899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notifications.Reset();
2901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that IsInPageNavigation returns appropriate results.  Prevents
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// regression for bug 1126349.
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, IsInPageNavigation) {
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL with no refs.
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com/home.html");
29095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url);
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reloading the page is not an in-page navigation.
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(url));
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL other_url("http://www.google.com/add.html");
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(other_url));
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url_with_ref("http://www.google.com/home.html#my_ref");
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref));
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL with refs.
29195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url_with_ref);
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reloading the page is not an in-page navigation.
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(url_with_ref));
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(url));
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(other_url));
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL other_url_with_ref("http://www.google.com/home.html#my_other_ref");
2926bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(controller.IsURLInPageNavigation(other_url_with_ref));
2927bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
2928bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Going to the same url again will be considered in-page
2929bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // if the renderer says it is even if the navigation type isn't IN_PAGE.
2930bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref, true,
2931bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      NAVIGATION_TYPE_UNKNOWN));
2932bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
2933bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Going back to the non ref url will be considered in-page if the navigation
2934bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // type is IN_PAGE.
2935bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(controller.IsURLInPageNavigation(url, true,
2936bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      NAVIGATION_TYPE_IN_PAGE));
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some pages can have subframes with the same base URL (minus the reference) as
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the main page. Even though this is hard, it can happen, and we don't want
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// these subframe navigations to affect the toplevel document. They should
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead be ignored.  http://crbug.com/5585
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, SameSubframe) {
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate the main frame.
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com/");
29475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url);
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should be at the first navigation entry.
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate a subframe that would normally count as in-page.
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL subframe("http://www.google.com/#");
29555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = subframe;
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
296290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(subframe);
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
29645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(test_rvh(), params, &details));
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing should have changed.
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that on cloning a WebContentsImpl and going back needs_reload is
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// false.
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CloneAndGoBack) {
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
29775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 title(base::ASCIIToUTF16("Title"));
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
29804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(title);
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, clone->GetController().GetEntryCount());
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(clone->GetController().NeedsReload());
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  clone->GetController().GoBack();
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigating back should have triggered needs_reload_ to go false.
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(clone->GetController().NeedsReload());
2990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Ensure that the pending URL and its title are visible.
2992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, clone->GetController().GetVisibleEntry()->GetURL());
2993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(title, clone->GetTitle());
2994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Make sure that reloading a cloned tab doesn't change its pending entry index.
2997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// See http://crbug.com/234491.
2998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CloneAndReload) {
2999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
30025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 title(base::ASCIIToUTF16("Title"));
3003868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3004868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
30054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(title);
3006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
3009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  clone->GetController().LoadIfNecessary();
3010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, clone->GetController().GetEntryCount());
3012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, clone->GetController().GetPendingEntryIndex());
3013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  clone->GetController().Reload(true);
3015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, clone->GetController().GetPendingEntryIndex());
30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that cloning a WebContentsImpl doesn't copy interstitials.
30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CloneOmitsInterstitials) {
30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add an interstitial entry.  Should be deleted with controller.
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* interstitial_entry = new NavigationEntryImpl();
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial_entry->set_page_type(PAGE_TYPE_INTERSTITIAL);
30302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(interstitial_entry);
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, clone->GetController().GetEntryCount());
30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test requesting and triggering a lazy reload.
30384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(NavigationControllerTest, LazyReload) {
30394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
30404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const GURL url("http://foo");
30414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommit(url);
30424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(controller.NeedsReload());
30434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
30444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Request a reload to happen when the controller becomes active (e.g. after
30454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the renderer gets killed in background on Android).
30464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.SetNeedsReload();
30474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.NeedsReload());
30484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
30494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set the controller as active, triggering the requested reload.
30504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.SetActive(true);
30514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(controller.NeedsReload());
30524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
30534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests a subframe navigation while a toplevel navigation is pending.
30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/43967
30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, SubframeWhilePending) {
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the first page.
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/");
30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start a pending load to a totally different page, but don't commit it.
30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://bar/");
30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send a subframe update from the first page, as if one had just
30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // automatically loaded. Auto subframes don't increment the page ID.
30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1_sub("http://foo/subframe");
30705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = controller.GetLastCommittedEntry()->GetPageID();
30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url1_sub;
30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
307790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url1_sub);
30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should return false meaning that nothing was actually updated.
30815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(test_rvh(), params, &details));
30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The notification should have updated the last committed one, and not
30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pending load.
30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetLastCommittedEntry()->GetURL());
30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The active entry should be unchanged by the subframe load.
30884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test CopyStateFrom with 2 urls, the first selected and nothing in the target.
30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFrom) {
30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_controller.CopyStateFrom(controller);
31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other_controller should now contain 2 urls.
31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should be looking at the first one.
31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, other_controller.GetCurrentEntryIndex());
31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is a different site than url1, so the IDs start again at 0.
31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID());
31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0));
31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3123ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3124ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Ensure the SessionStorageNamespaceMaps are the same size and have
3125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // the same partitons loaded.
3126ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  //
3127ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // TODO(ajwong): We should load a url from a different partition earlier
3128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // to make sure this map has more than one entry.
3129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const SessionStorageNamespaceMap& session_storage_namespace_map =
3130ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      controller.GetSessionStorageNamespaceMap();
3131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const SessionStorageNamespaceMap& other_session_storage_namespace_map =
3132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      other_controller.GetSessionStorageNamespaceMap();
3133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(session_storage_namespace_map.size(),
3134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            other_session_storage_namespace_map.size());
3135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  for (SessionStorageNamespaceMap::const_iterator it =
3136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch           session_storage_namespace_map.begin();
3137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch       it != session_storage_namespace_map.end();
3138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch       ++it) {
3139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SessionStorageNamespaceMap::const_iterator other =
3140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        other_session_storage_namespace_map.find(it->first);
3141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(other != other_session_storage_namespace_map.end());
3142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests CopyStateFromAndPrune with 2 urls in source, 1 in dest.
31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPrune) {
31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First two entries should have the same SiteInstance.
31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0));
31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 =
31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1));
31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, instance2);
31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetEntryAtIndex(0)->GetPageID());
31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryAtIndex(1)->GetPageID());
31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, contents()->GetMaxPageIDForSiteInstance(instance1));
31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
31725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other_controller should now contain the 3 urls: url1, url2 and url3.
31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL());
31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetEntryAtIndex(1)->GetPageID());
31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A new SiteInstance in a different BrowsingInstance should be used for the
31885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // new tab.
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance3 =
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance3, instance1);
31925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(instance3->IsRelatedSiteInstance(instance1));
31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, other_contents->GetMaxPageIDForSiteInstance(instance1));
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance3));
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, the first selected and 1 entry in
32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the target.
32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPrune2) {
32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
3211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  contents()->CommitPendingNavigation();
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
3219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
32205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url3
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
3225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(1, other_controller.GetCurrentEntryIndex());
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
3229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID());
32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
3234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1));
32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, the last selected and 2 entries in
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the target.
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPrune3) {
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
3245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url4("http://foo4");
3246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
3248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
3255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1)), 2,
3257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
32585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url2, url4
3261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
3263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
3264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
3267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL());
3268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
3273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, 2 entries in the target, with
3277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// not the last entry selected in the target.
3278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneNotLast) {
3279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
3282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url3("http://foo3");
3283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url4("http://foo4");
3284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
3286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
3293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_controller.GoBack();
3294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->CommitPendingNavigation();
3295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
3297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
32985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url2, url3
3301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
3303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
3304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
3307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL());
3308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
3313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, the first selected and 1 entry plus
3317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// a pending entry in the target.
3318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneTargetPending) {
3319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
3322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url3("http://foo3");
3323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url4("http://foo4");
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
3328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  contents()->CommitPendingNavigation();
33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_controller.LoadURL(
3335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url4, Referrer(), PAGE_TRANSITION_TYPED, std::string());
3336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
3338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
33395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain url1, url3, and a pending entry
3342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // for url4.
3343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
3345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
3346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
3349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // And there should be a pending entry for url4.
3351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(other_controller.GetPendingEntry());
3352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetPendingEntry()->GetURL());
3353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0));
3358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 1 url in the source, 1 entry and a pending
3362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// client redirect entry (with the same page ID) in the target.  This used to
3363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// crash because the last committed entry would be pruned but max_page_id
3364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// remembered the page ID (http://crbug.com/234809).
3365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneTargetPending2) {
3366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2a("http://foo2/a");
3369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2b("http://foo2/b");
33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url2a);
3377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Simulate a client redirect, which has the same page ID as entry 2a.
3378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_controller.LoadURL(
3379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url2b, Referrer(), PAGE_TRANSITION_LINK, std::string());
3380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_controller.GetPendingEntry()->SetPageID(
3381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetLastCommittedEntry()->GetPageID());
3382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
3385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
33865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain url1, url2a, and a pending entry
3389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // for url2b.
3390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
3392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2a, other_controller.GetEntryAtIndex(1)->GetURL());
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // And there should be a pending entry for url4.
33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(other_controller.GetPendingEntry());
3399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2b, other_controller.GetPendingEntry()->GetURL());
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Let the pending entry commit.
3402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->CommitPendingNavigation();
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
3407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1));
3408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, a back navigation pending in the
3412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// source, and 1 entry in the target. The back pending entry should be ignored.
3413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneSourcePending) {
3414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
3417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url3("http://foo3");
3418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
3420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.GoBack();
3422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
3429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
34305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url2, url3
3433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
3435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
3436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
3439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL());
3440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
3441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests CopyStateFromAndPrune with 3 urls in source, 1 in dest,
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when the max entry count is 3.  We should prune one entry.
34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneMaxEntries) {
34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t original_count = NavigationControllerImpl::max_entry_count();
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxEntryCount = 3;
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount);
34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url4("http://foo/4");
34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a PrunedListener to observe prune notifications.
34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrunedListener listener(&controller);
34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
34775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have received a pruned notification.
34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.notification_count_);
34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(listener.details_.from_front);
34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.details_.count);
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other_controller should now contain only 3 urls: url2, url3 and url4.
34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(0)->GetURL());
34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL());
34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetEntryAtIndex(0)->GetPageID());
34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, other_controller.GetEntryAtIndex(1)->GetPageID());
34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(original_count);
34985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests CopyStateFromAndPrune with 2 urls in source, 1 in dest, with
35015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// replace_entry set to true.
35025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneReplaceEntry) {
35035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
35045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo/1");
35055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url2("http://foo/2");
35065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url3("http://foo/3");
35075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url1);
35095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url2);
35105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // First two entries should have the same SiteInstance.
35125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SiteInstance* instance1 =
35135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0));
35145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SiteInstance* instance2 =
35155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1));
35165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(instance1, instance2);
35175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, controller.GetEntryAtIndex(0)->GetPageID());
35185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryAtIndex(1)->GetPageID());
35195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, contents()->GetMaxPageIDForSiteInstance(instance1));
35205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
35225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
35235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
35245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
35255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
35265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
35275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
35285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, true);
35295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // other_controller should now contain the 2 urls: url1 and url3.
35315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
35335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, other_controller.GetCurrentEntryIndex());
35355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
35375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
35385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
35395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID());
35405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A new SiteInstance in a different BrowsingInstance should be used for the
35425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // new tab.
35435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SiteInstance* instance3 =
35445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1));
35455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(instance3, instance1);
35465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(instance3->IsRelatedSiteInstance(instance1));
35475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
35495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // from the current tab.
35505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, other_contents->GetMaxPageIDForSiteInstance(instance1));
35515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance3));
35525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
35535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests CopyStateFromAndPrune with 3 urls in source, 1 in dest, when the max
35555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// entry count is 3 and replace_entry is true.  We should not prune entries.
35565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneMaxEntriesReplaceEntry) {
35575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
35585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t original_count = NavigationControllerImpl::max_entry_count();
35595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kMaxEntryCount = 3;
35605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount);
35625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo/1");
35645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url2("http://foo/2");
35655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url3("http://foo/3");
35665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url4("http://foo/4");
35675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create a PrunedListener to observe prune notifications.
35695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrunedListener listener(&controller);
35705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url1);
35725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url2);
35735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url3);
35745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
35765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
35775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
35785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
35795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
35805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
35815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
35825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, true);
35835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should have received no pruned notification.
35855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, listener.notification_count_);
35865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // other_controller should now contain only 3 urls: url1, url2 and url4.
35885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
35905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
35925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
35935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
35945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
35955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL());
35965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
35975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetEntryAtIndex(1)->GetPageID());
35985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
35995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
36005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(original_count);
36015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
36025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that navigations initiated from the page (with the history object)
36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// work as expected without navigation entries.
36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, HistoryNavigate) {
36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the page calling history.back(), it should not create a pending
36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry.
36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->OnGoToEntryAtOffset(-1);
36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual cross-navigation is suspended until the current RVH tells us
36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it unloaded, simulate that.
36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also make sure we told the page to navigate.
36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const IPC::Message* message =
36265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID);
36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message != NULL);
36285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Tuple1<FrameMsg_Navigate_Params> nav_params;
36295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameMsg_Navigate::Read(message, &nav_params);
36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, nav_params.a.url);
36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process()->sink().ClearMessages();
36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now test history.forward()
36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->OnGoToEntryAtOffset(1);
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual cross-navigation is suspended until the current RVH tells us
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it unloaded, simulate that.
36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
36395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message = process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID);
36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message != NULL);
36415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameMsg_Navigate::Read(message, &nav_params);
36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, nav_params.a.url);
36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process()->sink().ClearMessages();
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure an extravagant history.go() doesn't break.
36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->OnGoToEntryAtOffset(120);  // Out of bounds.
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
36485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message = process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID);
36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message == NULL);
36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for the only entry.
3653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForSingle) {
36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
36572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
36592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0)), 0,
36602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(0)->GetPageID());
36612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url1);
36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for first entry.
3669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForFirst) {
36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
36832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0)), 0,
36842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(0)->GetPageID());
36852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url1);
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for intermediate entry.
3693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForIntermediate) {
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
37062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1)), 0,
37072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(1)->GetPageID());
37082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url2);
37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for a pending entry that is not yet in
3716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the list of entries.
3717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForPendingNotInList) {
37182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
37192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url1("http://foo/1");
37202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://foo/2");
37212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url3("http://foo/3");
37222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateAndCommit(url1);
37242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateAndCommit(url2);
37252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a pending entry that is not in the entry list.
37272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
37282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url3, Referrer(), PAGE_TRANSITION_TYPED, std::string());
37292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
37302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
37312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
37332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL, 0, controller.GetPendingEntry()->GetPageID());
3734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
37352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We should only have the last committed and pending entries at this point,
3737868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and the pending entry should still not be in the entry list.
3738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
3739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
37402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
37412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
3742868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
37432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to commit the pending entry.
37455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
37462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
37472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
3748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
3749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test to ensure that when we do a history navigation back to the current
37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// committed page (e.g., going forward to a slow-loading page, then pressing
37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the back button), we just stop the navigation to prevent the throbber from
37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// running continuously. Otherwise, the RenderViewHost forces the throbber to
37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// start, but WebKit essentially ignores the navigation and never sends a
37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message to stop the throbber.
37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, StopOnHistoryNavigationToCurrentPage) {
37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url0);
37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back to the original page, then forward to the slow page, then back
37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetPendingEntryIndex());
37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, IsInitialNavigation) {
37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initial state.
37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.IsInitialNavigation());
37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After commit, it stays false.
37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
37875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
3788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
3789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.IsInitialNavigation());
37912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After starting a new navigation, it stays false.
37932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://foo2");
37942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
37952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url2, Referrer(), PAGE_TRANSITION_TYPED, std::string());
37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that the favicon is not reused across a client redirect.
37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (crbug.com/28515)
38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ClearFaviconOnRedirect) {
38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kPageWithFavicon("http://withfavicon.html");
38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kPageWithoutFavicon("http://withoutfavicon.html");
38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kIconURL("http://withfavicon.ico");
38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Image kDefaultFavicon = FaviconStatus().image;
38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kPageWithFavicon);
3811868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
3812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller.GetLastCommittedEntry();
38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPageWithFavicon, entry->GetURL());
38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate Chromium having set the favicon for |kPageWithFavicon|.
38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::FaviconStatus& favicon_status = entry->GetFavicon();
38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.image = CreateImage(SK_ColorWHITE);
38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.url = kIconURL;
38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.valid = true;
38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image));
38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithTransition(
38262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      0,  // same page ID.
38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPageWithoutFavicon,
38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PAGE_TRANSITION_CLIENT_REDIRECT);
3829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
3830868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller.GetLastCommittedEntry();
38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPageWithoutFavicon, entry->GetURL());
38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image));
38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that the favicon is not cleared for NavigationEntries which were
38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// previously navigated to.
38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, BackNavigationDoesNotClearFavicon) {
38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://www.a.com/1");
38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://www.a.com/2");
38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kIconURL("http://www.a.com/1/favicon.ico");
38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
3851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
3852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate Chromium having set the favicon for |kUrl1|.
38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image favicon_image = CreateImage(SK_ColorWHITE);
38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NavigationEntry* entry = controller.GetLastCommittedEntry();
38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::FaviconStatus& favicon_status = entry->GetFavicon();
38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.image = favicon_image;
38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.url = kIconURL;
38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.valid = true;
38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to another page and go back to the original page.
38645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
3865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
3866868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
38675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithTransition(
38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUrl1,
38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PAGE_TRANSITION_FORWARD_BACK);
3871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
3872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the favicon for the page at |kUrl1| was not cleared.
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller.GetEntryAtIndex(0);
38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl1, entry->GetURL());
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(DoImagesMatch(favicon_image, entry->GetFavicon().image));
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The test crashes on android: http://crbug.com/170449
38822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
38832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_PurgeScreenshot DISABLED_PurgeScreenshot
38842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
38852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_PurgeScreenshot PurgeScreenshot
38862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
38872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that screenshot are purged correctly.
38882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NavigationControllerTest, MAYBE_PurgeScreenshot) {
38892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
38902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationEntryImpl* entry;
38922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate enough times to make sure that some screenshots are purged.
38942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 12; ++i) {
38952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL url(base::StringPrintf("http://foo%d/", i));
38962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NavigateAndCommit(url);
38972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(i, controller.GetCurrentEntryIndex());
38982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
38992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockScreenshotManager* screenshot_manager =
3901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new MockScreenshotManager(&controller);
3902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller.SetScreenshotManager(screenshot_manager);
39032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount(); ++i) {
39042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
3906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
39077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(entry->screenshot().get());
39082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateAndCommit(GURL("https://foo/"));
39112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(13, controller.GetEntryCount());
39122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry = NavigationEntryImpl::FromNavigationEntry(
39132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(11));
3914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  screenshot_manager->TakeScreenshotFor(entry);
39152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; ++i) {
39172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
39197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
39207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not purged";
39212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 2; i < controller.GetEntryCount() - 1; ++i) {
39242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
39267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(entry->screenshot().get()) << "Screenshot not found for " << i;
39272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to index 5 and then try to assign screenshot to all entries.
39302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoToIndex(5);
39312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->CommitPendingNavigation();
39322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5, controller.GetCurrentEntryIndex());
39332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount() - 1; ++i) {
39342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
3936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
39372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 10; i <= 12; ++i) {
39402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
39427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
39437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not purged";
3944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
39452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to index 7 and assign screenshot to all entries.
39482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoToIndex(7);
39492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->CommitPendingNavigation();
39502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(7, controller.GetCurrentEntryIndex());
39512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount() - 1; ++i) {
39522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
3954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
39552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; ++i) {
39582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
39607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
39617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not purged";
39622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear all screenshots.
39652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(13, controller.GetEntryCount());
3966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(10, screenshot_manager->GetScreenshotCount());
39672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.ClearAllScreenshots();
3968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, screenshot_manager->GetScreenshotCount());
39692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount(); ++i) {
39702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
39712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
39727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
39737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not cleared";
39742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
39752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
39762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test that the navigation controller clears its session history when a
3978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// navigation commits with the clear history list flag set.
3979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NavigationControllerTest, ClearHistoryList) {
3980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url1("http://foo1");
3981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url2("http://foo2");
3982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url3("http://foo3");
3983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url4("http://foo4");
3984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a session history with three entries, second entry is active.
3988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateAndCommit(url1);
3989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateAndCommit(url2);
3990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateAndCommit(url3);
3991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller.GoBack();
3992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  contents()->CommitPendingNavigation();
3993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
3994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
3995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a new pending navigation, and indicate that the session history
3997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // should be cleared.
3998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationController::LoadURLParams params(url4);
3999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.should_clear_history_list = true;
4000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller.LoadURLWithParams(params);
4001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that the pending entry correctly indicates that the session history
4003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // should be cleared.
4004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationEntryImpl* entry =
4005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
4006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          controller.GetPendingEntry());
4007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(entry);
4008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(entry->should_clear_history_list());
4009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Assume that the RV correctly cleared its history and commit the navigation.
4011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost())->
4012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      set_simulate_history_list_was_cleared(true);
4013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  contents()->CommitPendingNavigation();
4014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that the NavigationController's session history was correctly
4016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // cleared.
4017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
4018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
4019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
4020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
4021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
4022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
40234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL());
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
4027