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