Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / ios / web / navigation / crw_session_entry_unittest.mm
blob210afc6974286724505db1182db96a0fb983732d
1 // Copyright 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 #import <Foundation/Foundation.h>
7 #include "base/mac/scoped_nsobject.h"
8 #include "base/strings/sys_string_conversions.h"
9 #import "ios/testing/ocmock_complex_type_helper.h"
10 #import "ios/web/navigation/crw_session_entry.h"
11 #include "ios/web/navigation/navigation_item_impl.h"
12 #include "ios/web/public/referrer.h"
13 #import "net/base/mac/url_conversions.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/gtest_mac.h"
16 #include "testing/platform_test.h"
17 #import "third_party/ocmock/OCMock/OCMock.h"
18 #include "third_party/ocmock/gtest_support.h"
19 #include "ui/base/page_transition_types.h"
21 @interface CRWSessionEntry (ExposedForTesting)
22 + (web::PageScrollState)scrollStateFromDictionary:(NSDictionary*)dictionary;
23 + (NSDictionary*)dictionaryFromScrollState:
24     (const web::PageScrollState&)scrollState;
25 @end
27 static NSString* const kHTTPHeaderKey1 = @"key1";
28 static NSString* const kHTTPHeaderKey2 = @"key2";
29 static NSString* const kHTTPHeaderValue1 = @"value1";
30 static NSString* const kHTTPHeaderValue2 = @"value2";
32 class CRWSessionEntryTest : public PlatformTest {
33  public:
34   static void expectEqualSessionEntries(CRWSessionEntry* entry1,
35                                         CRWSessionEntry* entry2,
36                                         ui::PageTransition transition);
38  protected:
39   void SetUp() override {
40     GURL url("http://init.test");
41     ui::PageTransition transition =
42         ui::PAGE_TRANSITION_AUTO_BOOKMARK;
43     sessionEntry_.reset([[CRWSessionEntry alloc] initWithUrl:url
44                                                     referrer:web::Referrer()
45                                                   transition:transition
46                                          useDesktopUserAgent:NO
47                                            rendererInitiated:NO]);
48     [sessionEntry_ navigationItem]->SetTimestamp(base::Time::Now());
49     [sessionEntry_ addHTTPHeaders:@{ kHTTPHeaderKey1 : kHTTPHeaderValue1 }];
50     [sessionEntry_
51         setPOSTData:[@"Test data" dataUsingEncoding:NSUTF8StringEncoding]];
52   }
53   void TearDown() override { sessionEntry_.reset(); }
55  protected:
56   base::scoped_nsobject<CRWSessionEntry> sessionEntry_;
59 @implementation OCMockComplexTypeHelper (CRWSessionEntryTest)
60 typedef void (^encodeBytes_length_forKey_block)(
61     const uint8_t*, NSUInteger, NSString*);
62 - (void)encodeBytes:(const uint8_t*)bytes
63              length:(NSUInteger)length
64              forKey:(NSString*)key {
65   static_cast<encodeBytes_length_forKey_block>([self blockForSelector:_cmd])(
66       bytes, length, key);
69 typedef const uint8_t* (^decodeBytesForKeyBlock)(NSString*, NSUInteger*);
70 - (const uint8_t*)decodeBytesForKey:(NSString*)key
71                       returnedLength:(NSUInteger*)lengthp {
72   return static_cast<decodeBytesForKeyBlock>([self blockForSelector:_cmd])(
73       key, lengthp);
75 @end
77 void CRWSessionEntryTest::expectEqualSessionEntries(
78     CRWSessionEntry* entry1,
79     CRWSessionEntry* entry2,
80     ui::PageTransition transition) {
81   EXPECT_EQ(entry1.index, entry2.index);
82   web::NavigationItem* navItem1 = entry1.navigationItem;
83   web::NavigationItem* navItem2 = entry2.navigationItem;
84   // url is not compared because it could differ after copy or archive.
85   EXPECT_EQ(navItem1->GetVirtualURL(), navItem2->GetVirtualURL());
86   EXPECT_EQ(navItem1->GetReferrer().url, navItem2->GetReferrer().url);
87   EXPECT_EQ(navItem1->GetTimestamp(), navItem2->GetTimestamp());
88   EXPECT_EQ(navItem1->GetTitle(), navItem2->GetTitle());
89   EXPECT_EQ(navItem1->GetPageScrollState(), navItem2->GetPageScrollState());
90   EXPECT_EQ(entry1.useDesktopUserAgent, entry2.useDesktopUserAgent);
91   EXPECT_EQ(entry1.usedDataReductionProxy, entry2.usedDataReductionProxy);
92   EXPECT_EQ(navItem2->GetTransitionType(), transition);
93   EXPECT_NSEQ(entry1.httpHeaders, entry2.httpHeaders);
94   EXPECT_TRUE((!entry1.POSTData && !entry2.POSTData) ||
95               [entry1.POSTData isEqualToData:entry2.POSTData]);
96   EXPECT_EQ(entry1.skipResubmitDataConfirmation,
97             entry2.skipResubmitDataConfirmation);
100 TEST_F(CRWSessionEntryTest, Description) {
101   [sessionEntry_ navigationItem]->SetTitle(base::SysNSStringToUTF16(@"Title"));
102   EXPECT_NSEQ([sessionEntry_ description], @"url:http://init.test/ "
103               @"originalurl:http://init.test/ " @"title:Title " @"transition:2 "
104               @"scrollState:{ scrollOffset:(nan, nan), zoomScaleRange:(nan, "
105               @"nan), zoomScale:nan } " @"desktopUA:0 " @"proxy:0");
108 TEST_F(CRWSessionEntryTest, InitWithCoder) {
109   web::NavigationItem* item = [sessionEntry_ navigationItem];
110   item->SetVirtualURL(GURL("http://user.friendly"));
111   item->SetTitle(base::SysNSStringToUTF16(@"Title"));
112   int index = sessionEntry_.get().index;
113   // Old serialized entries have no timestamp.
114   item->SetTimestamp(base::Time::FromInternalValue(0));
116   NSURL* virtualUrl = net::NSURLWithGURL(item->GetVirtualURL());
117   NSURL* referrer = net::NSURLWithGURL(item->GetReferrer().url);
118   NSString* title = base::SysUTF16ToNSString(item->GetTitle());
119   base::scoped_nsobject<id> decoder([[OCMockComplexTypeHelper alloc]
120       initWithRepresentedObject:[OCMockObject mockForClass:[NSCoder class]]]);
122   decodeBytesForKeyBlock block = ^ const uint8_t* (NSString* key,
123                                                    NSUInteger* length) {
124       *length = 0;
125       return NULL;
126   };
128   [[[decoder stub] andReturnValue:[NSNumber numberWithBool:NO]]
129       containsValueForKey:[OCMArg any]];
131   [decoder onSelector:@selector(decodeBytesForKey:returnedLength:)
132       callBlockExpectation:block];
133   [[[decoder expect] andReturnValue:OCMOCK_VALUE(index)]
134       decodeIntForKey:@"index"];
135   [[[decoder expect] andReturn:virtualUrl]
136       decodeObjectForKey:@"virtualUrl"];
137   [[[decoder expect] andReturn:referrer]
138       decodeObjectForKey:@"referrer"];
139   [[[decoder expect] andReturn:title]
140       decodeObjectForKey:@"title"];
141   const web::PageScrollState& scrollState =
142       [sessionEntry_ navigationItem]->GetPageScrollState();
143   NSDictionary* serializedScrollState =
144       [CRWSessionEntry dictionaryFromScrollState:scrollState];
145   [[[decoder expect] andReturn:serializedScrollState]
146       decodeObjectForKey:@"state"];
147   BOOL useDesktopUserAgent = sessionEntry_.get().useDesktopUserAgent;
148   [[[decoder expect] andReturnValue:OCMOCK_VALUE(useDesktopUserAgent)]
149       decodeBoolForKey:@"useDesktopUserAgent"];
150   BOOL usedDataReductionProxy = sessionEntry_.get().usedDataReductionProxy;
151   [[[decoder expect] andReturnValue:OCMOCK_VALUE(usedDataReductionProxy)]
152       decodeBoolForKey:@"usedDataReductionProxy"];
153   [[[decoder expect] andReturn:sessionEntry_.get().httpHeaders]
154       decodeObjectForKey:@"httpHeaders"];
155   [[[decoder expect] andReturn:sessionEntry_.get().POSTData]
156       decodeObjectForKey:@"POSTData"];
157   BOOL skipResubmitDataConfirmation =
158       sessionEntry_.get().skipResubmitDataConfirmation;
159   [[[decoder expect] andReturnValue:OCMOCK_VALUE(skipResubmitDataConfirmation)]
160       decodeBoolForKey:@"skipResubmitDataConfirmation"];
162   base::scoped_nsobject<CRWSessionEntry> newSessionEntry(
163       [[CRWSessionEntry alloc] initWithCoder:decoder]);
164   web::NavigationItem* newItem = [newSessionEntry navigationItem];
166   EXPECT_OCMOCK_VERIFY(decoder);
167   expectEqualSessionEntries(sessionEntry_, newSessionEntry,
168                             ui::PAGE_TRANSITION_RELOAD);
169   EXPECT_NE(item->GetURL(), newItem->GetURL());
170   EXPECT_EQ(item->GetVirtualURL(), newItem->GetURL());
173 TEST_F(CRWSessionEntryTest, InitWithCoderNewStyle) {
174   web::NavigationItem* item = [sessionEntry_ navigationItem];
175   item->SetVirtualURL(GURL("http://user.friendly"));
176   item->SetTitle(base::SysNSStringToUTF16(@"Title"));
177   int index = sessionEntry_.get().index;
178   int64 timestamp = item->GetTimestamp().ToInternalValue();
180   std::string virtualUrl = item->GetVirtualURL().spec();
181   std::string referrerUrl = item->GetReferrer().url.spec();
182   NSString* title = base::SysUTF16ToNSString(item->GetTitle());
183   base::scoped_nsobject<id> decoder([[OCMockComplexTypeHelper alloc]
184       initWithRepresentedObject:[OCMockObject mockForClass:[NSCoder class]]]);
186   const std::string emptyString;
187   decodeBytesForKeyBlock block =  ^ const uint8_t* (NSString* key,
188                                                     NSUInteger* length) {
189       const std::string *value = &emptyString;
190       if ([key isEqualToString:@"virtualUrlString"])
191         value = &virtualUrl;
192       else if ([key isEqualToString:@"referrerUrlString"])
193         value = &referrerUrl;
194       else
195         EXPECT_TRUE(false);
197       *length = value->size();
198       return reinterpret_cast<const uint8_t*>(value->data());
199   };
201   [decoder onSelector:@selector(decodeBytesForKey:returnedLength:)
202       callBlockExpectation:block];
203   [[[decoder stub] andReturnValue:[NSNumber numberWithBool:YES]]
204       containsValueForKey:[OCMArg any]];
205   [[[decoder expect] andReturnValue:OCMOCK_VALUE(index)]
206       decodeIntForKey:@"index"];
207   web::ReferrerPolicy expectedPolicy = item->GetReferrer().policy;
208   [[[decoder expect]
209       andReturnValue:OCMOCK_VALUE(expectedPolicy)]
210       decodeIntForKey:@"referrerPolicy"];
211   [[[decoder expect] andReturnValue:OCMOCK_VALUE(timestamp)]
212       decodeInt64ForKey:@"timestamp"];
213   [[[decoder expect] andReturn:title]
214       decodeObjectForKey:@"title"];
215   const web::PageScrollState& scrollState =
216       [sessionEntry_ navigationItem]->GetPageScrollState();
217   NSDictionary* serializedScrollState =
218       [CRWSessionEntry dictionaryFromScrollState:scrollState];
219   [[[decoder expect] andReturn:serializedScrollState]
220       decodeObjectForKey:@"state"];
221   BOOL useDesktopUserAgent = sessionEntry_.get().useDesktopUserAgent;
222   [[[decoder expect] andReturnValue:OCMOCK_VALUE(useDesktopUserAgent)]
223       decodeBoolForKey:@"useDesktopUserAgent"];
224   BOOL usedDataReductionProxy = sessionEntry_.get().usedDataReductionProxy;
225   [[[decoder expect] andReturnValue:OCMOCK_VALUE(usedDataReductionProxy)]
226       decodeBoolForKey:@"usedDataReductionProxy"];
227   [[[decoder expect] andReturn:sessionEntry_.get().httpHeaders]
228       decodeObjectForKey:@"httpHeaders"];
229   [[[decoder expect] andReturn:sessionEntry_.get().POSTData]
230       decodeObjectForKey:@"POSTData"];
231   BOOL skipResubmitDataConfirmation =
232       sessionEntry_.get().skipResubmitDataConfirmation;
233   [[[decoder expect] andReturnValue:OCMOCK_VALUE(skipResubmitDataConfirmation)]
234       decodeBoolForKey:@"skipResubmitDataConfirmation"];
236   base::scoped_nsobject<CRWSessionEntry> newSessionEntry(
237       [[CRWSessionEntry alloc] initWithCoder:decoder]);
238   web::NavigationItem* newItem = [newSessionEntry navigationItem];
240   EXPECT_OCMOCK_VERIFY(decoder);
241   expectEqualSessionEntries(sessionEntry_, newSessionEntry,
242                             ui::PAGE_TRANSITION_RELOAD);
243   EXPECT_NE(item->GetURL(), newItem->GetURL());
244   EXPECT_EQ(item->GetVirtualURL(), newItem->GetVirtualURL());
247 TEST_F(CRWSessionEntryTest, EncodeDecode) {
248   NSData *data =
249       [NSKeyedArchiver archivedDataWithRootObject:sessionEntry_];
250   id decoded = [NSKeyedUnarchiver unarchiveObjectWithData:data];
252   expectEqualSessionEntries(sessionEntry_, decoded,
253                             ui::PAGE_TRANSITION_RELOAD);
256 TEST_F(CRWSessionEntryTest, EncodeWithCoder) {
257   web::NavigationItem* item = [sessionEntry_ navigationItem];
258   NSString* title = base::SysUTF16ToNSString(item->GetTitle());
260   base::scoped_nsobject<id> coder([[OCMockComplexTypeHelper alloc]
261       initWithRepresentedObject:[OCMockObject mockForClass:[NSCoder class]]]);
263   encodeBytes_length_forKey_block block = ^(const uint8_t* bytes,
264                                             NSUInteger length,
265                                             NSString* key) {
266       if ([key isEqualToString:@"virtualUrlString"]) {
267         ASSERT_EQ(item->GetVirtualURL().spec(),
268                   std::string(reinterpret_cast<const char*>(bytes), length));
269         return;
270       } else if ([key isEqualToString:@"referrerUrlString"]) {
271         ASSERT_EQ(item->GetReferrer().url.spec(),
272                   std::string(reinterpret_cast<const char*>(bytes), length));
273         return;
274       }
275       FAIL();
276   };
277   [coder onSelector:@selector(encodeBytes:length:forKey:)
278       callBlockExpectation:block];
279   [[coder expect] encodeInt:[sessionEntry_ index] forKey:@"index"];
280   [[coder expect] encodeInt:item->GetReferrer().policy
281                      forKey:@"referrerPolicy"];
282   [[coder expect] encodeInt64:item->GetTimestamp().ToInternalValue()
283                        forKey:@"timestamp"];
284   [[coder expect] encodeObject:title forKey:@"title"];
285   const web::PageScrollState& scrollState =
286       [sessionEntry_ navigationItem]->GetPageScrollState();
287   NSDictionary* serializedScrollState =
288       [CRWSessionEntry dictionaryFromScrollState:scrollState];
289   [[coder expect] encodeObject:serializedScrollState forKey:@"state"];
290   [[coder expect] encodeBool:[sessionEntry_ useDesktopUserAgent]
291                       forKey:@"useDesktopUserAgent"];
292   [[coder expect] encodeBool:[sessionEntry_ usedDataReductionProxy]
293                       forKey:@"usedDataReductionProxy"];
294   [[coder expect] encodeObject:[sessionEntry_ httpHeaders]
295                         forKey:@"httpHeaders"];
296   [[coder expect] encodeObject:[sessionEntry_ POSTData] forKey:@"POSTData"];
297   [[coder expect] encodeBool:[sessionEntry_ skipResubmitDataConfirmation]
298                       forKey:@"skipResubmitDataConfirmation"];
299   [sessionEntry_ encodeWithCoder:coder];
300   EXPECT_OCMOCK_VERIFY(coder);
303 TEST_F(CRWSessionEntryTest, CodingEncoding) {
304   web::NavigationItem* item = [sessionEntry_ navigationItem];
305   item->SetVirtualURL(GURL("http://user.friendly"));
306   NSData* data = [NSKeyedArchiver archivedDataWithRootObject:sessionEntry_];
307   EXPECT_TRUE(data != nil);
308   CRWSessionEntry* unarchivedSessionEntry =
309       [NSKeyedUnarchiver unarchiveObjectWithData:data];
310   ASSERT_TRUE(unarchivedSessionEntry != nil);
311   web::NavigationItem* unarchivedItem = [unarchivedSessionEntry navigationItem];
312   expectEqualSessionEntries(sessionEntry_, unarchivedSessionEntry,
313                             ui::PAGE_TRANSITION_RELOAD);
314   EXPECT_EQ(unarchivedItem->GetURL(), item->GetVirtualURL());
315   EXPECT_NE(unarchivedItem->GetURL(), item->GetURL());
318 TEST_F(CRWSessionEntryTest, CopyWithZone) {
319   CRWSessionEntry* sessionEntry2 = [sessionEntry_ copy];
320   EXPECT_NE(sessionEntry_, sessionEntry2);
321   expectEqualSessionEntries(
322       sessionEntry_, sessionEntry2,
323       [sessionEntry_ navigationItem]->GetTransitionType());
326 TEST_F(CRWSessionEntryTest, EmptyVirtualUrl) {
327   EXPECT_EQ(GURL("http://init.test/"),
328             [sessionEntry_ navigationItem]->GetURL());
331 TEST_F(CRWSessionEntryTest, NonEmptyVirtualUrl) {
332   web::NavigationItem* item = [sessionEntry_ navigationItem];
333   item->SetVirtualURL(GURL("http://user.friendly"));
334   EXPECT_EQ(GURL("http://user.friendly/"), item->GetVirtualURL());
335   EXPECT_EQ(GURL("http://init.test/"), item->GetURL());
338 TEST_F(CRWSessionEntryTest, EmptyDescription) {
339   EXPECT_GT([[sessionEntry_ description] length], 0U);
342 TEST_F(CRWSessionEntryTest, CreateWithNavigationItem) {
343   int index = 5;  // Just pick something non-zero.
344   GURL url("http://www.virtualurl.com");
345   web::Referrer referrer(GURL("http://www.referrer.com"),
346                          web::ReferrerPolicyDefault);
347   base::string16 title = base::SysNSStringToUTF16(@"Title");
348   std::string state;
349   ui::PageTransition transition = ui::PAGE_TRANSITION_GENERATED;
351   scoped_ptr<web::NavigationItem> navigation_item(
352       new web::NavigationItemImpl());
353   navigation_item->SetURL(url);
354   navigation_item->SetReferrer(referrer);
355   navigation_item->SetTitle(title);
356   navigation_item->SetTransitionType(transition);
358   base::scoped_nsobject<CRWSessionEntry> sessionEntry(
359       [[CRWSessionEntry alloc] initWithNavigationItem:navigation_item.Pass()
360                                                 index:index]);
361   web::NavigationItem* item = [sessionEntry navigationItem];
362   // Validate everything was set correctly.
363   EXPECT_EQ(sessionEntry.get().index, index);
364   // Desktop only persists the virtual url, all three fields are initialized
365   // by it.
366   EXPECT_EQ(item->GetURL(), url);
367   EXPECT_EQ(item->GetVirtualURL(), url);
368   EXPECT_EQ(sessionEntry.get().originalUrl, url);
369   EXPECT_EQ(item->GetReferrer().url, referrer.url);
370   EXPECT_EQ(item->GetTitle(), title);
371   EXPECT_EQ(item->GetTransitionType(), transition);
374 TEST_F(CRWSessionEntryTest, AddHTTPHeaders) {
375   EXPECT_NSEQ(@{ kHTTPHeaderKey1 : kHTTPHeaderValue1 },
376               [sessionEntry_ httpHeaders]);
378   [sessionEntry_ addHTTPHeaders:@{ kHTTPHeaderKey1 : kHTTPHeaderValue2 }];
379   EXPECT_NSEQ(@{ kHTTPHeaderKey1 : kHTTPHeaderValue2 },
380               [sessionEntry_ httpHeaders]);
382   [sessionEntry_ addHTTPHeaders:@{ kHTTPHeaderKey2 : kHTTPHeaderValue1 }];
383   NSDictionary* expected = @{ kHTTPHeaderKey1 : kHTTPHeaderValue2,
384                               kHTTPHeaderKey2 : kHTTPHeaderValue1 };
385   EXPECT_NSEQ(expected, [sessionEntry_ httpHeaders]);
388 TEST_F(CRWSessionEntryTest, RemoveHTTPHeaderForKey) {
389   NSDictionary* httpHeaders = @{ kHTTPHeaderKey1 : kHTTPHeaderValue1,
390                                  kHTTPHeaderKey2 : kHTTPHeaderValue2 };
391   [sessionEntry_ addHTTPHeaders:httpHeaders];
392   EXPECT_NSEQ(httpHeaders, [sessionEntry_ httpHeaders]);
394   [sessionEntry_ removeHTTPHeaderForKey:kHTTPHeaderKey1];
395   EXPECT_NSEQ(@{ kHTTPHeaderKey2 : kHTTPHeaderValue2 },
396               [sessionEntry_ httpHeaders]);
398   [sessionEntry_ removeHTTPHeaderForKey:kHTTPHeaderKey2];
399   EXPECT_TRUE([sessionEntry_ httpHeaders] == nil);