1// Copyright 2013 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/strings/string16.h"
6#include "base/strings/string_util.h"
7#include "base/strings/utf_string_conversions.h"
8#include "base/time/time.h"
9#include "content/browser/frame_host/navigation_entry_impl.h"
10#include "content/browser/site_instance_impl.h"
11#include "content/public/common/ssl_status.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace content {
15
16class NavigationEntryTest : public testing::Test {
17 public:
18  NavigationEntryTest() : instance_(NULL) {
19  }
20
21  virtual void SetUp() {
22    entry1_.reset(new NavigationEntryImpl);
23
24#if !defined(OS_IOS)
25    instance_ = static_cast<SiteInstanceImpl*>(SiteInstance::Create(NULL));
26#endif
27    entry2_.reset(new NavigationEntryImpl(
28          instance_, 3,
29          GURL("test:url"),
30          Referrer(GURL("from"), blink::WebReferrerPolicyDefault),
31          ASCIIToUTF16("title"),
32          PAGE_TRANSITION_TYPED,
33          false));
34  }
35
36  virtual void TearDown() {
37  }
38
39 protected:
40  scoped_ptr<NavigationEntryImpl> entry1_;
41  scoped_ptr<NavigationEntryImpl> entry2_;
42  // SiteInstances are deleted when their NavigationEntries are gone.
43  SiteInstanceImpl* instance_;
44};
45
46// Test unique ID accessors
47TEST_F(NavigationEntryTest, NavigationEntryUniqueIDs) {
48  // Two entries should have different IDs by default
49  EXPECT_NE(entry1_->GetUniqueID(), entry2_->GetUniqueID());
50
51  // Can set an entry to have the same ID as another
52  entry2_->set_unique_id(entry1_->GetUniqueID());
53  EXPECT_EQ(entry1_->GetUniqueID(), entry2_->GetUniqueID());
54}
55
56// Test URL accessors
57TEST_F(NavigationEntryTest, NavigationEntryURLs) {
58  // Start with no virtual_url (even if a url is set)
59  EXPECT_FALSE(entry1_->has_virtual_url());
60  EXPECT_FALSE(entry2_->has_virtual_url());
61
62  EXPECT_EQ(GURL(), entry1_->GetURL());
63  EXPECT_EQ(GURL(), entry1_->GetVirtualURL());
64  EXPECT_TRUE(entry1_->GetTitleForDisplay(std::string()).empty());
65
66  // Setting URL affects virtual_url and GetTitleForDisplay
67  entry1_->SetURL(GURL("http://www.google.com"));
68  EXPECT_EQ(GURL("http://www.google.com"), entry1_->GetURL());
69  EXPECT_EQ(GURL("http://www.google.com"), entry1_->GetVirtualURL());
70  EXPECT_EQ(ASCIIToUTF16("www.google.com"),
71            entry1_->GetTitleForDisplay(std::string()));
72
73  // file:/// URLs should only show the filename.
74  entry1_->SetURL(GURL("file:///foo/bar baz.txt"));
75  EXPECT_EQ(ASCIIToUTF16("bar baz.txt"),
76            entry1_->GetTitleForDisplay(std::string()));
77
78  // Title affects GetTitleForDisplay
79  entry1_->SetTitle(ASCIIToUTF16("Google"));
80  EXPECT_EQ(ASCIIToUTF16("Google"), entry1_->GetTitleForDisplay(std::string()));
81
82  // Setting virtual_url doesn't affect URL
83  entry2_->SetVirtualURL(GURL("display:url"));
84  EXPECT_TRUE(entry2_->has_virtual_url());
85  EXPECT_EQ(GURL("test:url"), entry2_->GetURL());
86  EXPECT_EQ(GURL("display:url"), entry2_->GetVirtualURL());
87
88  // Having a title set in constructor overrides virtual URL
89  EXPECT_EQ(ASCIIToUTF16("title"), entry2_->GetTitleForDisplay(std::string()));
90
91  // User typed URL is independent of the others
92  EXPECT_EQ(GURL(), entry1_->GetUserTypedURL());
93  EXPECT_EQ(GURL(), entry2_->GetUserTypedURL());
94  entry2_->set_user_typed_url(GURL("typedurl"));
95  EXPECT_EQ(GURL("typedurl"), entry2_->GetUserTypedURL());
96}
97
98// Test Favicon inner class construction.
99TEST_F(NavigationEntryTest, NavigationEntryFavicons) {
100  EXPECT_EQ(GURL(), entry1_->GetFavicon().url);
101  EXPECT_FALSE(entry1_->GetFavicon().valid);
102}
103
104// Test SSLStatus inner class
105TEST_F(NavigationEntryTest, NavigationEntrySSLStatus) {
106  // Default (unknown)
107  EXPECT_EQ(SECURITY_STYLE_UNKNOWN, entry1_->GetSSL().security_style);
108  EXPECT_EQ(SECURITY_STYLE_UNKNOWN, entry2_->GetSSL().security_style);
109  EXPECT_EQ(0, entry1_->GetSSL().cert_id);
110  EXPECT_EQ(0U, entry1_->GetSSL().cert_status);
111  EXPECT_EQ(-1, entry1_->GetSSL().security_bits);
112  int content_status = entry1_->GetSSL().content_status;
113  EXPECT_FALSE(!!(content_status & SSLStatus::DISPLAYED_INSECURE_CONTENT));
114  EXPECT_FALSE(!!(content_status & SSLStatus::RAN_INSECURE_CONTENT));
115}
116
117// Test other basic accessors
118TEST_F(NavigationEntryTest, NavigationEntryAccessors) {
119  // SiteInstance
120  EXPECT_TRUE(entry1_->site_instance() == NULL);
121  EXPECT_EQ(instance_, entry2_->site_instance());
122  entry1_->set_site_instance(instance_);
123  EXPECT_EQ(instance_, entry1_->site_instance());
124
125  // Page type
126  EXPECT_EQ(PAGE_TYPE_NORMAL, entry1_->GetPageType());
127  EXPECT_EQ(PAGE_TYPE_NORMAL, entry2_->GetPageType());
128  entry2_->set_page_type(PAGE_TYPE_INTERSTITIAL);
129  EXPECT_EQ(PAGE_TYPE_INTERSTITIAL, entry2_->GetPageType());
130
131  // Referrer
132  EXPECT_EQ(GURL(), entry1_->GetReferrer().url);
133  EXPECT_EQ(GURL("from"), entry2_->GetReferrer().url);
134  entry2_->SetReferrer(
135      Referrer(GURL("from2"), blink::WebReferrerPolicyDefault));
136  EXPECT_EQ(GURL("from2"), entry2_->GetReferrer().url);
137
138  // Title
139  EXPECT_EQ(base::string16(), entry1_->GetTitle());
140  EXPECT_EQ(ASCIIToUTF16("title"), entry2_->GetTitle());
141  entry2_->SetTitle(ASCIIToUTF16("title2"));
142  EXPECT_EQ(ASCIIToUTF16("title2"), entry2_->GetTitle());
143
144  // State
145  EXPECT_FALSE(entry1_->GetPageState().IsValid());
146  EXPECT_FALSE(entry2_->GetPageState().IsValid());
147  entry2_->SetPageState(PageState::CreateFromEncodedData("state"));
148  EXPECT_EQ("state", entry2_->GetPageState().ToEncodedData());
149
150  // Page ID
151  EXPECT_EQ(-1, entry1_->GetPageID());
152  EXPECT_EQ(3, entry2_->GetPageID());
153  entry2_->SetPageID(2);
154  EXPECT_EQ(2, entry2_->GetPageID());
155
156  // Transition type
157  EXPECT_EQ(PAGE_TRANSITION_LINK, entry1_->GetTransitionType());
158  EXPECT_EQ(PAGE_TRANSITION_TYPED, entry2_->GetTransitionType());
159  entry2_->SetTransitionType(PAGE_TRANSITION_RELOAD);
160  EXPECT_EQ(PAGE_TRANSITION_RELOAD, entry2_->GetTransitionType());
161
162  // Is renderer initiated
163  EXPECT_FALSE(entry1_->is_renderer_initiated());
164  EXPECT_FALSE(entry2_->is_renderer_initiated());
165  entry2_->set_is_renderer_initiated(true);
166  EXPECT_TRUE(entry2_->is_renderer_initiated());
167
168  // Post Data
169  EXPECT_FALSE(entry1_->GetHasPostData());
170  EXPECT_FALSE(entry2_->GetHasPostData());
171  entry2_->SetHasPostData(true);
172  EXPECT_TRUE(entry2_->GetHasPostData());
173
174  // Restored
175  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE, entry1_->restore_type());
176  EXPECT_EQ(NavigationEntryImpl::RESTORE_NONE, entry2_->restore_type());
177  entry2_->set_restore_type(
178      NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY);
179  EXPECT_EQ(NavigationEntryImpl::RESTORE_LAST_SESSION_EXITED_CLEANLY,
180            entry2_->restore_type());
181
182  // Original URL
183  EXPECT_EQ(GURL(), entry1_->GetOriginalRequestURL());
184  EXPECT_EQ(GURL(), entry2_->GetOriginalRequestURL());
185  entry2_->SetOriginalRequestURL(GURL("original_url"));
186  EXPECT_EQ(GURL("original_url"), entry2_->GetOriginalRequestURL());
187
188  // User agent override
189  EXPECT_FALSE(entry1_->GetIsOverridingUserAgent());
190  EXPECT_FALSE(entry2_->GetIsOverridingUserAgent());
191  entry2_->SetIsOverridingUserAgent(true);
192  EXPECT_TRUE(entry2_->GetIsOverridingUserAgent());
193
194  // Browser initiated post data
195  EXPECT_EQ(NULL, entry1_->GetBrowserInitiatedPostData());
196  EXPECT_EQ(NULL, entry2_->GetBrowserInitiatedPostData());
197  const int length = 11;
198  const unsigned char* raw_data =
199      reinterpret_cast<const unsigned char*>("post\n\n\0data");
200  std::vector<unsigned char> post_data_vector(raw_data, raw_data+length);
201  scoped_refptr<base::RefCountedBytes> post_data =
202      base::RefCountedBytes::TakeVector(&post_data_vector);
203  entry2_->SetBrowserInitiatedPostData(post_data.get());
204  EXPECT_EQ(post_data->front(),
205      entry2_->GetBrowserInitiatedPostData()->front());
206
207 // Frame to navigate.
208  EXPECT_TRUE(entry1_->GetFrameToNavigate().empty());
209  EXPECT_TRUE(entry2_->GetFrameToNavigate().empty());
210}
211
212// Test timestamps.
213TEST_F(NavigationEntryTest, NavigationEntryTimestamps) {
214  EXPECT_EQ(base::Time(), entry1_->GetTimestamp());
215  const base::Time now = base::Time::Now();
216  entry1_->SetTimestamp(now);
217  EXPECT_EQ(now, entry1_->GetTimestamp());
218}
219
220// Test extra data stored in the navigation entry.
221TEST_F(NavigationEntryTest, NavigationEntryExtraData) {
222  base::string16 test_data = ASCIIToUTF16("my search terms");
223  base::string16 output;
224  entry1_->SetExtraData("search_terms", test_data);
225
226  EXPECT_FALSE(entry1_->GetExtraData("non_existent_key", &output));
227  EXPECT_EQ(ASCIIToUTF16(""), output);
228  EXPECT_TRUE(entry1_->GetExtraData("search_terms", &output));
229  EXPECT_EQ(test_data, output);
230  // Data is cleared.
231  entry1_->ClearExtraData("search_terms");
232  // Content in |output| is not modified if data is not present at the key.
233  EXPECT_FALSE(entry1_->GetExtraData("search_terms", &output));
234  EXPECT_EQ(test_data, output);
235  // Using an empty string shows that the data is not present in the map.
236  base::string16 output2;
237  EXPECT_FALSE(entry1_->GetExtraData("search_terms", &output2));
238  EXPECT_EQ(ASCIIToUTF16(""), output2);
239}
240
241}  // namespace content
242