1 // Copyright (c) 2012 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.
5 #include "base/macros.h"
6 #include "base/values.h"
7 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
8 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
9 #include "chrome/test/base/testing_profile.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 namespace extensions {
14 class FrameNavigationStateTest : public ChromeRenderViewHostTestHarness {
16 FrameNavigationStateTest() {}
17 virtual ~FrameNavigationStateTest() {}
19 FrameNavigationState navigation_state_;
22 DISALLOW_COPY_AND_ASSIGN(FrameNavigationStateTest);
25 // Test that a frame is correctly tracked, and removed once the tab contents
27 TEST_F(FrameNavigationStateTest, TrackFrame) {
28 const GURL url1("http://www.google.com/");
29 const GURL url2("http://mail.google.com/");
31 // Create a main frame.
32 EXPECT_FALSE(navigation_state_.CanSendEvents(main_rfh()));
33 EXPECT_FALSE(navigation_state_.IsValidFrame(main_rfh()));
34 navigation_state_.TrackFrame(main_rfh(), url1, false, false);
35 navigation_state_.SetNavigationCommitted(main_rfh());
36 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
37 EXPECT_TRUE(navigation_state_.IsValidFrame(main_rfh()));
40 content::RenderFrameHost* sub_frame =
41 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
42 EXPECT_FALSE(navigation_state_.CanSendEvents(sub_frame));
43 EXPECT_FALSE(navigation_state_.IsValidFrame(sub_frame));
44 navigation_state_.TrackFrame(sub_frame, url2, false, false);
45 navigation_state_.SetNavigationCommitted(sub_frame);
46 EXPECT_TRUE(navigation_state_.CanSendEvents(sub_frame));
47 EXPECT_TRUE(navigation_state_.IsValidFrame(sub_frame));
50 EXPECT_EQ(url1, navigation_state_.GetUrl(main_rfh()));
51 EXPECT_EQ(url2, navigation_state_.GetUrl(sub_frame));
52 EXPECT_EQ(main_rfh(), navigation_state_.GetLastCommittedMainFrameHost());
55 navigation_state_.StopTrackingFramesInRVH(rvh(), NULL);
56 EXPECT_FALSE(navigation_state_.CanSendEvents(main_rfh()));
57 EXPECT_FALSE(navigation_state_.IsValidFrame(main_rfh()));
58 EXPECT_FALSE(navigation_state_.CanSendEvents(sub_frame));
59 EXPECT_FALSE(navigation_state_.IsValidFrame(sub_frame));
62 // Test that no events can be sent for a frame after an error occurred, but
63 // before a new navigation happened in this frame.
64 TEST_F(FrameNavigationStateTest, ErrorState) {
65 const GURL url("http://www.google.com/");
67 navigation_state_.TrackFrame(main_rfh(), url, false, false);
68 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
69 EXPECT_FALSE(navigation_state_.GetErrorOccurredInFrame(main_rfh()));
71 // After an error occurred, no further events should be sent.
72 navigation_state_.SetErrorOccurredInFrame(main_rfh());
73 EXPECT_FALSE(navigation_state_.CanSendEvents(main_rfh()));
74 EXPECT_TRUE(navigation_state_.GetErrorOccurredInFrame(main_rfh()));
76 // Navigations to a network error page should be ignored.
77 navigation_state_.TrackFrame(main_rfh(), GURL(), true, false);
78 EXPECT_FALSE(navigation_state_.CanSendEvents(main_rfh()));
79 EXPECT_TRUE(navigation_state_.GetErrorOccurredInFrame(main_rfh()));
81 // However, when the frame navigates again, it should send events again.
82 navigation_state_.TrackFrame(main_rfh(), url, false, false);
83 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
84 EXPECT_FALSE(navigation_state_.GetErrorOccurredInFrame(main_rfh()));
87 // Tests that for a sub frame, no events are send after an error occurred, but
88 // before a new navigation happened in this frame.
89 TEST_F(FrameNavigationStateTest, ErrorStateFrame) {
90 const GURL url("http://www.google.com/");
92 content::RenderFrameHost* sub_frame =
93 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
94 navigation_state_.TrackFrame(main_rfh(), url, false, false);
95 navigation_state_.TrackFrame(sub_frame, url, false, false);
96 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
97 EXPECT_TRUE(navigation_state_.CanSendEvents(sub_frame));
99 // After an error occurred, no further events should be sent.
100 navigation_state_.SetErrorOccurredInFrame(sub_frame);
101 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
102 EXPECT_FALSE(navigation_state_.CanSendEvents(sub_frame));
104 // Navigations to a network error page should be ignored.
105 navigation_state_.TrackFrame(sub_frame, GURL(), true, false);
106 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
107 EXPECT_FALSE(navigation_state_.CanSendEvents(sub_frame));
109 // However, when the frame navigates again, it should send events again.
110 navigation_state_.TrackFrame(sub_frame, url, false, false);
111 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
112 EXPECT_TRUE(navigation_state_.CanSendEvents(sub_frame));
115 // Tests that no events are send for a not web-safe scheme.
116 TEST_F(FrameNavigationStateTest, WebSafeScheme) {
117 const GURL url("unsafe://www.google.com/");
119 navigation_state_.TrackFrame(main_rfh(), url, false, false);
120 EXPECT_FALSE(navigation_state_.CanSendEvents(main_rfh()));
123 // Test for <iframe srcdoc=""> frames.
124 TEST_F(FrameNavigationStateTest, SrcDoc) {
125 const GURL url("http://www.google.com/");
126 const GURL blank("about:blank");
127 const GURL srcdoc("about:srcdoc");
129 content::RenderFrameHost* sub_frame =
130 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
131 navigation_state_.TrackFrame(main_rfh(), url, false, false);
132 navigation_state_.TrackFrame(sub_frame, blank, false, true);
133 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
134 EXPECT_TRUE(navigation_state_.CanSendEvents(sub_frame));
136 EXPECT_EQ(url, navigation_state_.GetUrl(main_rfh()));
137 EXPECT_EQ(srcdoc, navigation_state_.GetUrl(sub_frame));
139 EXPECT_TRUE(navigation_state_.IsValidUrl(srcdoc));
142 // Test that an individual frame can be detached.
143 TEST_F(FrameNavigationStateTest, DetachFrame) {
144 const GURL url1("http://www.google.com/");
145 const GURL url2("http://mail.google.com/");
147 // Create a main frame.
148 EXPECT_FALSE(navigation_state_.CanSendEvents(main_rfh()));
149 EXPECT_FALSE(navigation_state_.IsValidFrame(main_rfh()));
150 navigation_state_.TrackFrame(main_rfh(), url1, false, false);
151 navigation_state_.SetNavigationCommitted(main_rfh());
152 EXPECT_TRUE(navigation_state_.CanSendEvents(main_rfh()));
153 EXPECT_TRUE(navigation_state_.IsValidFrame(main_rfh()));
156 content::RenderFrameHost* sub_frame =
157 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
158 EXPECT_FALSE(navigation_state_.CanSendEvents(sub_frame));
159 EXPECT_FALSE(navigation_state_.IsValidFrame(sub_frame));
160 navigation_state_.TrackFrame(sub_frame, url2, false, false);
161 navigation_state_.SetNavigationCommitted(sub_frame);
162 EXPECT_TRUE(navigation_state_.CanSendEvents(sub_frame));
163 EXPECT_TRUE(navigation_state_.IsValidFrame(sub_frame));
165 // Check frame state.
166 EXPECT_EQ(url1, navigation_state_.GetUrl(main_rfh()));
167 EXPECT_EQ(url2, navigation_state_.GetUrl(sub_frame));
168 EXPECT_EQ(main_rfh(), navigation_state_.GetLastCommittedMainFrameHost());
171 navigation_state_.FrameDetached(sub_frame);
172 EXPECT_EQ(url1, navigation_state_.GetUrl(main_rfh()));
173 EXPECT_EQ(main_rfh(), navigation_state_.GetLastCommittedMainFrameHost());
174 EXPECT_FALSE(navigation_state_.CanSendEvents(sub_frame));
175 EXPECT_FALSE(navigation_state_.IsValidFrame(sub_frame));
178 } // namespace extensions