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. 4 5 #include "base/values.h" 6 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h" 7 #include "chrome/test/base/testing_profile.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 10 namespace extensions { 11 12 content::RenderViewHost* fake_rvh = 13 reinterpret_cast<content::RenderViewHost*>(31337); 14 15 // Test that a frame is correctly tracked, and removed once the tab contents 16 // goes away. 17 TEST(FrameNavigationStateTest, TrackFrame) { 18 FrameNavigationState navigation_state; 19 const FrameNavigationState::FrameID frame_id0(-1, fake_rvh); 20 const FrameNavigationState::FrameID frame_id1(23, fake_rvh); 21 const FrameNavigationState::FrameID frame_id2(42, fake_rvh); 22 const GURL url1("http://www.google.com/"); 23 const GURL url2("http://mail.google.com/"); 24 25 // Create a main frame. 26 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id1)); 27 EXPECT_FALSE(navigation_state.IsValidFrame(frame_id1)); 28 navigation_state.TrackFrame(frame_id1, frame_id0, url1, true, false, false); 29 navigation_state.SetNavigationCommitted(frame_id1); 30 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 31 EXPECT_TRUE(navigation_state.IsValidFrame(frame_id1)); 32 33 // Add a sub frame. 34 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2)); 35 EXPECT_FALSE(navigation_state.IsValidFrame(frame_id2)); 36 navigation_state.TrackFrame(frame_id2, frame_id1, url2, false, false, false); 37 navigation_state.SetNavigationCommitted(frame_id2); 38 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2)); 39 EXPECT_TRUE(navigation_state.IsValidFrame(frame_id2)); 40 41 // Check frame state. 42 EXPECT_TRUE(navigation_state.IsMainFrame(frame_id1)); 43 EXPECT_EQ(url1, navigation_state.GetUrl(frame_id1)); 44 EXPECT_FALSE(navigation_state.IsMainFrame(frame_id2)); 45 EXPECT_EQ(url2, navigation_state.GetUrl(frame_id2)); 46 EXPECT_EQ(frame_id1, navigation_state.GetMainFrameID()); 47 48 // Drop the frames. 49 navigation_state.StopTrackingFramesInRVH(fake_rvh, 50 FrameNavigationState::FrameID()); 51 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id1)); 52 EXPECT_FALSE(navigation_state.IsValidFrame(frame_id1)); 53 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2)); 54 EXPECT_FALSE(navigation_state.IsValidFrame(frame_id2)); 55 } 56 57 // Test that no events can be sent for a frame after an error occurred, but 58 // before a new navigation happened in this frame. 59 TEST(FrameNavigationStateTest, ErrorState) { 60 FrameNavigationState navigation_state; 61 const FrameNavigationState::FrameID frame_id0(-1, fake_rvh); 62 const FrameNavigationState::FrameID frame_id1(42, fake_rvh); 63 const GURL url("http://www.google.com/"); 64 65 navigation_state.TrackFrame(frame_id1, frame_id0, url, true, false, false); 66 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 67 EXPECT_FALSE(navigation_state.GetErrorOccurredInFrame(frame_id1)); 68 69 // After an error occurred, no further events should be sent. 70 navigation_state.SetErrorOccurredInFrame(frame_id1); 71 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id1)); 72 EXPECT_TRUE(navigation_state.GetErrorOccurredInFrame(frame_id1)); 73 74 // Navigations to a network error page should be ignored. 75 navigation_state.TrackFrame(frame_id1, frame_id0, GURL(), true, true, false); 76 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id1)); 77 EXPECT_TRUE(navigation_state.GetErrorOccurredInFrame(frame_id1)); 78 79 // However, when the frame navigates again, it should send events again. 80 navigation_state.TrackFrame(frame_id1, frame_id0, url, true, false, false); 81 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 82 EXPECT_FALSE(navigation_state.GetErrorOccurredInFrame(frame_id1)); 83 } 84 85 // Tests that for a sub frame, no events are send after an error occurred, but 86 // before a new navigation happened in this frame. 87 TEST(FrameNavigationStateTest, ErrorStateFrame) { 88 FrameNavigationState navigation_state; 89 const FrameNavigationState::FrameID frame_id0(-1, fake_rvh); 90 const FrameNavigationState::FrameID frame_id1(23, fake_rvh); 91 const FrameNavigationState::FrameID frame_id2(42, fake_rvh); 92 const GURL url("http://www.google.com/"); 93 94 navigation_state.TrackFrame(frame_id1, frame_id0, url, true, false, false); 95 navigation_state.TrackFrame(frame_id2, frame_id1, url, false, false, false); 96 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 97 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2)); 98 99 // After an error occurred, no further events should be sent. 100 navigation_state.SetErrorOccurredInFrame(frame_id2); 101 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 102 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2)); 103 104 // Navigations to a network error page should be ignored. 105 navigation_state.TrackFrame(frame_id2, frame_id1, GURL(), false, true, false); 106 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 107 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2)); 108 109 // However, when the frame navigates again, it should send events again. 110 navigation_state.TrackFrame(frame_id2, frame_id1, url, false, false, false); 111 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 112 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2)); 113 } 114 115 // Tests that no events are send for a not web-safe scheme. 116 TEST(FrameNavigationStateTest, WebSafeScheme) { 117 FrameNavigationState navigation_state; 118 const FrameNavigationState::FrameID frame_id0(-1, fake_rvh); 119 const FrameNavigationState::FrameID frame_id1(23, fake_rvh); 120 const GURL url("unsafe://www.google.com/"); 121 122 navigation_state.TrackFrame(frame_id1, frame_id0, url, true, false, false); 123 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id1)); 124 } 125 126 // Test that parent frame IDs are tracked. 127 TEST(FrameNavigationStateTest, ParentFrameID) { 128 FrameNavigationState navigation_state; 129 const FrameNavigationState::FrameID frame_id0(-1, fake_rvh); 130 const FrameNavigationState::FrameID frame_id1(23, fake_rvh); 131 const FrameNavigationState::FrameID frame_id2(42, fake_rvh); 132 const GURL url("http://www.google.com/"); 133 134 navigation_state.TrackFrame(frame_id1, frame_id0, url, true, false, false); 135 navigation_state.TrackFrame(frame_id2, frame_id1, url, false, false, false); 136 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 137 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2)); 138 139 EXPECT_TRUE(navigation_state.GetParentFrameID(frame_id1) == frame_id0); 140 EXPECT_TRUE(navigation_state.GetParentFrameID(frame_id2) == frame_id1); 141 } 142 143 // Test for <iframe srcdoc=""> frames. 144 TEST(FrameNavigationStateTest, SrcDoc) { 145 FrameNavigationState navigation_state; 146 const FrameNavigationState::FrameID frame_id0(-1, fake_rvh); 147 const FrameNavigationState::FrameID frame_id1(23, fake_rvh); 148 const FrameNavigationState::FrameID frame_id2(42, fake_rvh); 149 const GURL url("http://www.google.com/"); 150 const GURL blank("about:blank"); 151 const GURL srcdoc("about:srcdoc"); 152 153 navigation_state.TrackFrame(frame_id1, frame_id0, url, true, false, false); 154 navigation_state.TrackFrame(frame_id2, frame_id1, blank, false, false, true); 155 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 156 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2)); 157 158 EXPECT_TRUE(navigation_state.GetUrl(frame_id1) == url); 159 EXPECT_TRUE(navigation_state.GetUrl(frame_id2) == srcdoc); 160 161 EXPECT_TRUE(navigation_state.IsValidUrl(srcdoc)); 162 } 163 164 // Test that an individual frame can be detached. 165 TEST(FrameNavigationStateTest, DetachFrame) { 166 FrameNavigationState navigation_state; 167 const FrameNavigationState::FrameID frame_id0(-1, fake_rvh); 168 const FrameNavigationState::FrameID frame_id1(23, fake_rvh); 169 const FrameNavigationState::FrameID frame_id2(42, fake_rvh); 170 const GURL url1("http://www.google.com/"); 171 const GURL url2("http://mail.google.com/"); 172 173 // Create a main frame. 174 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id1)); 175 EXPECT_FALSE(navigation_state.IsValidFrame(frame_id1)); 176 navigation_state.TrackFrame(frame_id1, frame_id0, url1, true, false, false); 177 navigation_state.SetNavigationCommitted(frame_id1); 178 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1)); 179 EXPECT_TRUE(navigation_state.IsValidFrame(frame_id1)); 180 181 // Add a sub frame. 182 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2)); 183 EXPECT_FALSE(navigation_state.IsValidFrame(frame_id2)); 184 navigation_state.TrackFrame(frame_id2, frame_id1, url2, false, false, false); 185 navigation_state.SetNavigationCommitted(frame_id2); 186 EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2)); 187 EXPECT_TRUE(navigation_state.IsValidFrame(frame_id2)); 188 189 // Check frame state. 190 EXPECT_TRUE(navigation_state.IsMainFrame(frame_id1)); 191 EXPECT_EQ(url1, navigation_state.GetUrl(frame_id1)); 192 EXPECT_FALSE(navigation_state.IsMainFrame(frame_id2)); 193 EXPECT_EQ(url2, navigation_state.GetUrl(frame_id2)); 194 EXPECT_EQ(frame_id1, navigation_state.GetMainFrameID()); 195 196 // Drop one frame. 197 navigation_state.FrameDetached(frame_id2); 198 EXPECT_TRUE(navigation_state.IsMainFrame(frame_id1)); 199 EXPECT_EQ(url1, navigation_state.GetUrl(frame_id1)); 200 EXPECT_EQ(frame_id1, navigation_state.GetMainFrameID()); 201 EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2)); 202 EXPECT_FALSE(navigation_state.IsValidFrame(frame_id2)); 203 } 204 205 } // namespace extensions 206