Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / sessions / serialized_navigation_entry_unittest.cc
1 // Copyright (c) 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 "components/sessions/serialized_navigation_entry.h"
6
7 #include <cstddef>
8 #include <string>
9
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/pickle.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/time/time.h"
17 #include "content/public/browser/favicon_status.h"
18 #include "content/public/browser/navigation_entry.h"
19 #include "content/public/common/page_transition_types.h"
20 #include "content/public/common/referrer.h"
21 #include "sync/protocol/session_specifics.pb.h"
22 #include "sync/util/time.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/WebKit/public/platform/WebReferrerPolicy.h"
25 #include "url/gurl.h"
26
27 namespace sessions {
28 namespace {
29
30 const int kIndex = 3;
31 const int kUniqueID = 50;
32 const content::Referrer kReferrer =
33     content::Referrer(GURL("http://www.referrer.com"),
34                       blink::WebReferrerPolicyAlways);
35 const GURL kVirtualURL("http://www.virtual-url.com");
36 const base::string16 kTitle = base::ASCIIToUTF16("title");
37 const content::PageState kPageState =
38     content::PageState::CreateFromEncodedData("page state");
39 const content::PageTransition kTransitionType =
40     static_cast<content::PageTransition>(
41         content::PAGE_TRANSITION_AUTO_SUBFRAME |
42         content::PAGE_TRANSITION_HOME_PAGE |
43         content::PAGE_TRANSITION_CLIENT_REDIRECT);
44 const bool kHasPostData = true;
45 const int64 kPostID = 100;
46 const GURL kOriginalRequestURL("http://www.original-request.com");
47 const bool kIsOverridingUserAgent = true;
48 const base::Time kTimestamp = syncer::ProtoTimeToTime(100);
49 const base::string16 kSearchTerms = base::ASCIIToUTF16("my search terms");
50 const GURL kFaviconURL("http://virtual-url.com/favicon.ico");
51 const int kHttpStatusCode = 404;
52 const GURL kRedirectURL0("http://go/redirect0");
53 const GURL kRedirectURL1("http://go/redirect1");
54 const GURL kOtherURL("http://other.com");
55
56 const int kPageID = 10;
57
58 // Create a NavigationEntry from the constants above.
59 scoped_ptr<content::NavigationEntry> MakeNavigationEntryForTest() {
60   scoped_ptr<content::NavigationEntry> navigation_entry(
61       content::NavigationEntry::Create());
62   navigation_entry->SetReferrer(kReferrer);
63   navigation_entry->SetVirtualURL(kVirtualURL);
64   navigation_entry->SetTitle(kTitle);
65   navigation_entry->SetPageState(kPageState);
66   navigation_entry->SetTransitionType(kTransitionType);
67   navigation_entry->SetHasPostData(kHasPostData);
68   navigation_entry->SetPostID(kPostID);
69   navigation_entry->SetOriginalRequestURL(kOriginalRequestURL);
70   navigation_entry->SetIsOverridingUserAgent(kIsOverridingUserAgent);
71   navigation_entry->SetTimestamp(kTimestamp);
72   navigation_entry->SetExtraData(kSearchTermsKey, kSearchTerms);
73   navigation_entry->GetFavicon().valid = true;
74   navigation_entry->GetFavicon().url = kFaviconURL;
75   navigation_entry->SetHttpStatusCode(kHttpStatusCode);
76   std::vector<GURL> redirect_chain;
77   redirect_chain.push_back(kRedirectURL0);
78   redirect_chain.push_back(kRedirectURL1);
79   redirect_chain.push_back(kVirtualURL);
80   navigation_entry->SetRedirectChain(redirect_chain);
81   return navigation_entry.Pass();
82 }
83
84 // Create a sync_pb::TabNavigation from the constants above.
85 sync_pb::TabNavigation MakeSyncDataForTest() {
86   sync_pb::TabNavigation sync_data;
87   sync_data.set_virtual_url(kVirtualURL.spec());
88   sync_data.set_referrer(kReferrer.url.spec());
89   sync_data.set_referrer_policy(blink::WebReferrerPolicyOrigin);
90   sync_data.set_title(base::UTF16ToUTF8(kTitle));
91   sync_data.set_state(kPageState.ToEncodedData());
92   sync_data.set_page_transition(
93       sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME);
94   sync_data.set_unique_id(kUniqueID);
95   sync_data.set_timestamp_msec(syncer::TimeToProtoTime(kTimestamp));
96   sync_data.set_redirect_type(sync_pb::SyncEnums::CLIENT_REDIRECT);
97   sync_data.set_navigation_home_page(true);
98   sync_data.set_search_terms(base::UTF16ToUTF8(kSearchTerms));
99   sync_data.set_favicon_url(kFaviconURL.spec());
100   sync_data.set_http_status_code(kHttpStatusCode);
101   // The redirect chain only syncs one way.
102   return sync_data;
103 }
104
105 // Create a default SerializedNavigationEntry.  All its fields should be
106 // initialized to their respective default values.
107 TEST(SerializedNavigationEntryTest, DefaultInitializer) {
108   const SerializedNavigationEntry navigation;
109   EXPECT_EQ(-1, navigation.index());
110   EXPECT_EQ(0, navigation.unique_id());
111   EXPECT_EQ(GURL(), navigation.referrer().url);
112   EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer().policy);
113   EXPECT_EQ(GURL(), navigation.virtual_url());
114   EXPECT_TRUE(navigation.title().empty());
115   EXPECT_FALSE(navigation.page_state().IsValid());
116   EXPECT_EQ(content::PAGE_TRANSITION_TYPED, navigation.transition_type());
117   EXPECT_FALSE(navigation.has_post_data());
118   EXPECT_EQ(-1, navigation.post_id());
119   EXPECT_EQ(GURL(), navigation.original_request_url());
120   EXPECT_FALSE(navigation.is_overriding_user_agent());
121   EXPECT_TRUE(navigation.timestamp().is_null());
122   EXPECT_TRUE(navigation.search_terms().empty());
123   EXPECT_FALSE(navigation.favicon_url().is_valid());
124   EXPECT_EQ(0, navigation.http_status_code());
125   EXPECT_EQ(0U, navigation.redirect_chain().size());
126 }
127
128 // Create a SerializedNavigationEntry from a NavigationEntry.  All its fields
129 // should match the NavigationEntry's.
130 TEST(SerializedNavigationEntryTest, FromNavigationEntry) {
131   const scoped_ptr<content::NavigationEntry> navigation_entry(
132       MakeNavigationEntryForTest());
133
134   const SerializedNavigationEntry& navigation =
135       SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry);
136
137   EXPECT_EQ(kIndex, navigation.index());
138
139   EXPECT_EQ(navigation_entry->GetUniqueID(), navigation.unique_id());
140   EXPECT_EQ(kReferrer.url, navigation.referrer().url);
141   EXPECT_EQ(kReferrer.policy, navigation.referrer().policy);
142   EXPECT_EQ(kVirtualURL, navigation.virtual_url());
143   EXPECT_EQ(kTitle, navigation.title());
144   EXPECT_EQ(kPageState, navigation.page_state());
145   EXPECT_EQ(kTransitionType, navigation.transition_type());
146   EXPECT_EQ(kHasPostData, navigation.has_post_data());
147   EXPECT_EQ(kPostID, navigation.post_id());
148   EXPECT_EQ(kOriginalRequestURL, navigation.original_request_url());
149   EXPECT_EQ(kIsOverridingUserAgent, navigation.is_overriding_user_agent());
150   EXPECT_EQ(kTimestamp, navigation.timestamp());
151   EXPECT_EQ(kFaviconURL, navigation.favicon_url());
152   EXPECT_EQ(kHttpStatusCode, navigation.http_status_code());
153   ASSERT_EQ(3U, navigation.redirect_chain().size());
154   EXPECT_EQ(kRedirectURL0, navigation.redirect_chain()[0]);
155   EXPECT_EQ(kRedirectURL1, navigation.redirect_chain()[1]);
156   EXPECT_EQ(kVirtualURL, navigation.redirect_chain()[2]);
157 }
158
159 // Create a SerializedNavigationEntry from a sync_pb::TabNavigation.  All its
160 // fields should match the protocol buffer's if it exists there, and
161 // sbould be set to the default value otherwise.
162 TEST(SerializedNavigationEntryTest, FromSyncData) {
163   const sync_pb::TabNavigation sync_data = MakeSyncDataForTest();
164
165   const SerializedNavigationEntry& navigation =
166       SerializedNavigationEntry::FromSyncData(kIndex, sync_data);
167
168   EXPECT_EQ(kIndex, navigation.index());
169   EXPECT_EQ(kUniqueID, navigation.unique_id());
170   EXPECT_EQ(kReferrer.url, navigation.referrer().url);
171   EXPECT_EQ(blink::WebReferrerPolicyOrigin, navigation.referrer().policy);
172   EXPECT_EQ(kVirtualURL, navigation.virtual_url());
173   EXPECT_EQ(kTitle, navigation.title());
174   EXPECT_EQ(kPageState, navigation.page_state());
175   EXPECT_EQ(kTransitionType, navigation.transition_type());
176   EXPECT_FALSE(navigation.has_post_data());
177   EXPECT_EQ(-1, navigation.post_id());
178   EXPECT_EQ(GURL(), navigation.original_request_url());
179   EXPECT_FALSE(navigation.is_overriding_user_agent());
180   EXPECT_TRUE(navigation.timestamp().is_null());
181   EXPECT_EQ(kSearchTerms, navigation.search_terms());
182   EXPECT_EQ(kFaviconURL, navigation.favicon_url());
183   EXPECT_EQ(kHttpStatusCode, navigation.http_status_code());
184   // The redirect chain only syncs one way.
185 }
186
187 // Create a SerializedNavigationEntry, pickle it, then create another one by
188 // unpickling.  The new one should match the old one except for fields
189 // that aren't pickled, which should be set to default values.
190 TEST(SerializedNavigationEntryTest, Pickle) {
191   const SerializedNavigationEntry& old_navigation =
192       SerializedNavigationEntry::FromNavigationEntry(
193           kIndex, *MakeNavigationEntryForTest());
194
195   Pickle pickle;
196   old_navigation.WriteToPickle(30000, &pickle);
197
198   SerializedNavigationEntry new_navigation;
199   PickleIterator pickle_iterator(pickle);
200   EXPECT_TRUE(new_navigation.ReadFromPickle(&pickle_iterator));
201
202   EXPECT_EQ(kIndex, new_navigation.index());
203
204   EXPECT_EQ(0, new_navigation.unique_id());
205   EXPECT_EQ(kReferrer.url, new_navigation.referrer().url);
206   EXPECT_EQ(kReferrer.policy, new_navigation.referrer().policy);
207   EXPECT_EQ(kVirtualURL, new_navigation.virtual_url());
208   EXPECT_EQ(kTitle, new_navigation.title());
209   EXPECT_FALSE(new_navigation.page_state().IsValid());
210   EXPECT_EQ(kTransitionType, new_navigation.transition_type());
211   EXPECT_EQ(kHasPostData, new_navigation.has_post_data());
212   EXPECT_EQ(-1, new_navigation.post_id());
213   EXPECT_EQ(kOriginalRequestURL, new_navigation.original_request_url());
214   EXPECT_EQ(kIsOverridingUserAgent, new_navigation.is_overriding_user_agent());
215   EXPECT_EQ(kTimestamp, new_navigation.timestamp());
216   EXPECT_EQ(kSearchTerms, new_navigation.search_terms());
217   EXPECT_EQ(kHttpStatusCode, new_navigation.http_status_code());
218   EXPECT_EQ(0U, new_navigation.redirect_chain().size());
219 }
220
221 // Create a NavigationEntry, then create another one by converting to
222 // a SerializedNavigationEntry and back.  The new one should match the old one
223 // except for fields that aren't preserved, which should be set to
224 // expected values.
225 TEST(SerializedNavigationEntryTest, ToNavigationEntry) {
226   const scoped_ptr<content::NavigationEntry> old_navigation_entry(
227       MakeNavigationEntryForTest());
228
229   const SerializedNavigationEntry& navigation =
230       SerializedNavigationEntry::FromNavigationEntry(kIndex,
231                                                      *old_navigation_entry);
232
233   const scoped_ptr<content::NavigationEntry> new_navigation_entry(
234       navigation.ToNavigationEntry(kPageID, NULL));
235
236   EXPECT_EQ(kReferrer.url, new_navigation_entry->GetReferrer().url);
237   EXPECT_EQ(kReferrer.policy, new_navigation_entry->GetReferrer().policy);
238   EXPECT_EQ(kVirtualURL, new_navigation_entry->GetVirtualURL());
239   EXPECT_EQ(kTitle, new_navigation_entry->GetTitle());
240   EXPECT_EQ(kPageState, new_navigation_entry->GetPageState());
241   EXPECT_EQ(kPageID, new_navigation_entry->GetPageID());
242   EXPECT_EQ(content::PAGE_TRANSITION_RELOAD,
243             new_navigation_entry->GetTransitionType());
244   EXPECT_EQ(kHasPostData, new_navigation_entry->GetHasPostData());
245   EXPECT_EQ(kPostID, new_navigation_entry->GetPostID());
246   EXPECT_EQ(kOriginalRequestURL,
247             new_navigation_entry->GetOriginalRequestURL());
248   EXPECT_EQ(kIsOverridingUserAgent,
249             new_navigation_entry->GetIsOverridingUserAgent());
250   base::string16 search_terms;
251   new_navigation_entry->GetExtraData(kSearchTermsKey, &search_terms);
252   EXPECT_EQ(kSearchTerms, search_terms);
253   EXPECT_EQ(kHttpStatusCode, new_navigation_entry->GetHttpStatusCode());
254   ASSERT_EQ(3U, new_navigation_entry->GetRedirectChain().size());
255   EXPECT_EQ(kRedirectURL0, new_navigation_entry->GetRedirectChain()[0]);
256   EXPECT_EQ(kRedirectURL1, new_navigation_entry->GetRedirectChain()[1]);
257   EXPECT_EQ(kVirtualURL, new_navigation_entry->GetRedirectChain()[2]);
258 }
259
260 // Create a NavigationEntry, convert it to a SerializedNavigationEntry, then
261 // create a sync protocol buffer from it.  The protocol buffer should
262 // have matching fields to the NavigationEntry (when applicable).
263 TEST(SerializedNavigationEntryTest, ToSyncData) {
264   const scoped_ptr<content::NavigationEntry> navigation_entry(
265       MakeNavigationEntryForTest());
266
267   const SerializedNavigationEntry& navigation =
268       SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry);
269
270   const sync_pb::TabNavigation sync_data = navigation.ToSyncData();
271
272   EXPECT_EQ(kVirtualURL.spec(), sync_data.virtual_url());
273   EXPECT_EQ(kReferrer.url.spec(), sync_data.referrer());
274   EXPECT_EQ(kTitle, base::ASCIIToUTF16(sync_data.title()));
275   EXPECT_TRUE(sync_data.state().empty());
276   EXPECT_EQ(sync_pb::SyncEnums_PageTransition_AUTO_SUBFRAME,
277             sync_data.page_transition());
278   EXPECT_TRUE(sync_data.has_redirect_type());
279   EXPECT_EQ(navigation_entry->GetUniqueID(), sync_data.unique_id());
280   EXPECT_EQ(syncer::TimeToProtoTime(kTimestamp), sync_data.timestamp_msec());
281   EXPECT_EQ(kTimestamp.ToInternalValue(), sync_data.global_id());
282   EXPECT_EQ(kFaviconURL.spec(), sync_data.favicon_url());
283   EXPECT_EQ(kHttpStatusCode, sync_data.http_status_code());
284   // The proto navigation redirects don't include the final chain entry
285   // (because it didn't redirect) so the lengths should differ by 1.
286   ASSERT_EQ(3, sync_data.navigation_redirect_size() + 1);
287   EXPECT_EQ(navigation_entry->GetRedirectChain()[0].spec(),
288             sync_data.navigation_redirect(0).url());
289   EXPECT_EQ(navigation_entry->GetRedirectChain()[1].spec(),
290             sync_data.navigation_redirect(1).url());
291   EXPECT_FALSE(sync_data.has_last_navigation_redirect_url());
292 }
293
294 // Test that the last_navigation_redirect_url is set when needed.
295 // This test is just like the above, but with a different virtual_url.
296 // Create a NavigationEntry, convert it to a SerializedNavigationEntry, then
297 // create a sync protocol buffer from it.  The protocol buffer should
298 // have a last_navigation_redirect_url.
299 TEST(SerializedNavigationEntryTest, LastNavigationRedirectUrl) {
300   const scoped_ptr<content::NavigationEntry> navigation_entry(
301       MakeNavigationEntryForTest());
302
303   navigation_entry->SetVirtualURL(kOtherURL);
304
305   const SerializedNavigationEntry& navigation =
306       SerializedNavigationEntry::FromNavigationEntry(kIndex, *navigation_entry);
307
308   const sync_pb::TabNavigation sync_data = navigation.ToSyncData();
309
310   EXPECT_TRUE(sync_data.has_last_navigation_redirect_url());
311   EXPECT_EQ(kVirtualURL.spec(), sync_data.last_navigation_redirect_url());
312
313   // The redirect chain should be the same as in the above test.
314   ASSERT_EQ(3, sync_data.navigation_redirect_size() + 1);
315   EXPECT_EQ(navigation_entry->GetRedirectChain()[0].spec(),
316             sync_data.navigation_redirect(0).url());
317   EXPECT_EQ(navigation_entry->GetRedirectChain()[1].spec(),
318             sync_data.navigation_redirect(1).url());
319 }
320
321 // Ensure all transition types and qualifiers are converted to/from the sync
322 // SerializedNavigationEntry representation properly.
323 TEST(SerializedNavigationEntryTest, TransitionTypes) {
324   scoped_ptr<content::NavigationEntry> navigation_entry(
325       MakeNavigationEntryForTest());
326   for (uint32 core_type = content::PAGE_TRANSITION_LINK;
327        core_type != content::PAGE_TRANSITION_LAST_CORE; ++core_type) {
328     // Because qualifier is a uint32, left shifting will eventually overflow
329     // and hit zero again. SERVER_REDIRECT, as the last qualifier and also
330     // in place of the sign bit, is therefore the last transition before
331     // breaking.
332     for (uint32 qualifier = content::PAGE_TRANSITION_FORWARD_BACK;
333          qualifier != 0; qualifier <<= 1) {
334       if (qualifier == 0x08000000)
335         continue;  // 0x08000000 is not a valid qualifier.
336       content::PageTransition transition =
337           static_cast<content::PageTransition>(core_type | qualifier);
338
339       navigation_entry->SetTransitionType(transition);
340       const SerializedNavigationEntry& navigation =
341           SerializedNavigationEntry::FromNavigationEntry(kIndex,
342                                                          *navigation_entry);
343       const sync_pb::TabNavigation& sync_data = navigation.ToSyncData();
344       const SerializedNavigationEntry& constructed_nav =
345           SerializedNavigationEntry::FromSyncData(kIndex, sync_data);
346       const content::PageTransition constructed_transition =
347           constructed_nav.transition_type();
348
349       EXPECT_EQ(transition, constructed_transition);
350     }
351   }
352 }
353
354 // Tests that the input data is sanitized when a SerializedNavigationEntry
355 // is created from a pickle format.
356 TEST(SerializedNavigationEntryTest, Sanitize) {
357   sync_pb::TabNavigation sync_data = MakeSyncDataForTest();
358
359   sync_data.set_referrer_policy(blink::WebReferrerPolicyNever);
360   content::PageState page_state =
361       content::PageState::CreateFromURL(kVirtualURL);
362   sync_data.set_state(page_state.ToEncodedData());
363
364   const SerializedNavigationEntry& navigation =
365       SerializedNavigationEntry::FromSyncData(kIndex, sync_data);
366
367   EXPECT_EQ(kIndex, navigation.index());
368   EXPECT_EQ(kUniqueID, navigation.unique_id());
369   EXPECT_EQ(GURL(), navigation.referrer().url);
370   EXPECT_EQ(blink::WebReferrerPolicyDefault, navigation.referrer().policy);
371   EXPECT_EQ(kVirtualURL, navigation.virtual_url());
372   EXPECT_EQ(kTitle, navigation.title());
373   EXPECT_EQ(page_state, navigation.page_state());
374   EXPECT_EQ(kTransitionType, navigation.transition_type());
375   EXPECT_FALSE(navigation.has_post_data());
376   EXPECT_EQ(-1, navigation.post_id());
377   EXPECT_EQ(GURL(), navigation.original_request_url());
378   EXPECT_FALSE(navigation.is_overriding_user_agent());
379   EXPECT_TRUE(navigation.timestamp().is_null());
380   EXPECT_EQ(kSearchTerms, navigation.search_terms());
381   EXPECT_EQ(kFaviconURL, navigation.favicon_url());
382   EXPECT_EQ(kHttpStatusCode, navigation.http_status_code());
383
384   content::PageState empty_state;
385   EXPECT_TRUE(empty_state.Equals(empty_state.RemoveReferrer()));
386 }
387
388 }  // namespace
389 }  // namespace sessions