overscroll_navigation_overlay_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
6
7#include "content/browser/frame_host/navigation_entry_impl.h"
8#include "content/browser/web_contents/aura/image_window_delegate.h"
9#include "content/browser/web_contents/web_contents_view.h"
10#include "content/common/view_messages.h"
11#include "content/public/test/mock_render_process_host.h"
12#include "content/test/test_render_view_host.h"
13#include "content/test/test_web_contents.h"
14#include "ui/aura/test/test_windows.h"
15#include "ui/aura/window.h"
16#include "ui/gfx/codec/png_codec.h"
17
18namespace content {
19
20class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness {
21 public:
22  OverscrollNavigationOverlayTest() {}
23  virtual ~OverscrollNavigationOverlayTest() {}
24
25  gfx::Image CreateDummyScreenshot() {
26    SkBitmap bitmap;
27    bitmap.allocN32Pixels(1, 1);
28    bitmap.eraseColor(SK_ColorWHITE);
29    return gfx::Image::CreateFrom1xBitmap(bitmap);
30  }
31
32  void SetDummyScreenshotOnNavEntry(NavigationEntry* entry) {
33    SkBitmap bitmap;
34    bitmap.allocN32Pixels(1, 1);
35    bitmap.eraseColor(SK_ColorWHITE);
36    std::vector<unsigned char> png_data;
37    gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data);
38    scoped_refptr<base::RefCountedBytes> png_bytes =
39        base::RefCountedBytes::TakeVector(&png_data);
40    NavigationEntryImpl* entry_impl =
41        NavigationEntryImpl::FromNavigationEntry(entry);
42    entry_impl->SetScreenshotPNGData(png_bytes);
43  }
44
45  void ReceivePaintUpdate() {
46    ViewHostMsg_DidFirstVisuallyNonEmptyPaint msg(test_rvh()->GetRoutingID());
47    RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg);
48  }
49
50  void PerformBackNavigationViaSliderCallbacks() {
51    // Sets slide direction to SLIDE_BACK, sets screenshot from NavEntry at
52    // offset -1  on layer_delegate_.
53    delete GetOverlay()->CreateBackLayer();
54    // Performs BACK navigation, sets image from layer_delegate_ on
55    // image_delegate_.
56    GetOverlay()->OnWindowSlideCompleting();
57    GetOverlay()->OnWindowSlideCompleted(scoped_ptr<ui::Layer>());
58  }
59
60 protected:
61  // RenderViewHostImplTestHarness:
62  virtual void SetUp() OVERRIDE {
63    RenderViewHostImplTestHarness::SetUp();
64
65    const GURL first("https://www.google.com");
66    contents()->NavigateAndCommit(first);
67    EXPECT_TRUE(controller().GetVisibleEntry());
68    EXPECT_FALSE(controller().CanGoBack());
69
70    const GURL second("http://www.chromium.org");
71    contents()->NavigateAndCommit(second);
72    EXPECT_TRUE(controller().CanGoBack());
73
74    // Receive a paint update. This is necessary to make sure the size is set
75    // correctly in RenderWidgetHostImpl.
76    ViewHostMsg_UpdateRect_Params params;
77    memset(&params, 0, sizeof(params));
78    params.view_size = gfx::Size(10, 10);
79    ViewHostMsg_UpdateRect rect(test_rvh()->GetRoutingID(), params);
80    RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect);
81
82    // Reset pending flags for size/paint.
83    test_rvh()->ResetSizeAndRepaintPendingFlags();
84
85    // Create the overlay, and set the contents of the overlay window.
86    overlay_.reset(new OverscrollNavigationOverlay(contents()));
87    ImageWindowDelegate* image_delegate = new ImageWindowDelegate();
88    scoped_ptr<aura::Window> overlay_window(
89      aura::test::CreateTestWindowWithDelegate(
90          image_delegate,
91          0,
92          gfx::Rect(root_window()->bounds().size()),
93          root_window()));
94
95    overlay_->SetOverlayWindow(overlay_window.Pass(), image_delegate);
96    overlay_->StartObserving();
97
98    EXPECT_TRUE(overlay_->web_contents());
99    EXPECT_FALSE(overlay_->loading_complete_);
100    EXPECT_FALSE(overlay_->received_paint_update_);
101  }
102
103  virtual void TearDown() OVERRIDE {
104    overlay_.reset();
105    RenderViewHostImplTestHarness::TearDown();
106  }
107
108  OverscrollNavigationOverlay* GetOverlay() {
109    return overlay_.get();
110  }
111
112 private:
113  scoped_ptr<OverscrollNavigationOverlay> overlay_;
114
115  DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest);
116};
117
118TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_NoImage) {
119  ReceivePaintUpdate();
120  EXPECT_TRUE(GetOverlay()->received_paint_update_);
121  EXPECT_FALSE(GetOverlay()->loading_complete_);
122  // The paint update will hide the overlay.
123  EXPECT_FALSE(GetOverlay()->web_contents());
124}
125
126TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_WithImage) {
127  GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
128
129  ReceivePaintUpdate();
130  EXPECT_TRUE(GetOverlay()->received_paint_update_);
131  EXPECT_FALSE(GetOverlay()->loading_complete_);
132  // The paint update will hide the overlay.
133  EXPECT_FALSE(GetOverlay()->web_contents());
134}
135
136TEST_F(OverscrollNavigationOverlayTest, LoadUpdateWithoutNonEmptyPaint) {
137  GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
138  process()->sink().ClearMessages();
139
140  contents()->TestSetIsLoading(false);
141  EXPECT_TRUE(GetOverlay()->loading_complete_);
142  EXPECT_FALSE(GetOverlay()->received_paint_update_);
143  // The page load should hide the overlay.
144  EXPECT_FALSE(GetOverlay()->web_contents());
145}
146
147TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_PaintUpdate) {
148  GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
149  SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1));
150
151  PerformBackNavigationViaSliderCallbacks();
152  // Screenshot was set on NavEntry at offset -1.
153  EXPECT_TRUE(GetOverlay()->image_delegate_->has_image());
154  EXPECT_FALSE(GetOverlay()->received_paint_update_);
155
156  ReceivePaintUpdate();
157  // Paint updates until the navigation is committed represent updates
158  // for the previous page, so they shouldn't affect the flag.
159  EXPECT_FALSE(GetOverlay()->received_paint_update_);
160
161  contents()->CommitPendingNavigation();
162  ReceivePaintUpdate();
163  // Navigation was committed and the paint update was received - the flag
164  // should now be updated.
165  EXPECT_TRUE(GetOverlay()->received_paint_update_);
166
167  EXPECT_FALSE(GetOverlay()->web_contents());
168}
169
170TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_LoadingUpdate) {
171  GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
172
173  PerformBackNavigationViaSliderCallbacks();
174  // No screenshot was set on NavEntry at offset -1.
175  EXPECT_FALSE(GetOverlay()->image_delegate_->has_image());
176  // Navigation was started, so the loading status flag should be reset.
177  EXPECT_FALSE(GetOverlay()->loading_complete_);
178
179  // Load updates until the navigation is committed represent updates for the
180  // previous page, so they shouldn't affect the flag.
181  contents()->TestSetIsLoading(true);
182  contents()->TestSetIsLoading(false);
183  EXPECT_FALSE(GetOverlay()->loading_complete_);
184
185  contents()->CommitPendingNavigation();
186  contents()->TestSetIsLoading(true);
187  contents()->TestSetIsLoading(false);
188  // Navigation was committed and the load update was received - the flag
189  // should now be updated.
190  EXPECT_TRUE(GetOverlay()->loading_complete_);
191
192  EXPECT_FALSE(GetOverlay()->web_contents());
193}
194
195}  // namespace content
196