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"
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/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"
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/browser/frame_host/cross_site_transferring_request.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_controller_impl.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/browser/frame_host/navigation_entry_impl.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/frame_host/navigator.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/site_instance_impl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/frame_messages.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/page_state.h"
302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/common/url_constants.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/mock_render_process_host.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_notification_tracker.h"
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/test/test_utils.h"
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/test/test_render_frame_host.h"
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/test/test_render_view_host.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/test/test_web_contents.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "skia/ext/platform_canvas.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates an image with a 1x1 SkBitmap of the specified |color|.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image CreateImage(SkColor color) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bitmap.allocN32Pixels(1, 1);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap.eraseColor(color);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Image::CreateFrom1xBitmap(bitmap);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if images |a| and |b| have the same pixel data.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DoImagesMatch(const gfx::Image& a, const gfx::Image& b) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assume that if the 1x bitmaps match, the images match.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap a_bitmap = a.AsBitmap();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap b_bitmap = b.AsBitmap();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (a_bitmap.width() != b_bitmap.width() ||
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      a_bitmap.height() != b_bitmap.height()) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels a_bitmap_lock(a_bitmap);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels b_bitmap_lock(b_bitmap);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return memcmp(a_bitmap.getPixels(),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                b_bitmap.getPixels(),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                a_bitmap.getSize()) == 0;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MockScreenshotManager : public content::NavigationEntryScreenshotManager {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit MockScreenshotManager(content::NavigationControllerImpl* owner)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : content::NavigationEntryScreenshotManager(owner),
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        encoding_screenshot_in_progress_(false) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MockScreenshotManager() {
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void TakeScreenshotFor(content::NavigationEntryImpl* entry) {
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SkBitmap bitmap;
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bitmap.allocPixels(SkImageInfo::Make(
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        1, 1, kAlpha_8_SkColorType, kPremul_SkAlphaType));
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    bitmap.eraseARGB(0, 0, 0, 0);
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    encoding_screenshot_in_progress_ = true;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnScreenshotTaken(entry->GetUniqueID(), true, bitmap);
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WaitUntilScreenshotIsReady();
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int GetScreenshotCount() {
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return content::NavigationEntryScreenshotManager::GetScreenshotCount();
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WaitUntilScreenshotIsReady() {
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!encoding_screenshot_in_progress_)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_runner_ = new content::MessageLoopRunner;
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_runner_->Run();
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Overridden from content::NavigationEntryScreenshotManager:
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TakeScreenshotImpl(
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RenderViewHost* host,
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::NavigationEntryImpl* entry) OVERRIDE {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnScreenshotSet(content::NavigationEntryImpl* entry) OVERRIDE {
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    encoding_screenshot_in_progress_ = false;
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NavigationEntryScreenshotManager::OnScreenshotSet(entry);
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (message_loop_runner_.get())
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message_loop_runner_->Quit();
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool encoding_screenshot_in_progress_;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockScreenshotManager);
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TimeSmoother tests ----------------------------------------------------------
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With no duplicates, GetSmoothedTime should be the identity
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, Basic) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 1; i < 1000; ++i) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time t = base::Time::FromInternalValue(i);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(t, smoother.GetSmoothedTime(t));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With a single duplicate and timestamps thereafter increasing by one
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// microsecond, the smoothed time should always be one behind.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, SingleDuplicate) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time t = base::Time::FromInternalValue(1);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(t, smoother.GetSmoothedTime(t));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 1; i < 1000; ++i) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t = base::Time::FromInternalValue(i + 1);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    t = base::Time::FromInternalValue(i);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With k duplicates and timestamps thereafter increasing by one
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// microsecond, the smoothed time should always be k behind.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, ManyDuplicates) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kNumDuplicates = 100;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time t = base::Time::FromInternalValue(1);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 0; i < kNumDuplicates; ++i) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t = base::Time::FromInternalValue(i + 1);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 1; i < 1000; ++i) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t =
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Time::FromInternalValue(i + kNumDuplicates);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    t = base::Time::FromInternalValue(i);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the clock jumps far back enough after a run of duplicates, it
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should immediately jump to that value.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeSmoother, ClockBackwardsJump) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 kNumDuplicates = 100;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::TimeSmoother smoother;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time t = base::Time::FromInternalValue(1000);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int64 i = 0; i < kNumDuplicates; ++i) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time expected_t = base::Time::FromInternalValue(i + 1000);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_t, smoother.GetSmoothedTime(t));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  t = base::Time::FromInternalValue(500);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(t, smoother.GetSmoothedTime(t));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NavigationControllerTest ----------------------------------------------------
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class NavigationControllerTest
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : public RenderViewHostImplTestHarness,
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      public WebContentsObserver {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerTest() : navigation_entry_committed_counter_(0) {
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    RenderViewHostImplTestHarness::SetUp();
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WebContents* web_contents = RenderViewHostImplTestHarness::web_contents();
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(web_contents);  // The WebContents should be created by now.
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WebContentsObserver::Observe(web_contents);
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // WebContentsObserver:
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void DidStartNavigationToPendingEntry(
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const GURL& url,
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NavigationController::ReloadType reload_type) OVERRIDE {
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    navigated_url_ = url;
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void NavigationEntryCommitted(
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const LoadCommittedDetails& load_details) OVERRIDE {
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_++;
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const GURL& navigated_url() const {
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return navigated_url_;
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller_impl() {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<NavigationControllerImpl&>(controller());
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GURL navigated_url_;
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t navigation_entry_committed_counter_;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RegisterForAllNavNotifications(TestNotificationTracker* tracker,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    NavigationController* controller) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tracker->ListenFor(NOTIFICATION_NAV_LIST_PRUNED,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     Source<NavigationController>(controller));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tracker->ListenFor(NOTIFICATION_NAV_ENTRY_CHANGED,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     Source<NavigationController>(controller));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SiteInstance* GetSiteInstanceFromEntry(NavigationEntry* entry) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NavigationEntryImpl::FromNavigationEntry(entry)->site_instance();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestWebContentsDelegate : public WebContentsDelegate {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestWebContentsDelegate() :
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      navigation_state_change_count_(0),
23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      repost_form_warning_count_(0) {}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int navigation_state_change_count() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return navigation_state_change_count_;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int repost_form_warning_count() {
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return repost_form_warning_count_;
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep track of whether the tab has notified us of a navigation state change.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void NavigationStateChanged(const WebContents* source,
2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                      InvalidateTypes changed_flags) OVERRIDE {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    navigation_state_change_count_++;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void ShowRepostFormWarningDialog(WebContents* source) OVERRIDE {
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    repost_form_warning_count_++;
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The number of times NavigationStateChanged has been called.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int navigation_state_change_count_;
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The number of times ShowRepostFormWarningDialog() was called.
26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int repost_form_warning_count_;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Defaults) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetLastCommittedEntry());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), -1);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 0);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, GoToOffset) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumUrls = 5;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> urls(kNumUrls);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumUrls; ++i) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    urls[i] = GURL(base::StringPrintf("http://www.a.com/%d", i));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, urls[0]);
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(urls[0], controller.GetVisibleEntry()->GetVirtualURL());
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(1));
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 1; i <= 4; ++i) {
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(i, urls[i]);
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(urls[i], controller.GetVisibleEntry()->GetVirtualURL());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(controller.CanGoToOffset(-i));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(-(i + 1)));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(1));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have loaded 5 pages, and are currently at the last-loaded page.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int url_index = 4;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Tests {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_MIDDLE_PAGE = -2,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_FORWARDS = 1,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_BACKWARDS = -1,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_BEGINNING = -2,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_END = 4,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUM_TESTS = 5,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int test_offsets[NUM_TESTS] = {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_MIDDLE_PAGE,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_FORWARDS,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_BACKWARDS,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_BEGINNING,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GO_TO_END
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int test = 0; test < NUM_TESTS; ++test) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int offset = test_offsets[test];
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.GoToOffset(offset);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_index += offset;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that the GoToOffset will land on the expected page.
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(urls[url_index], controller.GetPendingEntry()->GetVirtualURL());
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(url_index, urls[url_index]);
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that we can go to any valid offset into the history.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < urls.size(); ++j)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(controller.CanGoToOffset(j - url_index));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that we can't go beyond the beginning or end of the history.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(-(url_index + 1)));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(controller.CanGoToOffset(urls.size() - url_index));
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creating a pending notification should not have issued any of the
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications we're listening for.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be pending.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 0);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), -1);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetLastCommittedEntry());
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(controller.GetPendingEntry());
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntry(), controller.GetVisibleEntry());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), -1);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Neither the timestamp nor the status code should have been set yet.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry()->GetTimestamp().is_null());
376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntry()->GetHttpStatusCode());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have gotten no notifications from the preceeding checks.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be committed.
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 0);
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should have been set.
3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry()->GetTimestamp().is_null());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load another...
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be pending.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(controller.GetPendingEntry());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntry(), controller.GetVisibleEntry());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): maybe this should really be true?
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 0);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry()->GetTimestamp().is_null());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the beforeunload ack for the cross-site transition, and then the
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // commit.
421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  test_rvh()->SendBeforeUnloadACK(true);
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetPendingMainFrame()->SendNavigate(1, url2);
423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The load should now be committed.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 1);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry()->GetTimestamp().is_null());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time GetFixedTime(base::Time time) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return time;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLSameTime) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the clock to always return a timestamp of 1.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.SetGetTimestampCallbackForTest(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GetFixedTime, base::Time::FromInternalValue(1)));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load another...
4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the beforeunload ack for the cross-site transition, and then the
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // commit.
473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  test_rvh()->SendBeforeUnloadACK(true);
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The two loads should now be committed.
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(controller.GetEntryCount(), 2);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamps should be distinct despite the clock returning the
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same value.
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(0)->GetTimestamp().ToInternalValue());
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(1)->GetTimestamp().ToInternalValue());
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CheckNavigationEntryMatchLoadParams(
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NavigationController::LoadURLParams& load_params,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NavigationEntryImpl* entry) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.url, entry->GetURL());
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.referrer.url, entry->GetReferrer().url);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.referrer.policy, entry->GetReferrer().policy);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.transition_type, entry->GetTransitionType());
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.extra_headers, entry->extra_headers());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.is_renderer_initiated, entry->is_renderer_initiated());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.base_url_for_data_url, entry->GetBaseURLForDataURL());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!load_params.virtual_url_for_data_url.is_empty()) {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(load_params.virtual_url_for_data_url, entry->GetVirtualURL());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NavigationController::UA_OVERRIDE_INHERIT !=
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      load_params.override_user_agent) {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool should_override = (NavigationController::UA_OVERRIDE_TRUE ==
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        load_params.override_user_agent);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(should_override, entry->GetIsOverridingUserAgent());
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(load_params.browser_initiated_post_data.get(),
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            entry->GetBrowserInitiatedPostData());
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(load_params.transferred_global_request_id,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entry->transferred_global_request_id());
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLWithParams) {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_params(GURL("http://foo"));
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.referrer =
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Referrer(GURL("http://referrer"), blink::WebReferrerPolicyDefault);
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_params.transition_type = ui::PAGE_TRANSITION_GENERATED;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.extra_headers = "content-type: text/plain";
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.load_type = NavigationController::LOAD_TYPE_DEFAULT;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.is_renderer_initiated = true;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
5262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  load_params.transferred_global_request_id = GlobalRequestID(2, 3);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_params);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry =
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetPendingEntry());
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should not have been set yet.
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(entry);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry->GetTimestamp().is_null());
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckNavigationEntryMatchLoadParams(load_params, entry);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLWithExtraParams_Data) {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_params(
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL("data:text/html,dataurl"));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.load_type = NavigationController::LOAD_TYPE_DATA;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.base_url_for_data_url = GURL("http://foo");
547f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  load_params.virtual_url_for_data_url = GURL(url::kAboutBlankURL);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.override_user_agent = NavigationController::UA_OVERRIDE_FALSE;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_params);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry =
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetPendingEntry());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckNavigationEntryMatchLoadParams(load_params, entry);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURLWithExtraParams_HttpPost) {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_params(GURL("https://posturl"));
5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_params.transition_type = ui::PAGE_TRANSITION_TYPED;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.load_type =
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationController::LOAD_TYPE_BROWSER_INITIATED_HTTP_POST;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char* raw_data =
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const unsigned char*>("d\n\0a2");
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int length = 5;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<unsigned char> post_data_vector(raw_data, raw_data+length);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> data =
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&post_data_vector);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_params.browser_initiated_post_data = data.get();
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_params);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* entry =
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetPendingEntry());
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckNavigationEntryMatchLoadParams(load_params, entry);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when the same page is loaded again.  Should not create a
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// new session history entry. This is what happens when you press enter in the
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URL bar to reload: a pending entry is created and then it is discarded when
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the load commits (because WebCore didn't actually make a new entry).
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_SamePage) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp();
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(timestamp.is_null());
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not have produced a new session history entry.
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should have been updated.
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Change this EXPECT_GE (and other similar ones) to
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // EXPECT_GT once we guarantee that timestamps are unique.
6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GE(controller.GetVisibleEntry()->GetTimestamp(), timestamp);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Load the same page twice, once as a GET and once as a POST.
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// We should update the post state on the NavigationEntry.
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_SamePage_DifferentMethod) {
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestNotificationTracker notifications;
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo1");
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.page_id = 0;
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.url = url1;
6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_TYPED;
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.is_post = true;
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.post_id = 123;
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  params.page_state = PageState::CreateForTesting(url1, false, 0, 0);
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithParams(&params);
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The post data should be visible.
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationEntry* entry = controller.GetVisibleEntry();
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(entry);
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(entry->GetHasPostData());
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(entry->GetPostID(), 123);
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should not have produced a new session history entry.
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(controller.GetVisibleEntry(), entry);
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The post data should have been cleared due to the GET.
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(entry->GetHasPostData());
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(entry->GetPostID(), 0);
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests loading a URL but discarding it before the load commits.
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_Discarded) {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
6854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp();
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(timestamp.is_null());
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
6891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.DiscardNonCommittedEntries();
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not have produced a new session history entry.
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
6994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp should not have changed.
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(timestamp, controller.GetVisibleEntry()->GetTimestamp());
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigations that come in unrequested. This happens when the user
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigates from the web page, and here we test that there is no pending entry.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_NoPending) {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make an existing committed entry.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://eh");
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do a new navigation without making a pending one.
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://see");
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(99, kNewURL);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
7324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigating to a new URL when there is a new pending navigation that is
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not the one that just loaded. This will happen if the user types in a URL to
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// somewhere slow, and then navigates the current page before the typed URL
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// commits.
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_NewPending) {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make an existing committed entry.
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://eh");
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a pending entry to somewhere new.
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL2("http://bee");
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the beforeunload but before it commits, do a new navigation.
759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  test_rvh()->SendBeforeUnloadACK(true);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://see");
7616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetPendingMainFrame()->SendNavigate(3, kNewURL);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigating to a new URL when there is a pending back/forward
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation. This will happen if the user hits back, but before that commits,
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// they navigate somewhere new.
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_ExistingPending) {
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make some history.
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://foo/eh");
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL2("http://foo/bee");
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kExistingURL2);
792868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending back/forward navigation. The zeroth entry should be
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pending.
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntryIndex());
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before that commits, do a new navigation.
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://foo/see");
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, kNewURL);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
810868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
8134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests navigating to a new URL when there is a pending back/forward
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// navigation to a cross-process, privileged URL. This will happen if the user
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// hits back, but before that commits, they navigate somewhere new.
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_PrivilegedPending) {
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestNotificationTracker notifications;
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First make some history, starting with a privileged URL.
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kExistingURL1("http://privileged");
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
8271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Pretend it has bindings so we can tell if we incorrectly copy it.
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  test_rvh()->AllowBindings(2);
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate cross-process to a second URL.
8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kExistingURL2("http://foo/eh");
8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
8371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  test_rvh()->SendBeforeUnloadACK(true);
8396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* foo_rfh = contents()->GetPendingMainFrame();
8406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  foo_rfh->SendNavigate(1, kExistingURL2);
841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now make a pending back/forward navigation to a privileged entry.
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The zeroth entry should be pending.
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoBack();
8476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  foo_rfh->GetRenderViewHost()->SendBeforeUnloadACK(true);
8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntryIndex());
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, NavigationEntryImpl::FromNavigationEntry(
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                controller.GetPendingEntry())->bindings());
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Before that commits, do a new navigation.
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL kNewURL("http://foo/bee");
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadCommittedDetails details;
8576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  foo_rfh->SendNavigate(3, kNewURL);
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // There should no longer be any pending entry, and the third navigation we
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // just made should be committed.
861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
8654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetVisibleEntry()->GetURL());
8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                controller.GetLastCommittedEntry())->bindings());
8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigating to an existing URL when there is a pending new navigation.
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will happen if the user enters a URL, but before that commits, the
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current page fires history.back().
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_BackPreemptsPending) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First make some history.
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL1("http://foo/eh");
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
8811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kExistingURL2("http://foo/bee");
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
8881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kExistingURL2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
8895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kExistingURL2);
890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending new navigation.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://foo/see");
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
8961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kNewURL, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before that commits, a back navigation from the renderer commits.
9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kExistingURL1);
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should no longer be any pending entry, and the back navigation we
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // just made should be committed.
906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
9104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(kExistingURL1, controller.GetVisibleEntry()->GetURL());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests an ignored navigation when there is a pending new navigation.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will happen if the user enters a URL, but before that commits, the
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current blank page reloads.  See http://crbug.com/77507.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_IgnorePreemptsPending) {
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a WebContentsDelegate to listen for state changes.
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetDelegate());
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(delegate.get());
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Without any navigations, the renderer starts at about:blank.
927f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const GURL kExistingURL(url::kAboutBlankURL);
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending new navigation.
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://eh");
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
9321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kNewURL, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->navigation_state_change_count());
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before that commits, a document.write and location.reload can cause the
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // renderer to send a FrameNavigate with page_id -1.
9415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(-1, kExistingURL);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should clear the pending entry and notify of a navigation state
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change, so that we do not keep displaying kNewURL.
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, delegate->navigation_state_change_count());
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(NULL);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the pending entry state is correct after an abort.
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We do not want to clear the pending entry, so that the user doesn't
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// lose a typed URL.  (See http://crbug.com/9682.)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_AbortDoesntCancelPending) {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a WebContentsDelegate to listen for state changes.
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetDelegate());
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(delegate.get());
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Start with a pending new navigation.
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kNewURL("http://eh");
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
9691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kNewURL, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
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());
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It may abort before committing, if it's a download or due to a stop or
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a new navigation from the user.
9785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidFailProvisionalLoadWithError_Params params;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.error_code = net::ERR_ABORTED;
980a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  params.error_description = base::string16();
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = kNewURL;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.showing_repost_interstitial = false;
9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->OnMessageReceived(
9845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FrameHostMsg_DidFailProvisionalLoadWithError(0,  // routing_id
9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                   params));
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should not clear the pending entry or notify of a navigation state
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // change, so that we keep displaying kNewURL (until the user clears it).
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, delegate->navigation_state_change_count());
993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationEntry* pending_entry = controller.GetPendingEntry();
994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Ensure that a reload keeps the same pending entry.
996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.Reload(true);
997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(pending_entry, controller.GetPendingEntry());
1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetLastCommittedEntryIndex());
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(NULL);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the pending URL is not visible during a renderer-initiated
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// redirect and abort.  See http://crbug.com/83031.
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_RedirectAbortDoesntShowPendingURL) {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // First make an existing committed entry.
1013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kExistingURL("http://foo/eh");
1014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURL(kExistingURL, content::Referrer(),
10151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     ui::PAGE_TRANSITION_TYPED, std::string());
10161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  main_test_rfh()->SendNavigate(1, kExistingURL);
1017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1018868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
1019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a WebContentsDelegate to listen for state changes.
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(contents()->GetDelegate());
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(delegate.get());
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now make a pending new navigation, initiated by the renderer.
1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kNewURL("http://foo/bee");
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(kNewURL);
10281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_url_params.transition_type = ui::PAGE_TRANSITION_TYPED;
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
1034868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
1035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, delegate->navigation_state_change_count());
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1037868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The visible entry should be the last committed URL, not the pending one.
1038868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL());
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now the navigation redirects. (There is no corresponding message here.)
1041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kRedirectURL("http://foo/see");
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't want to change the NavigationEntry's url, in case it cancels.
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prevents regression of http://crbug.com/77786.
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kNewURL, controller.GetPendingEntry()->GetURL());
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It may abort before committing, if it's a download or due to a stop or
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a new navigation from the user.
10495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidFailProvisionalLoadWithError_Params params;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.error_code = net::ERR_ABORTED;
1051a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  params.error_description = base::string16();
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = kRedirectURL;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.showing_repost_interstitial = false;
10545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->OnMessageReceived(
10555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FrameHostMsg_DidFailProvisionalLoadWithError(0,  // routing_id
10565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                   params));
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Because the pending entry is renderer initiated and not visible, we
105958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // clear it when it fails.
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
106158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
1062868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
10630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1, delegate->navigation_state_change_count());
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The visible entry should be the last committed URL, not the pending one,
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // so that no spoof is possible.
1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(kExistingURL, controller.GetVisibleEntry()->GetURL());
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->SetDelegate(NULL);
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure that NavigationEntries track which bindings their RenderViewHost had
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// at the time they committed.  http://crbug.com/173672.
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NavigationControllerTest, LoadURL_WithBindings) {
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestNotificationTracker notifications;
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
1078effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<GURL> url_chain;
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url1("http://foo1");
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://foo2");
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to a first, unprivileged URL.
10841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
10851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::kInvalidBindings,
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                controller.GetPendingEntry())->bindings());
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Commit.
10916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* orig_rfh = contents()->GetMainFrame();
10926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  orig_rfh->SendNavigate(0, url1);
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Manually increase the number of active views in the SiteInstance
10996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // that orig_rfh belongs to, to prevent it from being destroyed when
11006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // it gets swapped out, so that we can reuse orig_rfh when the
11017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // controller goes back.
11026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static_cast<SiteInstanceImpl*>(orig_rfh->GetSiteInstance())->
11037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      increment_active_view_count();
11047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to a second URL, simulate the beforeunload ack for the cross-site
110603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // transition, and set bindings on the pending RenderViewHost to simulate a
110703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // privileged url.
11081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
11091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
11106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  orig_rfh->GetRenderViewHost()->SendBeforeUnloadACK(true);
11116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestRenderFrameHost* new_rfh = contents()->GetPendingMainFrame();
11126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  new_rfh->GetRenderViewHost()->AllowBindings(1);
11136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  new_rfh->SendNavigate(1, url2);
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second load should be committed, and bindings should be remembered.
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, NavigationEntryImpl::FromNavigationEntry(
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Going back, the first entry should still appear unprivileged.
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoBack();
11246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  new_rfh->GetRenderViewHost()->SendBeforeUnloadACK(true);
11256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  orig_rfh->SendNavigate(0, url1);
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, NavigationEntryImpl::FromNavigationEntry(
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetLastCommittedEntry())->bindings());
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Reload) {
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
11391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
11415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
11444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
11455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title"));
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.Reload(true);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const base::Time timestamp = controller.GetVisibleEntry()->GetTimestamp();
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(timestamp.is_null());
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The reload is pending.
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the title has been cleared (will be redrawn just after reload).
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoids a stale cached title when the new page being reloaded has no title.
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See http://crbug.com/96041.
11634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty());
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the reload is committed.
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The timestamp should have been updated.
11794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
11804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_GE(controller.GetVisibleEntry()->GetTimestamp(), timestamp);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when a reload navigation produces a new page.
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Reload_GeneratesNewPage) {
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
11931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
11945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.Reload(true);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the reload is committed.
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This test ensures that when a guest renderer reloads, the reload goes through
12165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// without ending up in the "we have a wrong process for the URL" branch in
12175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// NavigationControllerImpl::ReloadInternal.
12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, ReloadWithGuest) {
12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
12205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo1");
12221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
12231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
12245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(controller.GetVisibleEntry());
12265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make the entry believe its RenderProcessHost is a guest.
12285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationEntryImpl* entry1 =
12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetVisibleEntry());
12305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reinterpret_cast<MockRenderProcessHost*>(
1231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entry1->site_instance()->GetProcess())->set_is_isolated_guest(true);
12325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // And reload.
12345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.Reload(true);
12355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The reload is pending. Check that the NavigationEntry didn't get replaced
12375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // because of having the wrong process.
12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
12395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
12405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
12415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationEntryImpl* entry2 =
12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry());
12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(entry1, entry2);
12455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)  // http://crbug.com/157428
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) {
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL original_url("http://foo1");
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL final_url("http://foo2");
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load up the original URL, but get redirected.
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
12581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      original_url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
12605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithOriginalRequestURL(
12615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      0, final_url, original_url);
1262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NavigationEntry should save both the original URL and the final
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // redirected URL.
12674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(
12684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      original_url, controller.GetVisibleEntry()->GetOriginalRequestURL());
12694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(final_url, controller.GetVisibleEntry()->GetURL());
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reload using the original URL.
12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(base::ASCIIToUTF16("Title"));
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.ReloadOriginalRequestURL(false);
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The reload is pending.  The request should point to the original URL.
12774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(original_url, navigated_url());
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the title has been cleared (will be redrawn just after reload).
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoids a stale cached title when the new page being reloaded has no title.
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See http://crbug.com/96041.
12894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(controller.GetVisibleEntry()->GetTitle().empty());
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send that the navigation has proceeded; say it got redirected again.
12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, final_url);
1293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the reload is committed.
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(OS_ANDROID)
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Test that certain non-persisted NavigationEntryImpl values get reset after
13091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// commit.
13101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(NavigationControllerTest, ResetEntryValuesAfterCommit) {
13111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
13121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const GURL url1("http://foo1");
13131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
13141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
13151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Set up some sample values.
13171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const unsigned char* raw_data =
13181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      reinterpret_cast<const unsigned char*>("post\n\n\0data");
13191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int length = 11;
13201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<unsigned char> post_data_vector(raw_data, raw_data+length);
13211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<base::RefCountedBytes> post_data =
13221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::RefCountedBytes::TakeVector(&post_data_vector);
13231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  GlobalRequestID transfer_id(3, 4);
13241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::vector<GURL> redirects;
13251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  redirects.push_back(GURL("http://foo2"));
13261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Set non-persisted values on the pending entry.
13281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NavigationEntryImpl* pending_entry =
13291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry());
13301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->SetBrowserInitiatedPostData(post_data.get());
13311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_is_renderer_initiated(true);
13321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_transferred_global_request_id(transfer_id);
13331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_should_replace_entry(true);
13341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  pending_entry->set_should_clear_history_list(true);
13351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(post_data.get(), pending_entry->GetBrowserInitiatedPostData());
13361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(pending_entry->is_renderer_initiated());
13371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(transfer_id, pending_entry->transferred_global_request_id());
13381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(pending_entry->should_replace_entry());
13391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_TRUE(pending_entry->should_clear_history_list());
13401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
13421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Certain values that are only used for pending entries get reset after
13441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // commit.
13451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  NavigationEntryImpl* committed_entry =
13461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
13471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          controller.GetLastCommittedEntry());
13481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->GetBrowserInitiatedPostData());
13491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->is_renderer_initiated());
13501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(GlobalRequestID(-1, -1),
13511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            committed_entry->transferred_global_request_id());
13521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->should_replace_entry());
13531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_FALSE(committed_entry->should_clear_history_list());
13541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
13551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Test that Redirects are preserved after a commit.
13570529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(NavigationControllerTest, RedirectsAreNotResetByCommit) {
13580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NavigationControllerImpl& controller = controller_impl();
13590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const GURL url1("http://foo1");
13601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
13611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
13620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Set up some redirect values.
13640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<GURL> redirects;
13650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  redirects.push_back(GURL("http://foo2"));
13660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Set redirects on the pending entry.
13680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NavigationEntryImpl* pending_entry =
13690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry());
13700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pending_entry->SetRedirectChain(redirects);
13710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(1U, pending_entry->GetRedirectChain().size());
13720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(GURL("http://foo2"), pending_entry->GetRedirectChain()[0]);
13730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Normal navigation will preserve redirects in the committed entry.
13750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  main_test_rfh()->SendNavigateWithRedirects(0, url1, redirects);
13760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NavigationEntryImpl* committed_entry =
13770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      NavigationEntryImpl::FromNavigationEntry(
13780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          controller.GetLastCommittedEntry());
13790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(1U, committed_entry->GetRedirectChain().size());
13800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(GURL("http://foo2"), committed_entry->GetRedirectChain()[0]);
13810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
13820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when we navigate back successfully
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back) {
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
13905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
13955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should now have a pending navigation to go back.
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-1));
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(1));
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(2));  // Cannot go foward 2 steps.
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 1 should be on or after that of entry 0.
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(),
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(0)->GetTimestamp());
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
1420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The back navigation completed successfully.
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-1));
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(1));
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(2));  // Cannot go foward 2 steps.
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 0 should be on or after that of entry 1
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (since we went back to it).
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(),
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(1)->GetTimestamp());
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when a back navigation produces a new page.
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back_GeneratesNewPage) {
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
14521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
14535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
14581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
14595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should now have a pending navigation to go back.
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
1476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The back navigation resulted in a completely new navigation.
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(darin): perhaps this behavior will be confusing to users?
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 3);
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 2);
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Receives a back message when there is a new pending navigation entry.
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back_NewPending) {
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://foo1");
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://foo2");
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl3("http://foo3");
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigate two places so we have some back history.
15015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
1502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // controller.LoadURL(kUrl2, ui::PAGE_TRANSITION_TYPED);
15065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
1507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start a new pending navigation and go back before it commits.
15111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
15121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kUrl3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl3, controller.GetPendingEntry()->GetURL());
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The pending navigation should now be the "back" item and the new one
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be gone.
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntryIndex());
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl1, controller.GetPendingEntry()->GetURL());
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Receives a back message when there is a different renavigation already
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pending.
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Back_OtherBackPending) {
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://foo/1");
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://foo/2");
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl3("http://foo/3");
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigate three places so we have some back history.
15325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
15335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
15345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, kUrl3);
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // With nothing pending, say we get a navigation to the second entry.
15375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We know all the entries have the same site instance, so we can just grab
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a random one for looking up other entries.
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* site_instance =
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetLastCommittedEntry())->site_instance();
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // That second URL should be the last committed and it should have gotten the
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new title.
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl2, controller.GetEntryWithPageID(site_instance, 1)->GetURL());
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go forward to the last item again and say it was committed.
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
15535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, kUrl3);
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start going back one to the second page. It will be pending.
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetPendingEntryIndex());
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not synthesize a totally new back event to the first page. This will not
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // match the pending one.
15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The committed navigation should clear the pending entry.
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But the navigated entry should be the last committed.
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl1, controller.GetLastCommittedEntry()->GetURL());
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when we navigate forward successfully.
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Forward) {
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
15905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should now have a pending navigation to go forward.
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 1);
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(-1));
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-2));  // Cannot go back 2 steps.
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(1));
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 0 should be on or after that of entry 1
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (since we went back to it).
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(0)->GetTimestamp(),
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(1)->GetTimestamp());
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The forward navigation completed successfully.
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.CanGoToOffset(-1));
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(-2));  // Cannot go back 2 steps.
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoToOffset(1));
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp for entry 1 should be on or after that of entry 0
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (since we went forward to it).
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(controller.GetEntryAtIndex(1)->GetTimestamp(),
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetEntryAtIndex(0)->GetTimestamp());
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests what happens when a forward navigation produces a new page.
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Forward_GeneratesNewPage) {
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
1650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
16545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should now have a pending navigation to go forward.
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), 1);
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
1671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
1673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(notifications.Check1AndReset(NOTIFICATION_NAV_LIST_PRUNED));
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Two consequent navigation for the same URL entered in should be considered
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as SAME_PAGE navigation even when we are redirected to some other page.
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Redirect) {
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");  // Redirection target
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request
16951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
16961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
16995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
1700868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second request
17041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
17051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
17141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_SERVER_REDIRECT;
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo1"));
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo2"));
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
172090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
1725a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
1726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
1727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.type == NAVIGATION_TYPE_SAME_PAGE);
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
17364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Similar to Redirect above, but the first URL is requested by POST,
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the second URL is requested by GET. NavigationEntry::has_post_data_
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// must be cleared. http://crbug.com/21245
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, PostThenRedirect) {
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");  // Redirection target
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request as POST
17541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
17551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
17564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.GetVisibleEntry()->SetHasPostData(true);
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
17595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
1760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second request
17641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
17651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
17741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_SERVER_REDIRECT;
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo1"));
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo2"));
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
178090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
1785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
1786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
1787868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.type == NAVIGATION_TYPE_SAME_PAGE);
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
17964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
17974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry()->GetHasPostData());
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A redirect right off the bat should be a NEW_PAGE.
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ImmediateRedirect) {
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");  // Redirection target
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request
18131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
18141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
18184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
18231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_SERVER_REDIRECT;
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo1"));
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.redirects.push_back(GURL("http://foo2"));
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
182990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
1834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
1835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
1836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.type == NAVIGATION_TYPE_NEW_PAGE);
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
18454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigation via link click within a subframe. A new navigation entry
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be created.
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, NewSubframe) {
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
18595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1860868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
18645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
18671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_MANUAL_SUBFRAME;
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
187190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
1874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
1875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
1876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1877868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, details.previous_url);
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.is_in_page);
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.is_main_frame);
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The new entry should be appended.
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // New entry should refer to the new page, but the old URL (entries only
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reflect the toplevel URL).
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, details.entry->GetURL());
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(params.page_id, details.entry->GetPageID());
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some pages create a popup, then write an iframe into it. This causes a
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subframe navigation without having any committed entry. Such navigations
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// just get thrown on the ground, but we shouldn't crash.
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, SubframeOnEmptyPage) {
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigation controller currently has no entries.
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://foo2");
19015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url;
19041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
190890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
1911a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params,
1912a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              &details));
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Auto subframes are ones the page loads automatically like ads. They should
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not create new navigation entries.
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, AutoSubframe) {
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
19245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
19295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
19321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
193690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigating should do nothing.
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
1940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params,
1941a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              &details));
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should still be only one entry.
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests navigation and then going back to a subframe navigation.
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, BackSubframe) {
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Main page.
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
19565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
1957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First manual subframe navigation.
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
19625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
19651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_MANUAL_SUBFRAME;
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
196990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should generate a new entry.
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
1973a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
1974a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
1975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second manual subframe navigation should also make a new entry.
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 2;
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url3;
1983a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
1984a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
1985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1986868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back one.
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
1994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
1995a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
1996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
1997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
20002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
20012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back one more.
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url1;
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
2007a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
2008a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
2009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
20132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
20142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, LinkClick) {
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
2026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
2030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not have produced a new session history entry.
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 2);
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, InPage) {
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Main page.
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo");
20505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
2051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure main page navigation to same url respects the was_within_same_page
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hint provided in the params.
20565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params self_params;
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.page_id = 0;
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.url = url1;
20591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  self_params.transition = ui::PAGE_TRANSITION_LINK;
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.should_update_history = false;
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.gesture = NavigationGestureUser;
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.is_post = false;
206390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  self_params.page_state = PageState::CreateFromURL(url1);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self_params.was_within_same_page = true;
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
2067a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), self_params,
20685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
2069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.did_replace_entry);
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fragment navigation to a new page_id.
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo#a");
20775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 1;
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
20801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_LINK;
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
208490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
2085bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  params.was_within_same_page = true;
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should generate a new entry.
2088a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
2089a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
2090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.did_replace_entry);
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back one.
20975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params back_params(params);
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  back_params.url = url1;
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  back_params.page_id = 0;
2101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), back_params,
21025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
2103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
2105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(details.is_in_page);
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
21084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(back_params.url, controller.GetVisibleEntry()->GetURL());
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go forward
21115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params forward_params(params);
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  forward_params.url = url2;
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  forward_params.page_id = 1;
2115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), forward_params,
21165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
2117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(forward_params.url,
21234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            controller.GetVisibleEntry()->GetURL());
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go back and forward again. This is to work around a bug where we would
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // compare the incoming URL with the last committed entry rather than the
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one identified by an existing page ID. This would result in the second URL
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // losing the reference fragment when you navigate away from it and then back.
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
2130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), back_params,
21315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
2133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), forward_params,
21345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             &details));
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(forward_params.url,
21364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            controller.GetVisibleEntry()->GetURL());
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, navigate to an unrelated URL to make sure in_page is not sticky.
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://bar");
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 2;
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url3;
2142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
2143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
2144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
2145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(details.is_in_page);
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetCurrentEntryIndex());
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, InPage_Replace) {
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Main page.
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo");
21595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
2160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigation.
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo#a");
21655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;  // Same page_id
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url2;
21681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_LINK;
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
217290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url2);
217346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.was_within_same_page = true;
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should NOT generate a new entry, nor prune the list.
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
2177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
2178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             &details));
2179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
2180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.is_in_page);
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(details.did_replace_entry);
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests for http://crbug.com/40395
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulates this:
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   <script>
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     window.location.replace("#a");
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     window.location='http://foo3/';
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   </script>
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ClientRedirectAfterInPageNavigation) {
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load an initial page.
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo/");
22005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(0, url);
2201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a new page.
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo2/");
22085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(1, url);
2209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate within the page.
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo2/#a");
22165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FrameHostMsg_DidCommitProvisionalLoad_Params params;
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.page_id = 1;  // Same page_id
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.url = url;
22191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    params.transition = ui::PAGE_TRANSITION_LINK;
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.redirects.push_back(url);
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.should_update_history = true;
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.gesture = NavigationGestureUnknown;
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.is_post = false;
222490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    params.page_state = PageState::CreateFromURL(url);
222546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    params.was_within_same_page = true;
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This should NOT generate a new entry, nor prune the list.
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadCommittedDetails details;
2229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
2230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                               &details));
2231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(details.is_in_page);
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(details.did_replace_entry);
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, controller.GetEntryCount());
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Perform a client redirect to a new page.
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo3/");
22415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FrameHostMsg_DidCommitProvisionalLoad_Params params;
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.page_id = 2;  // New page_id
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.url = url;
22441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    params.transition = ui::PAGE_TRANSITION_CLIENT_REDIRECT;
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.redirects.push_back(GURL("http://foo2/#a"));
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.redirects.push_back(url);
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.should_update_history = true;
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.gesture = NavigationGestureUnknown;
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params.is_post = false;
225090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    params.page_state = PageState::CreateFromURL(url);
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This SHOULD generate a new entry.
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LoadCommittedDetails details;
2254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(controller.RendererDidNavigate(main_test_rfh(), params,
2255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                               &details));
2256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(details.is_in_page);
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3, controller.GetEntryCount());
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that BACK brings us back to http://foo2/.
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL url("http://foo2/");
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.GoBack();
22665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(1, url);
2267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_EQ(1U, navigation_entry_committed_counter_);
2268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    navigation_entry_committed_counter_ = 0;
22694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
227346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(NavigationControllerTest, PushStateWithoutPreviousEntry)
227446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){
227546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_FALSE(controller_impl().GetLastCommittedEntry());
227646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
227746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GURL url("http://foo");
227846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_id = 1;
227946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.url = url;
228046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
228146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.was_within_same_page = true;
228246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  test_rvh()->SendNavigateWithParams(&params);
228346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // We pass if we don't crash.
228446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
228546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NotificationObserver implementation used in verifying we've received the
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTIFICATION_NAV_LIST_PRUNED method.
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrunedListener : public NotificationObserver {
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit PrunedListener(NavigationControllerImpl* controller)
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : notification_count_(0) {
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(this, NOTIFICATION_NAV_LIST_PRUNED,
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   Source<NavigationController>(controller));
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const NotificationSource& source,
22982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const NotificationDetails& details) OVERRIDE {
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == NOTIFICATION_NAV_LIST_PRUNED) {
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      notification_count_++;
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      details_ = *(Details<PrunedDetails>(details).ptr());
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of times NAV_LIST_PRUNED has been observed.
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int notification_count_;
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Details from the last NAV_LIST_PRUNED.
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrunedDetails details_;
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationRegistrar registrar_;
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PrunedListener);
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we limit the number of navigation entries created correctly.
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, EnforceMaxNavigationCount) {
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t original_count = NavigationControllerImpl::max_entry_count();
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxEntryCount = 5;
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount);
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int url_index;
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load up to the max count, all entries should be there.
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (url_index = 0; url_index < kMaxEntryCount; url_index++) {
23282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GURL url(base::StringPrintf("http://www.a.com/%d", url_index));
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.LoadURL(
23301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
23315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(url_index, url);
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Created a PrunedListener to observe prune notifications.
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrunedListener listener(&controller);
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate some more.
23402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url(base::StringPrintf("http://www.a.com/%d", url_index));
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
23421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
23435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(url_index, url);
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  url_index++;
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have got a pruned navigation.
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.notification_count_);
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(listener.details_.from_front);
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.details_.count);
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We expect http://www.a.com/0 to be gone.
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(),
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GURL("http:////www.a.com/1"));
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More navigations.
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
23582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    url = GURL(base::StringPrintf("http:////www.a.com/%d", url_index));
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    controller.LoadURL(
23601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
23615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    main_test_rfh()->SendNavigate(url_index, url);
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_index++;
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), kMaxEntryCount);
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(),
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GURL("http:////www.a.com/4"));
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(original_count);
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can do a restore and navigate to the restored entries and
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything is updated properly. This can be tricky since there is no
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SiteInstance for the entries created initially.
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, RestoreNavigate) {
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a NavigationController with a restored set of tabs.
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://foo");
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<NavigationEntry*> entries;
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry(
23791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url, Referrer(), ui::PAGE_TRANSITION_RELOAD, false, std::string(),
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_context());
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->SetPageID(0);
23825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry->SetTitle(base::ASCIIToUTF16("Title"));
238390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  entry->SetPageState(PageState::CreateFromEncodedData("state"));
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Time timestamp = base::Time::Now();
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->SetTimestamp(timestamp);
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries.push_back(entry);
23872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>(
23882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContents::Create(WebContents::CreateParams(browser_context()))));
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& our_controller = our_contents->GetController();
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.Restore(
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &entries);
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, entries.size());
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before navigating to the restored entry, it should have a restore_type
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and no SiteInstance.
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, our_controller.GetEntryCount());
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY,
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(NavigationEntryImpl::FromNavigationEntry(
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After navigating, we should have one entry, and it should be "pending".
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should now have a SiteInstance and no restore_type.
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.GoToIndex(0);
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(our_controller.GetEntryAtIndex(0),
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            our_controller.GetPendingEntry());
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetEntryAtIndex(0)->GetPageID());
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                (our_controller.GetEntryAtIndex(0))->restore_type());
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NavigationEntryImpl::FromNavigationEntry(
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp should remain the same before the navigation finishes.
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(timestamp, our_controller.GetEntryAtIndex(0)->GetTimestamp());
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Say we navigated to that entry.
24225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url;
24251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_LINK;
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
242990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
2431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  our_controller.RendererDidNavigate(our_contents->GetMainFrame(), params,
24325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     &details);
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be no longer any pending entry and one committed one. This
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // means that we were able to locate the entry, assign its site instance, and
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // commit it properly.
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetLastCommittedEntryIndex());
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(our_controller.GetPendingEntry());
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url,
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetLastCommittedEntry())->site_instance()->
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    GetSiteURL());
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp should have been updated.
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(our_controller.GetEntryAtIndex(0)->GetTimestamp(), timestamp);
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can still navigate to a restored entry after a different
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation fails and clears the pending entry.  http://crbug.com/90085
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, RestoreNavigateAfterFailure) {
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a NavigationController with a restored set of tabs.
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url("http://foo");
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<NavigationEntry*> entries;
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry(
24591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url, Referrer(), ui::PAGE_TRANSITION_RELOAD, false, std::string(),
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_context());
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->SetPageID(0);
24625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry->SetTitle(base::ASCIIToUTF16("Title"));
246390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  entry->SetPageState(PageState::CreateFromEncodedData("state"));
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries.push_back(entry);
24652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebContentsImpl> our_contents(static_cast<WebContentsImpl*>(
24662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContents::Create(WebContents::CreateParams(browser_context()))));
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& our_controller = our_contents->GetController();
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.Restore(
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries);
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, entries.size());
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Before navigating to the restored entry, it should have a restore_type
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and no SiteInstance.
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY,
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(NavigationEntryImpl::FromNavigationEntry(
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After navigating, we should have one entry, and it should be "pending".
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should now have a SiteInstance and no restore_type.
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  our_controller.GoToIndex(0);
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(our_controller.GetEntryAtIndex(0),
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            our_controller.GetPendingEntry());
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetEntryAtIndex(0)->GetPageID());
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NavigationEntryImpl::FromNavigationEntry(
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      our_controller.GetEntryAtIndex(0))->site_instance());
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This pending navigation may have caused a different navigation to fail,
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which causes the pending entry to be cleared.
24955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidFailProvisionalLoadWithError_Params fail_load_params;
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.error_code = net::ERR_ABORTED;
2497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  fail_load_params.error_description = base::string16();
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.url = url;
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_load_params.showing_repost_interstitial = false;
25005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->OnMessageReceived(
25015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FrameHostMsg_DidFailProvisionalLoadWithError(0,  // routing_id
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  fail_load_params));
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the pending restored entry commits.
25055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url;
25081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_LINK;
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureUser;
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
251290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
2514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  our_controller.RendererDidNavigate(our_contents->GetMainFrame(), params,
2515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     &details);
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be no pending entry and one committed one.
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, our_controller.GetEntryCount());
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, our_controller.GetLastCommittedEntryIndex());
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(our_controller.GetPendingEntry());
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url,
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetLastCommittedEntry())->site_instance()->
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    GetSiteURL());
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE,
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NavigationEntryImpl::FromNavigationEntry(
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                our_controller.GetEntryAtIndex(0))->restore_type());
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that the page type and stuff is correct after an interstitial.
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, Interstitial) {
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First navigate somewhere normal.
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo");
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
25375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now navigate somewhere with an interstitial.
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://bar");
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_page_type(PAGE_TYPE_INTERSTITIAL);
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point the interstitial will be displayed and the load will still
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be pending. If the user continues, the load will commit.
25485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The page should be a normal page again.
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PAGE_TYPE_NORMAL,
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            controller.GetLastCommittedEntry()->GetPageType());
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, RemoveEntry) {
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url4("http://foo/4");
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url5("http://foo/5");
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL pending_url("http://foo/pending");
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL default_url("http://foo/default");
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
25685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
25715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url2);
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
25745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url4, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
25775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url4);
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
25791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url5, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
25805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(4, url5);
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try to remove the last entry.  Will fail because it is the current entry.
2583a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, controller.GetEntryCount());
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, controller.GetLastCommittedEntryIndex());
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2587a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Go back, but don't commit yet. Check that we can't delete the current
2588a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // and pending entries.
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
2590a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
2591a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_FALSE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 2));
2592a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
2593a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Now commit and delete the last entry.
25945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url4);
2595a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_TRUE(controller.RemoveEntryAtIndex(controller.GetEntryCount() - 1));
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, controller.GetEntryCount());
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetLastCommittedEntryIndex());
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove an entry which is not the last committed one.
2601a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  EXPECT_TRUE(controller.RemoveEntryAtIndex(0));
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, controller.GetLastCommittedEntryIndex());
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the 2 remaining entries.
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.RemoveEntryAtIndex(1);
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.RemoveEntryAtIndex(0);
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should leave us with only the last committed entry.
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the transient entry, making sure it goes away with all navigations.
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, TransientEntry) {
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
26252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url3_ref("http://foo/3#bar");
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url4("http://foo/4");
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL transient_url("http://foo/transient");
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
26301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url0, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
26315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url0);
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
26331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
26345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url1);
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notifications.Reset();
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adding a transient with no pending entry.
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* transient_entry = new NavigationEntryImpl;
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not have received any notifications.
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, notifications.size());
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check our state.
26474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 3);
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 1);
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetPendingEntryIndex(), -1);
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetLastCommittedEntry());
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(contents()->GetMaxPageID(), 1);
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate.
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
26591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
26605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url2);
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have navigated, transient entry should be gone.
26634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 3);
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient again, then navigate with no pending entry this time.
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (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);
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transient entry should be gone.
26734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL());
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 4);
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiate a navigation, add a transient then commit navigation.
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
26781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url4, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(4, url4);
26844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL());
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 5);
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go back.  This should simply remove the transient.
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
26902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
26914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoBack());
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transient entry should be gone.
26964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL());
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 5);
26985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url3);
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go to an entry before the current one.
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
27032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
27044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoToIndex(1);
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The navigation should have been initiated, transient entry should be gone.
27074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
27084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Visible entry does not update for history navigations until commit.
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL());
27115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url1);
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go to an entry after the current one.
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
27172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
27184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoToIndex(3);
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The navigation should have been initiated, transient entry should be gone.
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Because of the transient entry that is removed, going to index 3 makes us
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // land on url2 (which is visible after the commit).
27234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
27255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url2);
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a transient and go forward.
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry = new NavigationEntryImpl;
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
27312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
27324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.CanGoForward());
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have navigated, transient entry should be gone.
27364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
27374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url3, controller.GetPendingEntry()->GetURL());
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
27395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url3);
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, controller.GetVisibleEntry()->GetURL());
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add a transient and do an in-page navigation, replacing the current entry.
27432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transient_entry = new NavigationEntryImpl;
27442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transient_entry->SetURL(transient_url);
27452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
27464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(3, url3_ref);
27482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Transient entry should be gone.
27494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
27504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url3_ref, controller.GetVisibleEntry()->GetURL());
27512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the URLs are correct.
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 5);
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0);
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(1)->GetURL(), url1);
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(2)->GetURL(), url2);
27572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(3)->GetURL(), url3_ref);
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(4)->GetURL(), url4);
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Reload initiates a new navigation to a transient entry's URL.
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ReloadTransient) {
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL transient_url("http://foo/transient");
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load |url0|, and start a pending navigation to |url1|.
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
27701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url0, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
27715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url0);
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
27731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A transient entry is added, interrupting the navigation.
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* transient_entry = new NavigationEntryImpl;
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transient_entry->SetURL(transient_url);
27782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(transient_entry);
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetTransientEntry());
27804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The page is reloaded, which should remove the pending entry for |url1| and
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the transient entry for |transient_url|, and start a navigation to
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |transient_url|.
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.Reload(true);
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.GetTransientEntry());
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
27884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(transient_url, controller.GetVisibleEntry()->GetURL());
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(controller.GetEntryCount(), 1);
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0);
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load of |transient_url| completes.
27935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, transient_url);
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(controller.GetEntryCount(), 2);
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url0);
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(1)->GetURL(), transient_url);
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2799ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Ensure that renderer initiated pending entries get replaced, so that we
2800ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// don't show a stale virtual URL when a navigation commits.
2801ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// See http://crbug.com/266922.
2802ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
2803ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  NavigationControllerImpl& controller = controller_impl();
2804a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Navigator* navigator =
2805a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      contents()->GetFrameTree()->root()->navigator();
2806ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2807ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const GURL url1("nonexistent:12121");
2808ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const GURL url1_fixed("http://nonexistent:12121/");
2809ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const GURL url2("http://foo");
2810ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2811ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We create pending entries for renderer-initiated navigations so that we
2812ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // can show them in new tabs when it is safe.
28135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), url1, false);
2814ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2815ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Simulate what happens if a BrowserURLHandler rewrites the URL, causing
2816ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // the virtual URL to differ from the URL.
2817ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  controller.GetPendingEntry()->SetURL(url1_fixed);
2818ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  controller.GetPendingEntry()->SetVirtualURL(url1);
2819ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2820ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1_fixed, controller.GetPendingEntry()->GetURL());
2821ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1, controller.GetPendingEntry()->GetVirtualURL());
2822ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(
2823ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
2824ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          is_renderer_initiated());
2825ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2826ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // If the user clicks another link, we should replace the pending entry.
28275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), url2, false);
2828ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
2829ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetPendingEntry()->GetVirtualURL());
2830ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2831ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Once it commits, the URL and virtual URL should reflect the actual page.
28325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
2833ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
2834ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetVirtualURL());
2835ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
2836ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We should not replace the pending entry for an error URL.
28375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), url1, false);
2838ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
2839116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  navigator->DidStartProvisionalLoad(main_test_rfh(),
28405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     GURL(kUnreachableWebDataURL), false);
2841ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
28428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
28438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We should remember if the pending entry will replace the current one.
28448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // http://crbug.com/308444.
28455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), url1, false);
28468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
28478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      set_should_replace_entry(true);
28485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  navigator->DidStartProvisionalLoad(main_test_rfh(), url2, false);
28498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_TRUE(
28508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
28518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          should_replace_entry());
2852a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(nasko): Until OnNavigate is moved to RenderFrameHost, we need
2853a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to go through the RenderViewHost. The TestRenderViewHost routes navigations
2854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to the main frame.
28555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url2);
28568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
2857ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
2858ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the URLs for renderer-initiated navigations are not displayed to
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the user until the navigation commits, to prevent URL spoof attacks.
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/99016.
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, DontShowRendererURLUntilCommit) {
28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For typed navigations (browser-initiated), both pending and visible entries
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should update before commit.
28721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  controller.LoadURL(
28731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url0, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
28744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url0, controller.GetPendingEntry()->GetURL());
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, controller.GetVisibleEntry()->GetURL());
28765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url0);
28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // For link clicks (renderer-initiated navigations), the pending entry should
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // update before commit but the visible should not.
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(url1);
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url0, controller.GetVisibleEntry()->GetURL());
28844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_renderer_initiated());
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // After commit, both visible should be updated, there should be no pending
28904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // entry, and we should no longer treat the entry as renderer-initiated.
28915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url1);
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
28934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          controller.GetLastCommittedEntry())->is_renderer_initiated());
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notifications.Reset();
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Tests that the URLs for renderer-initiated navigations in new tabs are
2902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// displayed to the user before commit, as long as the initial about:blank
2903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// page has not been modified.  If so, we must revert to showing about:blank.
2904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// See http://crbug.com/9682.
2905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, ShowRendererURLInNewTabUntilModified) {
2906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
2907868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestNotificationTracker notifications;
2908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
2909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url("http://foo");
2911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // For renderer-initiated navigations in new tabs (with no committed entries),
2913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we show the pending entry's URL as long as the about:blank page is not
2914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // modified.
2915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(url);
29161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_url_params.transition_type = ui::PAGE_TRANSITION_LINK;
2917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
2918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
2919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
29204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
2921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(
2922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
2923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          is_renderer_initiated());
2924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.IsInitialNavigation());
29255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(contents()->HasAccessedInitialDocument());
2926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // There should be no title yet.
2928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(contents()->GetTitle().empty());
2929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // If something else modifies the contents of the about:blank page, then
2931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we must revert to showing about:blank to avoid a URL spoof.
29325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  main_test_rfh()->OnMessageReceived(FrameHostMsg_DidAccessInitialDocument(0));
29335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(contents()->HasAccessedInitialDocument());
2934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(controller.GetVisibleEntry());
29354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
2936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notifications.Reset();
2938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
29400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Tests that the URLs for browser-initiated navigations in new tabs are
29410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// displayed to the user even after they fail, as long as the initial
29420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// about:blank page has not been modified.  If so, we must revert to showing
29430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// about:blank. See http://crbug.com/355537.
29440529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(NavigationControllerTest, ShowBrowserURLAfterFailUntilModified) {
29450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NavigationControllerImpl& controller = controller_impl();
29460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestNotificationTracker notifications;
29470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegisterForAllNavNotifications(&notifications, &controller);
29480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
29490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const GURL url("http://foo");
29500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
29510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // For browser-initiated navigations in new tabs (with no committed entries),
29520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // we show the pending entry's URL as long as the about:blank page is not
29530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // modified.  This is possible in cases that the user types a URL into a popup
29540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // tab created with a slow URL.
29550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NavigationController::LoadURLParams load_url_params(url);
29561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_url_params.transition_type = ui::PAGE_TRANSITION_TYPED;
29570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  load_url_params.is_renderer_initiated = false;
29580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  controller.LoadURLWithParams(load_url_params);
29590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
29600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
29610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(
29620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
29630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          is_renderer_initiated());
29640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(controller.IsInitialNavigation());
29655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(contents()->HasAccessedInitialDocument());
29660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
29670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // There should be no title yet.
29680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(contents()->GetTitle().empty());
29690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
29700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Suppose it aborts before committing, if it's a 204 or download or due to a
29710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // stop or a new navigation from the user.  The URL should remain visible.
29720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FrameHostMsg_DidFailProvisionalLoadWithError_Params params;
29730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.error_code = net::ERR_ABORTED;
29740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.error_description = base::string16();
29750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.url = url;
29760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.showing_repost_interstitial = false;
29770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  main_test_rfh()->OnMessageReceived(
29780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FrameHostMsg_DidFailProvisionalLoadWithError(0, params));
29790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  contents()->SetIsLoading(test_rvh(), false, true, NULL);
29800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
29810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
29820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If something else later modifies the contents of the about:blank page, then
29830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // we must revert to showing about:blank to avoid a URL spoof.
29845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  main_test_rfh()->OnMessageReceived(FrameHostMsg_DidAccessInitialDocument(0));
29855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(contents()->HasAccessedInitialDocument());
29860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(controller.GetVisibleEntry());
29870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(controller.GetPendingEntry());
29880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
29890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  notifications.Reset();
29900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
29910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
29920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Tests that the URLs for renderer-initiated navigations in new tabs are
29930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// displayed to the user even after they fail, as long as the initial
29940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// about:blank page has not been modified.  If so, we must revert to showing
29950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// about:blank. See http://crbug.com/355537.
29960529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(NavigationControllerTest, ShowRendererURLAfterFailUntilModified) {
29970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NavigationControllerImpl& controller = controller_impl();
29980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestNotificationTracker notifications;
29990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RegisterForAllNavNotifications(&notifications, &controller);
30000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const GURL url("http://foo");
30020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // For renderer-initiated navigations in new tabs (with no committed entries),
30040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // we show the pending entry's URL as long as the about:blank page is not
30050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // modified.
30060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  NavigationController::LoadURLParams load_url_params(url);
30071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_url_params.transition_type = ui::PAGE_TRANSITION_LINK;
30080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  load_url_params.is_renderer_initiated = true;
30090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  controller.LoadURLWithParams(load_url_params);
30100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
30110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
30120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(
30130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
30140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          is_renderer_initiated());
30150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(controller.IsInitialNavigation());
30165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(contents()->HasAccessedInitialDocument());
30170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // There should be no title yet.
30190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(contents()->GetTitle().empty());
30200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Suppose it aborts before committing, if it's a 204 or download or due to a
30220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // stop or a new navigation from the user.  The URL should remain visible.
30230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FrameHostMsg_DidFailProvisionalLoadWithError_Params params;
30240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.error_code = net::ERR_ABORTED;
30250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.error_description = base::string16();
30260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.url = url;
30270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  params.showing_repost_interstitial = false;
30280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  main_test_rfh()->OnMessageReceived(
30290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FrameHostMsg_DidFailProvisionalLoadWithError(0, params));
30300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(url, controller.GetVisibleEntry()->GetURL());
30310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If something else later modifies the contents of the about:blank page, then
30330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // we must revert to showing about:blank to avoid a URL spoof.
30345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  main_test_rfh()->OnMessageReceived(FrameHostMsg_DidAccessInitialDocument(0));
30355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(contents()->HasAccessedInitialDocument());
30360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(controller.GetVisibleEntry());
30370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(url, controller.GetPendingEntry()->GetURL());
30380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
30390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  notifications.Reset();
30400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
30410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, DontShowRendererURLInNewTabAfterCommit) {
3043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TestNotificationTracker notifications;
3045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
3046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo/eh");
3048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo/bee");
3049868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // For renderer-initiated navigations in new tabs (with no committed entries),
3051868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // we show the pending entry's URL as long as the about:blank page is not
3052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // modified.
3053868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationController::LoadURLParams load_url_params(url1);
30541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_url_params.transition_type = ui::PAGE_TRANSITION_LINK;
3055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url_params.is_renderer_initiated = true;
3056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURLWithParams(load_url_params);
3057868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
3058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(
3059868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(controller.GetPendingEntry())->
3060868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          is_renderer_initiated());
3061868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.IsInitialNavigation());
30625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(contents()->HasAccessedInitialDocument());
3063868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3064868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Simulate a commit and then starting a new pending navigation.
30655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
3066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationController::LoadURLParams load_url2_params(url2);
30671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  load_url2_params.transition_type = ui::PAGE_TRANSITION_LINK;
3068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  load_url2_params.is_renderer_initiated = true;
3069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.LoadURLWithParams(load_url2_params);
3070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We should not consider this an initial navigation, and thus should
3072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // not show the pending URL.
30735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(contents()->HasAccessedInitialDocument());
3074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(controller.IsInitialNavigation());
3075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(controller.GetVisibleEntry());
3076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetVisibleEntry()->GetURL());
3077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  notifications.Reset();
3079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that IsInPageNavigation returns appropriate results.  Prevents
30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// regression for bug 1126349.
30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, IsInPageNavigation) {
30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com/home.html");
3086116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3087116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // If the renderer claims it performed an in-page navigation from
3088116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // about:blank, trust the renderer.
3089116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This can happen when an iframe is created and populated via
3090116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // document.write(), then tries to perform a fragment navigation.
3091116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(japhet): We should only trust the renderer if the about:blank
3092116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // was the first document in the given frame, but we don't have enough
3093116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // information to identify that case currently.
3094116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const GURL blank_url(url::kAboutBlankURL);
3095116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  main_test_rfh()->SendNavigate(0, blank_url);
3096116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(controller.IsURLInPageNavigation(url, true,
3097116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
3098116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3099116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Navigate to URL with no refs.
31005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url);
31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reloading the page is not an in-page navigation.
310346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(url, false,
3104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL other_url("http://www.google.com/add.html");
310646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(other_url, false,
3107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url_with_ref("http://www.google.com/home.html#my_ref");
310946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref, true,
3110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to URL with refs.
31135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, url_with_ref);
31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reloading the page is not an in-page navigation.
311646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(url_with_ref, false,
3117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
311846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(url, false,
3119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
312046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(other_url, false,
3121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL other_url_with_ref("http://www.google.com/home.html#my_other_ref");
312346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(controller.IsURLInPageNavigation(other_url_with_ref, true,
3124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
3125bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
3126bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Going to the same url again will be considered in-page
3127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // if the renderer says it is even if the navigation type isn't IN_PAGE.
3128bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(controller.IsURLInPageNavigation(url_with_ref, true,
3129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
3130bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
3131bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // Going back to the non ref url will be considered in-page if the navigation
3132bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  // type is IN_PAGE.
3133bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  EXPECT_TRUE(controller.IsURLInPageNavigation(url, true,
3134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
313546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
313646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // If the renderer says this is a same-origin in-page navigation, believe it.
313746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // This is the pushState/replaceState case.
313846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(controller.IsURLInPageNavigation(other_url, true,
3139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
314046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3141cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  // Test allow_universal_access_from_file_urls flag.
314246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const GURL different_origin_url("http://www.example.com");
3143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockRenderProcessHost* rph =
3144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      static_cast<MockRenderProcessHost*>(main_test_rfh()->GetProcess());
3145cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  WebPreferences prefs = test_rvh()->GetWebkitPreferences();
3146cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  prefs.allow_universal_access_from_file_urls = true;
3147cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  test_rvh()->UpdateWebkitPreferences(prefs);
3148cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  prefs = test_rvh()->GetWebkitPreferences();
3149cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  EXPECT_TRUE(prefs.allow_universal_access_from_file_urls);
3150cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  // Allow in page navigation if existing URL is file scheme.
3151cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  const GURL file_url("file:///foo/index.html");
3152cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  main_test_rfh()->SendNavigate(0, file_url);
3153cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  EXPECT_EQ(0, rph->bad_msg_count());
3154cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  EXPECT_TRUE(controller.IsURLInPageNavigation(different_origin_url, true,
3155cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu      main_test_rfh()));
3156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(0, rph->bad_msg_count());
3157cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  // Don't honor allow_universal_access_from_file_urls if existing URL is
3158cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  // not file scheme.
3159cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  main_test_rfh()->SendNavigate(0, url);
316046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(controller.IsURLInPageNavigation(different_origin_url, true,
3161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      main_test_rfh()));
3162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(1, rph->bad_msg_count());
3163cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu
3164cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  // Remove allow_universal_access_from_file_urls flag.
3165cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  prefs.allow_universal_access_from_file_urls = false;
3166cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  test_rvh()->UpdateWebkitPreferences(prefs);
3167cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  prefs = test_rvh()->GetWebkitPreferences();
3168cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  EXPECT_FALSE(prefs.allow_universal_access_from_file_urls);
3169cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu
3170cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  // Don't believe the renderer if it claims a cross-origin navigation is
3171cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  // in-page.
3172cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  EXPECT_EQ(1, rph->bad_msg_count());
3173cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  EXPECT_FALSE(controller.IsURLInPageNavigation(different_origin_url, true,
3174cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu      main_test_rfh()));
3175cebcd4cfff375dbdae8cf55d6148cf3dddd127d1ningxin.hu  EXPECT_EQ(2, rph->bad_msg_count());
31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some pages can have subframes with the same base URL (minus the reference) as
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the main page. Even though this is hard, it can happen, and we don't want
31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// these subframe navigations to affect the toplevel document. They should
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead be ignored.  http://crbug.com/5585
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, SameSubframe) {
31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate the main frame.
31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url("http://www.google.com/");
31865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url);
31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should be at the first navigation entry.
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate a subframe that would normally count as in-page.
31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL subframe("http://www.google.com/#");
31945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = 0;
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = subframe;
31971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
320190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(subframe);
32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
3203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params,
3204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              &details));
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nothing should have changed.
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryCount(), 1);
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that on cloning a WebContentsImpl and going back needs_reload is
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// false.
32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CloneAndGoBack) {
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
32175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 title(base::ASCIIToUTF16("Title"));
32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
32204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(title);
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, clone->GetController().GetEntryCount());
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(clone->GetController().NeedsReload());
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  clone->GetController().GoBack();
32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigating back should have triggered needs_reload_ to go false.
32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(clone->GetController().NeedsReload());
3230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Ensure that the pending URL and its title are visible.
3232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, clone->GetController().GetVisibleEntry()->GetURL());
3233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(title, clone->GetTitle());
3234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Make sure that reloading a cloned tab doesn't change its pending entry index.
3237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// See http://crbug.com/234491.
3238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CloneAndReload) {
3239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
32425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 title(base::ASCIIToUTF16("Title"));
3243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
32454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.GetVisibleEntry()->SetTitle(title);
3246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
3249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  clone->GetController().LoadIfNecessary();
3250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, clone->GetController().GetEntryCount());
3252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, clone->GetController().GetPendingEntryIndex());
3253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  clone->GetController().Reload(true);
3255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, clone->GetController().GetPendingEntryIndex());
32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that cloning a WebContentsImpl doesn't copy interstitials.
32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CloneOmitsInterstitials) {
32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add an interstitial entry.  Should be deleted with controller.
32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntryImpl* interstitial_entry = new NavigationEntryImpl();
32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  interstitial_entry->set_page_type(PAGE_TYPE_INTERSTITIAL);
32702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.SetTransientEntry(interstitial_entry);
32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WebContents> clone(controller.GetWebContents()->Clone());
32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, clone->GetController().GetEntryCount());
32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test requesting and triggering a lazy reload.
32784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(NavigationControllerTest, LazyReload) {
32794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
32804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const GURL url("http://foo");
32814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NavigateAndCommit(url);
32824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(controller.NeedsReload());
32834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
32844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Request a reload to happen when the controller becomes active (e.g. after
32854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // the renderer gets killed in background on Android).
32864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.SetNeedsReload();
32874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(controller.NeedsReload());
32884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
32894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set the controller as active, triggering the requested reload.
32904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  controller.SetActive(true);
32914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(controller.NeedsReload());
32924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
32934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests a subframe navigation while a toplevel navigation is pending.
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/43967
32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, SubframeWhilePending) {
32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the first page.
32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/");
33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start a pending load to a totally different page, but don't commit it.
33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://bar/");
33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.LoadURL(
33051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send a subframe update from the first page, as if one had just
33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // automatically loaded. Auto subframes don't increment the page ID.
33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1_sub("http://foo/subframe");
33105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.page_id = controller.GetLastCommittedEntry()->GetPageID();
33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.url = url1_sub;
33131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.should_update_history = false;
33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.gesture = NavigationGestureAuto;
33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.is_post = false;
331790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url1_sub);
33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadCommittedDetails details;
33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should return false meaning that nothing was actually updated.
3321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(controller.RendererDidNavigate(main_test_rfh(), params,
3322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              &details));
33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The notification should have updated the last committed one, and not
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pending load.
33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, controller.GetLastCommittedEntry()->GetURL());
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The active entry should be unchanged by the subframe load.
33294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url2, controller.GetVisibleEntry()->GetURL());
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test CopyStateFrom with 2 urls, the first selected and nothing in the target.
33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFrom) {
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_controller.CopyStateFrom(controller);
33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other_controller should now contain 2 urls.
33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should be looking at the first one.
33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, other_controller.GetCurrentEntryIndex());
33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is a different site than url1, so the IDs start again at 0.
33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID());
33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0));
33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Ensure the SessionStorageNamespaceMaps are the same size and have
3366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // the same partitons loaded.
3367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  //
3368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // TODO(ajwong): We should load a url from a different partition earlier
3369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // to make sure this map has more than one entry.
3370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const SessionStorageNamespaceMap& session_storage_namespace_map =
3371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      controller.GetSessionStorageNamespaceMap();
3372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const SessionStorageNamespaceMap& other_session_storage_namespace_map =
3373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      other_controller.GetSessionStorageNamespaceMap();
3374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  EXPECT_EQ(session_storage_namespace_map.size(),
3375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch            other_session_storage_namespace_map.size());
3376ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  for (SessionStorageNamespaceMap::const_iterator it =
3377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch           session_storage_namespace_map.begin();
3378ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch       it != session_storage_namespace_map.end();
3379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch       ++it) {
3380ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    SessionStorageNamespaceMap::const_iterator other =
3381ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        other_session_storage_namespace_map.find(it->first);
3382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    EXPECT_TRUE(other != other_session_storage_namespace_map.end());
3383ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests CopyStateFromAndPrune with 2 urls in source, 1 in dest.
33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPrune) {
33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First two entries should have the same SiteInstance.
33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0));
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance2 =
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1));
34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(instance1, instance2);
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, controller.GetEntryAtIndex(0)->GetPageID());
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryAtIndex(1)->GetPageID());
34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, contents()->GetMaxPageIDForSiteInstance(instance1));
34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
34135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other_controller should now contain the 3 urls: url1, url2 and url3.
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL());
34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetEntryAtIndex(1)->GetPageID());
34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A new SiteInstance in a different BrowsingInstance should be used for the
34295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // new tab.
34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance3 =
34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(instance3, instance1);
34335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(instance3->IsRelatedSiteInstance(instance1));
34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, other_contents->GetMaxPageIDForSiteInstance(instance1));
34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance3));
34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, the first selected and 1 entry in
34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the target.
34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPrune2) {
34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
3452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  contents()->CommitPendingNavigation();
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
3460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
34615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url3
34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
3466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(1, other_controller.GetCurrentEntryIndex());
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
3470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID());
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
3475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1));
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, the last selected and 2 entries in
34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the target.
34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPrune3) {
34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo2");
34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo3");
3486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url4("http://foo4");
3487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
3489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3491868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
3496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1)), 2,
3498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
34995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3500868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url2, url4
3502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
3504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
3505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
3508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL());
3509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
3514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, 2 entries in the target, with
3518868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// not the last entry selected in the target.
3519868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneNotLast) {
3520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
3523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url3("http://foo3");
3524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url4("http://foo4");
3525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
3527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3531868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
3534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_controller.GoBack();
3535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->CommitPendingNavigation();
3536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
3538868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
35395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url2, url3
3542868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
3544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
3545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
3548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL());
3549868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
3554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, the first selected and 1 entry plus
3558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// a pending entry in the target.
3559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneTargetPending) {
3560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
3563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url3("http://foo3");
3564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url4("http://foo4");
35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
3569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  contents()->CommitPendingNavigation();
35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_controller.LoadURL(
35761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url4, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
3577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
3579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
35805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain url1, url3, and a pending entry
3583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // for url4.
3584868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
3586868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
3587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
3590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // And there should be a pending entry for url4.
3592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(other_controller.GetPendingEntry());
3593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetPendingEntry()->GetURL());
3594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0));
3599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3601868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 1 url in the source, 1 entry and a pending
3603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// client redirect entry (with the same page ID) in the target.  This used to
3604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// crash because the last committed entry would be pruned but max_page_id
3605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// remembered the page ID (http://crbug.com/234809).
3606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneTargetPending2) {
3607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2a("http://foo2/a");
3610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2b("http://foo2/b");
36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3612868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3614868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3616868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url2a);
3618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Simulate a client redirect, which has the same page ID as entry 2a.
3619868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_controller.LoadURL(
36201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2b, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
3621868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_controller.GetPendingEntry()->SetPageID(
3622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetLastCommittedEntry()->GetPageID());
3623868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
3626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
36275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3628868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain url1, url2a, and a pending entry
3630868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // for url2b.
3631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
3633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetCurrentEntryIndex());
36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2a, other_controller.GetEntryAtIndex(1)->GetURL());
36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // And there should be a pending entry for url4.
36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(other_controller.GetPendingEntry());
3640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2b, other_controller.GetPendingEntry()->GetURL());
36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Let the pending entry commit.
3643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->CommitPendingNavigation();
36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the current tab.
36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SiteInstance* instance1 =
3648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1));
3649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
3650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
3651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Test CopyStateFromAndPrune with 2 urls, a back navigation pending in the
3653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// source, and 1 entry in the target. The back pending entry should be ignored.
3654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneSourcePending) {
3655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
3656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url1("http://foo1");
3657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url2("http://foo2");
3658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL url3("http://foo3");
3659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3660868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url1);
3661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigateAndCommit(url2);
3662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  controller.GoBack();
3663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
3665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
3666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
3667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
3668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
3669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
3670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
36715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
3672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // other_controller should now contain: url1, url2, url3
3674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
3676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
3677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
3679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
3680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(2)->GetURL());
3681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
3682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
3684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // from the current tab.
3685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SiteInstance* instance1 =
3686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(2));
36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance1));
36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests CopyStateFromAndPrune with 3 urls in source, 1 in dest,
36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when the max entry count is 3.  We should prune one entry.
36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneMaxEntries) {
36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t original_count = NavigationControllerImpl::max_entry_count();
36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxEntryCount = 3;
36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount);
36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url4("http://foo/4");
37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a PrunedListener to observe prune notifications.
37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrunedListener listener(&controller);
37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
37185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, false);
37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have received a pruned notification.
37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.notification_count_);
37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(listener.details_.from_front);
37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, listener.details_.count);
37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other_controller should now contain only 3 urls: url2, url3 and url4.
37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(0)->GetURL());
37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL());
37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetEntryAtIndex(0)->GetPageID());
37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, other_controller.GetEntryAtIndex(1)->GetPageID());
37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(original_count);
37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests CopyStateFromAndPrune with 2 urls in source, 1 in dest, with
37425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// replace_entry set to true.
37435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneReplaceEntry) {
37445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
37455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo/1");
37465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url2("http://foo/2");
37475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url3("http://foo/3");
37485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url1);
37505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url2);
37515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // First two entries should have the same SiteInstance.
37535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SiteInstance* instance1 =
37545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0));
37555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SiteInstance* instance2 =
37565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1));
37575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(instance1, instance2);
37585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, controller.GetEntryAtIndex(0)->GetPageID());
37595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryAtIndex(1)->GetPageID());
37605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, contents()->GetMaxPageIDForSiteInstance(instance1));
37615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
37635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
37645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
37655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->NavigateAndCommit(url3);
37665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
37675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 1,
37685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
37695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, true);
37705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // other_controller should now contain the 2 urls: url1 and url3.
37725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetEntryCount());
37745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1, other_controller.GetCurrentEntryIndex());
37765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
37785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url3, other_controller.GetEntryAtIndex(1)->GetURL());
37795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
37805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(1)->GetPageID());
37815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A new SiteInstance in a different BrowsingInstance should be used for the
37835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // new tab.
37845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SiteInstance* instance3 =
37855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(1));
37865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_NE(instance3, instance1);
37875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(instance3->IsRelatedSiteInstance(instance1));
37885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The max page ID map should be copied over and updated with the max page ID
37905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // from the current tab.
37915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, other_contents->GetMaxPageIDForSiteInstance(instance1));
37925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_contents->GetMaxPageIDForSiteInstance(instance3));
37935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
37945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests CopyStateFromAndPrune with 3 urls in source, 1 in dest, when the max
37965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// entry count is 3 and replace_entry is true.  We should not prune entries.
37975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(NavigationControllerTest, CopyStateFromAndPruneMaxEntriesReplaceEntry) {
37985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
37995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t original_count = NavigationControllerImpl::max_entry_count();
38005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kMaxEntryCount = 3;
38015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(kMaxEntryCount);
38035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url1("http://foo/1");
38055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url2("http://foo/2");
38065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url3("http://foo/3");
38075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const GURL url4("http://foo/4");
38085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create a PrunedListener to observe prune notifications.
38105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrunedListener listener(&controller);
38115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url1);
38135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url2);
38145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateAndCommit(url3);
38155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<TestWebContents> other_contents(
38175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      static_cast<TestWebContents*>(CreateTestWebContents()));
38185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl& other_controller = other_contents->GetController();
38195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->NavigateAndCommit(url4);
38205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_contents->ExpectSetHistoryLengthAndPrune(
38215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetSiteInstanceFromEntry(other_controller.GetEntryAtIndex(0)), 2,
38225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      other_controller.GetEntryAtIndex(0)->GetPageID());
38235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  other_controller.CopyStateFromAndPrune(&controller, true);
38245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We should have received no pruned notification.
38265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, listener.notification_count_);
38275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // other_controller should now contain only 3 urls: url1, url2 and url4.
38295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(3, other_controller.GetEntryCount());
38315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2, other_controller.GetCurrentEntryIndex());
38335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url1, other_controller.GetEntryAtIndex(0)->GetURL());
38355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url2, other_controller.GetEntryAtIndex(1)->GetURL());
38365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(url4, other_controller.GetEntryAtIndex(2)->GetURL());
38375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(0)->GetPageID());
38385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, other_controller.GetEntryAtIndex(1)->GetPageID());
38395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, other_controller.GetEntryAtIndex(2)->GetPageID());
38405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigationControllerImpl::set_max_entry_count_for_testing(original_count);
38425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
38435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Tests that we can navigate to the restored entries
38455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// imported by CopyStateFromAndPrune.
38465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(NavigationControllerTest, CopyRestoredStateAndNavigate) {
38475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const GURL kRestoredUrls[] = {
38485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GURL("http://site1.com"),
38495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GURL("http://site2.com"),
38505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  };
38515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const GURL kInitialUrl("http://site3.com");
38525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
38535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::vector<NavigationEntry*> entries;
38545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (size_t i = 0; i < arraysize(kRestoredUrls); ++i) {
38555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NavigationEntry* entry = NavigationControllerImpl::CreateNavigationEntry(
38561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        kRestoredUrls[i], Referrer(), ui::PAGE_TRANSITION_RELOAD, false,
38575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        std::string(), browser_context());
38585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    entry->SetPageID(static_cast<int>(i));
38595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    entries.push_back(entry);
38605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
38615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
38625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Create a WebContents with restored entries.
38635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<TestWebContents> source_contents(
38645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      static_cast<TestWebContents*>(CreateTestWebContents()));
38655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  NavigationControllerImpl& source_controller =
38665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      source_contents->GetController();
38675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  source_controller.Restore(
38685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      entries.size() - 1,
38695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
38705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      &entries);
38715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_EQ(0u, entries.size());
38725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  source_controller.LoadIfNecessary();
38735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  source_contents->CommitPendingNavigation();
38745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
38755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Load a page, then copy state from |source_contents|.
38765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  NavigateAndCommit(kInitialUrl);
38775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  contents()->ExpectSetHistoryLengthAndPrune(
38785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetSiteInstanceFromEntry(controller_impl().GetEntryAtIndex(0)), 2,
38795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      controller_impl().GetEntryAtIndex(0)->GetPageID());
38805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  controller_impl().CopyStateFromAndPrune(&source_controller, false);
38815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_EQ(3, controller_impl().GetEntryCount());
38825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
38835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Go back to the first entry one at a time and
38845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // verify that it works as expected.
38855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(2, controller_impl().GetCurrentEntryIndex());
38865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(kInitialUrl, controller_impl().GetActiveEntry()->GetURL());
38875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
38885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  controller_impl().GoBack();
38895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  contents()->CommitPendingNavigation();
38905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(1, controller_impl().GetCurrentEntryIndex());
38915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(kRestoredUrls[1], controller_impl().GetActiveEntry()->GetURL());
38925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
38935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  controller_impl().GoBack();
38945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  contents()->CommitPendingNavigation();
38955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(0, controller_impl().GetCurrentEntryIndex());
38965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(kRestoredUrls[0], controller_impl().GetActiveEntry()->GetURL());
38975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
38985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that navigations initiated from the page (with the history object)
3900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// work as expected, creating pending entries.
39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, HistoryNavigate) {
39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3913a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Simulate the page calling history.back(). It should create a pending entry.
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->OnGoToEntryAtOffset(-1);
3915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, controller.GetPendingEntryIndex());
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual cross-navigation is suspended until the current RVH tells us
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it unloaded, simulate that.
39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also make sure we told the page to navigate.
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const IPC::Message* message =
39215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID);
39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message != NULL);
39235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Tuple1<FrameMsg_Navigate_Params> nav_params;
39245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameMsg_Navigate::Read(message, &nav_params);
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url1, nav_params.a.url);
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process()->sink().ClearMessages();
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now test history.forward()
3929a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  contents()->OnGoToEntryAtOffset(2);
3930a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, controller.GetPendingEntryIndex());
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual cross-navigation is suspended until the current RVH tells us
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it unloaded, simulate that.
39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->ProceedWithCrossSiteNavigation();
39345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message = process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID);
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(message != NULL);
39365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameMsg_Navigate::Read(message, &nav_params);
39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(url3, nav_params.a.url);
39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process()->sink().ClearMessages();
39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  controller.DiscardNonCommittedEntries();
3941a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure an extravagant history.go() doesn't break.
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->OnGoToEntryAtOffset(120);  // Out of bounds.
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
39455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  message = process()->sink().GetFirstMessageMatching(FrameMsg_Navigate::ID);
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(message == NULL);
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3949f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for the only entry.
3950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForSingle) {
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
39542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
39562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0)), 0,
39572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(0)->GetPageID());
39582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url1);
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for first entry.
3966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForFirst) {
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
39802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(0)), 0,
39812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(0)->GetPageID());
39822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url1);
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for intermediate entry.
3990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForIntermediate) {
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url2("http://foo/2");
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url3("http://foo/3");
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url2);
39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url3);
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
40032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSiteInstanceFromEntry(controller.GetEntryAtIndex(1)), 0,
40042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(1)->GetPageID());
40052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(controller.GetEntryAtIndex(0)->GetURL(), url2);
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test call to PruneAllButLastCommitted for a pending entry that is not yet in
4013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the list of entries.
4014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(NavigationControllerTest, PruneAllButLastCommittedForPendingNotInList) {
40152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
40162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url1("http://foo/1");
40172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://foo/2");
40182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url3("http://foo/3");
40192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateAndCommit(url1);
40212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateAndCommit(url2);
40222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a pending entry that is not in the entry list.
40242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
40251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
40262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
40272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
40282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->ExpectSetHistoryLengthAndPrune(
40302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL, 0, controller.GetPendingEntry()->GetPageID());
4031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  controller.PruneAllButLastCommitted();
40322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4033868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We should only have the last committed and pending entries at this point,
4034868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and the pending entry should still not be in the entry list.
4035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
4036868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url2, controller.GetEntryAtIndex(0)->GetURL());
40372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
40382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(controller.GetPendingEntry());
4039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
40402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to commit the pending entry.
40425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(2, url3);
40432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
40442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(controller.GetPendingEntry());
4045868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, controller.GetEntryCount());
4046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(url3, controller.GetEntryAtIndex(1)->GetURL());
40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test to ensure that when we do a history navigation back to the current
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// committed page (e.g., going forward to a slow-loading page, then pressing
40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the back button), we just stop the navigation to prevent the throbber from
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// running continuously. Otherwise, the RenderViewHost forces the throbber to
40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// start, but WebKit essentially ignores the navigation and never sends a
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message to stop the throbber.
40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, StopOnHistoryNavigationToCurrentPage) {
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url0("http://foo/0");
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo/1");
40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url0);
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateAndCommit(url1);
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go back to the original page, then forward to the slow page, then back
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  contents()->CommitPendingNavigation();
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoForward();
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, controller.GetPendingEntryIndex());
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller.GoBack();
40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, IsInitialNavigation) {
40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initial state.
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(controller.IsInitialNavigation());
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After commit, it stays false.
40835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL url1("http://foo1");
40845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, url1);
4085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
4086868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(controller.IsInitialNavigation());
40882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After starting a new navigation, it stays false.
40902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL url2("http://foo2");
40912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.LoadURL(
40921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that the favicon is not reused across a client redirect.
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (crbug.com/28515)
40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, ClearFaviconOnRedirect) {
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kPageWithFavicon("http://withfavicon.html");
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kPageWithoutFavicon("http://withoutfavicon.html");
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kIconURL("http://withfavicon.ico");
41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Image kDefaultFavicon = FaviconStatus().image;
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kPageWithFavicon);
4108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
4109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* entry = controller.GetLastCommittedEntry();
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPageWithFavicon, entry->GetURL());
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate Chromium having set the favicon for |kPageWithFavicon|.
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::FaviconStatus& favicon_status = entry->GetFavicon();
41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.image = CreateImage(SK_ColorWHITE);
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.url = kIconURL;
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.valid = true;
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image));
41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithTransition(
41232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      0,  // same page ID.
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPageWithoutFavicon,
41251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::PAGE_TRANSITION_CLIENT_REDIRECT);
4126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
4127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller.GetLastCommittedEntry();
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kPageWithoutFavicon, entry->GetURL());
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(DoImagesMatch(kDefaultFavicon, entry->GetFavicon().image));
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that the favicon is not cleared for NavigationEntries which were
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// previously navigated to.
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(NavigationControllerTest, BackNavigationDoesNotClearFavicon) {
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl1("http://www.a.com/1");
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kUrl2("http://www.a.com/2");
41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kIconURL("http://www.a.com/1/favicon.ico");
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestNotificationTracker notifications;
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisterForAllNavNotifications(&notifications, &controller);
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(0, kUrl1);
4148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
4149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate Chromium having set the favicon for |kUrl1|.
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image favicon_image = CreateImage(SK_ColorWHITE);
41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NavigationEntry* entry = controller.GetLastCommittedEntry();
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::FaviconStatus& favicon_status = entry->GetFavicon();
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.image = favicon_image;
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.url = kIconURL;
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  favicon_status.valid = true;
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to another page and go back to the original page.
41615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigate(1, kUrl2);
4162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
4163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
41645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  main_test_rfh()->SendNavigateWithTransition(
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUrl1,
41671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::PAGE_TRANSITION_FORWARD_BACK);
4168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1U, navigation_entry_committed_counter_);
4169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  navigation_entry_committed_counter_ = 0;
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the favicon for the page at |kUrl1| was not cleared.
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry = controller.GetEntryAtIndex(0);
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(entry);
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUrl1, entry->GetURL());
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(DoImagesMatch(favicon_image, entry->GetFavicon().image));
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The test crashes on android: http://crbug.com/170449
41792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
41802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_PurgeScreenshot DISABLED_PurgeScreenshot
41812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
41822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_PurgeScreenshot PurgeScreenshot
41832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
41842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that screenshot are purged correctly.
41852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(NavigationControllerTest, MAYBE_PurgeScreenshot) {
41862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
41872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationEntryImpl* entry;
41892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate enough times to make sure that some screenshots are purged.
41912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 12; ++i) {
41922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL url(base::StringPrintf("http://foo%d/", i));
41932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NavigateAndCommit(url);
41942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(i, controller.GetCurrentEntryIndex());
41952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
41962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockScreenshotManager* screenshot_manager =
4198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new MockScreenshotManager(&controller);
4199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller.SetScreenshotManager(screenshot_manager);
42002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount(); ++i) {
42012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
4203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
42047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(entry->screenshot().get());
42052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateAndCommit(GURL("https://foo/"));
42082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(13, controller.GetEntryCount());
42092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry = NavigationEntryImpl::FromNavigationEntry(
42102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller.GetEntryAtIndex(11));
4211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  screenshot_manager->TakeScreenshotFor(entry);
42122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; ++i) {
42142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
42167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
42177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not purged";
42182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 2; i < controller.GetEntryCount() - 1; ++i) {
42212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
42237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(entry->screenshot().get()) << "Screenshot not found for " << i;
42242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to index 5 and then try to assign screenshot to all entries.
42272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoToIndex(5);
42282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->CommitPendingNavigation();
42292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(5, controller.GetCurrentEntryIndex());
42302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount() - 1; ++i) {
42312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
4233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
42342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 10; i <= 12; ++i) {
42372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
42397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
42407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not purged";
4241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
42422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Navigate to index 7 and assign screenshot to all entries.
42452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.GoToIndex(7);
42462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents()->CommitPendingNavigation();
42472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(7, controller.GetCurrentEntryIndex());
42482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount() - 1; ++i) {
42492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
4251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screenshot_manager->TakeScreenshotFor(entry);
42522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 2; ++i) {
42552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
42577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
42587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not purged";
42592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear all screenshots.
42622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(13, controller.GetEntryCount());
4263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(10, screenshot_manager->GetScreenshotCount());
42642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller.ClearAllScreenshots();
4265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, screenshot_manager->GetScreenshotCount());
42662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < controller.GetEntryCount(); ++i) {
42672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    entry = NavigationEntryImpl::FromNavigationEntry(
42682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        controller.GetEntryAtIndex(i));
42697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i
42707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            << " not cleared";
42712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
42722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
42732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(NavigationControllerTest, PushStateUpdatesTitleAndFavicon) {
42756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Navigate.
427646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  test_rvh()->SendNavigate(1, GURL("http://foo"));
427746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
42786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Set title and favicon.
427946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::string16 title(base::ASCIIToUTF16("Title"));
42806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  FaviconStatus favicon;
42816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  favicon.valid = true;
42826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  favicon.url = GURL("http://foo/favicon.ico");
428346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  controller().GetLastCommittedEntry()->SetTitle(title);
42846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  controller().GetLastCommittedEntry()->GetFavicon() = favicon;
428546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
428646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // history.pushState() is called.
428746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
428846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GURL url("http://foo#foo");
428946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_id = 2;
429046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.url = url;
429146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
429246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.was_within_same_page = true;
429346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  test_rvh()->SendNavigateWithParams(&params);
429446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
429546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The title should immediately be visible on the new NavigationEntry.
429646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::string16 new_title =
429746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      controller().GetLastCommittedEntry()->GetTitleForDisplay(std::string());
429846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(title, new_title);
42996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  FaviconStatus new_favicon =
43006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      controller().GetLastCommittedEntry()->GetFavicon();
43016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(favicon.valid, new_favicon.valid);
43026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(favicon.url, new_favicon.url);
430346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
430446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test that the navigation controller clears its session history when a
4306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// navigation commits with the clear history list flag set.
4307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(NavigationControllerTest, ClearHistoryList) {
4308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url1("http://foo1");
4309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url2("http://foo2");
4310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url3("http://foo3");
4311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL url4("http://foo4");
4312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationControllerImpl& controller = controller_impl();
4314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a session history with three entries, second entry is active.
4316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateAndCommit(url1);
4317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateAndCommit(url2);
4318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateAndCommit(url3);
4319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller.GoBack();
4320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  contents()->CommitPendingNavigation();
4321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3, controller.GetEntryCount());
4322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, controller.GetCurrentEntryIndex());
4323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a new pending navigation, and indicate that the session history
4325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // should be cleared.
4326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationController::LoadURLParams params(url4);
4327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  params.should_clear_history_list = true;
4328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller.LoadURLWithParams(params);
4329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that the pending entry correctly indicates that the session history
4331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // should be cleared.
4332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationEntryImpl* entry =
4333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NavigationEntryImpl::FromNavigationEntry(
4334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          controller.GetPendingEntry());
4335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(entry);
4336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(entry->should_clear_history_list());
4337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Assume that the RV correctly cleared its history and commit the navigation.
43396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  contents()->GetPendingMainFrame()->GetRenderViewHost()->
4340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      set_simulate_history_list_was_cleared(true);
4341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  contents()->CommitPendingNavigation();
4342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify that the NavigationController's session history was correctly
4344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // cleared.
4345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, controller.GetEntryCount());
4346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, controller.GetCurrentEntryIndex());
4347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
4348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(-1, controller.GetPendingEntryIndex());
4349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoBack());
4350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(controller.CanGoForward());
43514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(url4, controller.GetVisibleEntry()->GetURL());
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(NavigationControllerTest, PostThenReplaceStateThenReload) {
435546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<TestWebContentsDelegate> delegate(new TestWebContentsDelegate());
435646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(contents()->GetDelegate());
435746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  contents()->SetDelegate(delegate.get());
435846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
435946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Submit a form.
436046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GURL url("http://foo");
436146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FrameHostMsg_DidCommitProvisionalLoad_Params params;
436246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_id = 1;
436346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.url = url;
43641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_FORM_SUBMIT;
436546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.gesture = NavigationGestureUser;
436646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(url);
436746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.was_within_same_page = false;
436846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.is_post = true;
436946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.post_id = 2;
437046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  test_rvh()->SendNavigateWithParams(&params);
437146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
437246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // history.replaceState() is called.
437346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GURL replace_url("http://foo#foo");
437446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_id = 1;
437546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.url = replace_url;
43761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  params.transition = ui::PAGE_TRANSITION_LINK;
437746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.gesture = NavigationGestureUser;
437846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.page_state = PageState::CreateFromURL(replace_url);
437946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.was_within_same_page = true;
438046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.is_post = false;
438146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  params.post_id = -1;
438246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  test_rvh()->SendNavigateWithParams(&params);
438346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
438446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Now reload. replaceState overrides the POST, so we should not show a
438546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // repost warning dialog.
438646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  controller_impl().Reload(true);
438746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(0, delegate->repost_form_warning_count());
438846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
438946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
4391