[Android WebViewShell] Add inclusion test for webview exposed stable interfaces.
[chromium-blink-merge.git] / ios / web / navigation / crw_session_entry_unittest.mm
blob8ffacf7797fdaeb7b45e5864c238938727375c44
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)pageStateFromDictionary:(NSDictionary*)dictionary;
23 + (NSDictionary*)dictionaryFromPageDisplayState:
24     (const web::PageDisplayState&)displayState;
25 @end
27 class CRWSessionEntryTest : public PlatformTest {
28  public:
29   static void expectEqualSessionEntries(CRWSessionEntry* entry1,
30                                         CRWSessionEntry* entry2,
31                                         ui::PageTransition transition);
33  protected:
34   void SetUp() override {
35     GURL url("http://init.test");
36     ui::PageTransition transition =
37         ui::PAGE_TRANSITION_AUTO_BOOKMARK;
38     scoped_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl());
39     item->SetURL(url);
40     item->SetTransitionType(transition);
41     item->SetTimestamp(base::Time::Now());
42     item->SetPostData([@"Test data" dataUsingEncoding:NSUTF8StringEncoding]);
43     sessionEntry_.reset(
44         [[CRWSessionEntry alloc] initWithNavigationItem:item.Pass()]);
45   }
46   void TearDown() override { sessionEntry_.reset(); }
48  protected:
49   base::scoped_nsobject<CRWSessionEntry> sessionEntry_;
52 @implementation OCMockComplexTypeHelper (CRWSessionEntryTest)
53 typedef void (^encodeBytes_length_forKey_block)(
54     const uint8_t*, NSUInteger, NSString*);
55 - (void)encodeBytes:(const uint8_t*)bytes
56              length:(NSUInteger)length
57              forKey:(NSString*)key {
58   static_cast<encodeBytes_length_forKey_block>([self blockForSelector:_cmd])(
59       bytes, length, key);
62 typedef const uint8_t* (^decodeBytesForKeyBlock)(NSString*, NSUInteger*);
63 - (const uint8_t*)decodeBytesForKey:(NSString*)key
64                       returnedLength:(NSUInteger*)lengthp {
65   return static_cast<decodeBytesForKeyBlock>([self blockForSelector:_cmd])(
66       key, lengthp);
68 @end
70 void CRWSessionEntryTest::expectEqualSessionEntries(
71     CRWSessionEntry* entry1,
72     CRWSessionEntry* entry2,
73     ui::PageTransition transition) {
74   web::NavigationItemImpl* navItem1 = entry1.navigationItemImpl;
75   web::NavigationItemImpl* navItem2 = entry2.navigationItemImpl;
76   // url is not compared because it could differ after copy or archive.
77   EXPECT_EQ(navItem1->GetVirtualURL(), navItem2->GetVirtualURL());
78   EXPECT_EQ(navItem1->GetReferrer().url, navItem2->GetReferrer().url);
79   EXPECT_EQ(navItem1->GetTimestamp(), navItem2->GetTimestamp());
80   EXPECT_EQ(navItem1->GetTitle(), navItem2->GetTitle());
81   EXPECT_EQ(navItem1->GetPageDisplayState(), navItem2->GetPageDisplayState());
82   EXPECT_EQ(navItem1->ShouldSkipResubmitDataConfirmation(),
83             navItem2->ShouldSkipResubmitDataConfirmation());
84   EXPECT_EQ(navItem1->IsOverridingUserAgent(),
85             navItem2->IsOverridingUserAgent());
86   EXPECT_TRUE((!navItem1->HasPostData() && !navItem2->HasPostData()) ||
87               [navItem1->GetPostData() isEqualToData:navItem2->GetPostData()]);
88   EXPECT_EQ(navItem2->GetTransitionType(), transition);
89   EXPECT_NSEQ(navItem1->GetHttpRequestHeaders(),
90               navItem2->GetHttpRequestHeaders());
93 TEST_F(CRWSessionEntryTest, Description) {
94   [sessionEntry_ navigationItem]->SetTitle(base::SysNSStringToUTF16(@"Title"));
95   EXPECT_NSEQ([sessionEntry_ description],
96               @"url:http://init.test/ originalurl:http://init.test/ "
97               @"title:Title transition:2 displayState:{ scrollOffset:(nan, "
98               @"nan), zoomScaleRange:(nan, nan), zoomScale:nan } desktopUA:0");
101 TEST_F(CRWSessionEntryTest, InitWithCoder) {
102   web::NavigationItem* item = [sessionEntry_ navigationItem];
103   item->SetVirtualURL(GURL("http://user.friendly"));
104   item->SetTitle(base::SysNSStringToUTF16(@"Title"));
105   // Old serialized entries have no timestamp.
106   item->SetTimestamp(base::Time::FromInternalValue(0));
108   NSURL* virtualUrl = net::NSURLWithGURL(item->GetVirtualURL());
109   NSURL* referrer = net::NSURLWithGURL(item->GetReferrer().url);
110   NSString* title = base::SysUTF16ToNSString(item->GetTitle());
111   base::scoped_nsobject<id> decoder([[OCMockComplexTypeHelper alloc]
112       initWithRepresentedObject:[OCMockObject mockForClass:[NSCoder class]]]);
114   decodeBytesForKeyBlock block = ^ const uint8_t* (NSString* key,
115                                                    NSUInteger* length) {
116       *length = 0;
117       return NULL;
118   };
120   [[[decoder stub] andReturnValue:[NSNumber numberWithBool:NO]]
121       containsValueForKey:[OCMArg any]];
123   [decoder onSelector:@selector(decodeBytesForKey:returnedLength:)
124       callBlockExpectation:block];
125   [[[decoder expect] andReturn:virtualUrl]
126       decodeObjectForKey:web::kSessionEntryURLDeperecatedKey];
127   [[[decoder expect] andReturn:referrer]
128       decodeObjectForKey:web::kSessionEntryReferrerURLDeprecatedKey];
129   [[[decoder expect] andReturn:title]
130       decodeObjectForKey:web::kSessionEntryTitleKey];
131   const web::PageDisplayState& pageState =
132       [sessionEntry_ navigationItem]->GetPageDisplayState();
133   NSDictionary* serializedPageDisplayState =
134       [CRWSessionEntry dictionaryFromPageDisplayState:pageState];
135   [[[decoder expect] andReturn:serializedPageDisplayState]
136       decodeObjectForKey:web::kSessionEntryPageScrollStateKey];
137   BOOL useDesktopUserAgent =
138       [sessionEntry_ navigationItem]->IsOverridingUserAgent();
139   [[[decoder expect] andReturnValue:OCMOCK_VALUE(useDesktopUserAgent)]
140       decodeBoolForKey:web::kSessionEntryUseDesktopUserAgentKey];
141   NSDictionary* requestHeaders =
142       [sessionEntry_ navigationItem]->GetHttpRequestHeaders();
143   [[[decoder expect] andReturn:requestHeaders]
144       decodeObjectForKey:web::kSessionEntryHTTPRequestHeadersKey];
145   [[[decoder expect]
146       andReturn:[sessionEntry_ navigationItemImpl]->GetPostData()]
147       decodeObjectForKey:web::kSessionEntryPOSTDataKey];
148   BOOL skipResubmitDataConfirmation =
149       [sessionEntry_ navigationItemImpl]->ShouldSkipResubmitDataConfirmation();
150   [[[decoder expect] andReturnValue:OCMOCK_VALUE(skipResubmitDataConfirmation)]
151       decodeBoolForKey:web::kSessionEntrySkipResubmitConfirmationKey];
153   base::scoped_nsobject<CRWSessionEntry> newSessionEntry(
154       [[CRWSessionEntry alloc] initWithCoder:decoder]);
155   web::NavigationItem* newItem = [newSessionEntry navigationItem];
157   EXPECT_OCMOCK_VERIFY(decoder);
158   expectEqualSessionEntries(sessionEntry_, newSessionEntry,
159                             ui::PAGE_TRANSITION_RELOAD);
160   EXPECT_NE(item->GetURL(), newItem->GetURL());
161   EXPECT_EQ(item->GetVirtualURL(), newItem->GetURL());
164 TEST_F(CRWSessionEntryTest, InitWithCoderNewStyle) {
165   web::NavigationItem* item = [sessionEntry_ navigationItem];
166   item->SetVirtualURL(GURL("http://user.friendly"));
167   item->SetTitle(base::SysNSStringToUTF16(@"Title"));
168   int64 timestamp = item->GetTimestamp().ToInternalValue();
170   std::string virtualUrl = item->GetVirtualURL().spec();
171   std::string referrerUrl = item->GetReferrer().url.spec();
172   NSString* title = base::SysUTF16ToNSString(item->GetTitle());
173   base::scoped_nsobject<id> decoder([[OCMockComplexTypeHelper alloc]
174       initWithRepresentedObject:[OCMockObject mockForClass:[NSCoder class]]]);
176   const std::string emptyString;
177   decodeBytesForKeyBlock block =  ^ const uint8_t* (NSString* key,
178                                                     NSUInteger* length) {
179       const std::string *value = &emptyString;
180       if ([key isEqualToString:web::kSessionEntryURLKey])
181         value = &virtualUrl;
182       else if ([key isEqualToString:web::kSessionEntryReferrerURLKey])
183         value = &referrerUrl;
184       else
185         EXPECT_TRUE(false);
187       *length = value->size();
188       return reinterpret_cast<const uint8_t*>(value->data());
189   };
191   [decoder onSelector:@selector(decodeBytesForKey:returnedLength:)
192       callBlockExpectation:block];
193   [[[decoder stub] andReturnValue:[NSNumber numberWithBool:YES]]
194       containsValueForKey:[OCMArg any]];
195   web::ReferrerPolicy expectedPolicy = item->GetReferrer().policy;
196   [[[decoder expect] andReturnValue:OCMOCK_VALUE(expectedPolicy)]
197       decodeIntForKey:web::kSessionEntryReferrerPolicyKey];
198   [[[decoder expect] andReturnValue:OCMOCK_VALUE(timestamp)]
199       decodeInt64ForKey:web::kSessionEntryTimestampKey];
200   [[[decoder expect] andReturn:title]
201       decodeObjectForKey:web::kSessionEntryTitleKey];
202   const web::PageDisplayState& pageState =
203       [sessionEntry_ navigationItem]->GetPageDisplayState();
204   NSDictionary* serializedPageDisplayState =
205       [CRWSessionEntry dictionaryFromPageDisplayState:pageState];
206   [[[decoder expect] andReturn:serializedPageDisplayState]
207       decodeObjectForKey:web::kSessionEntryPageScrollStateKey];
208   BOOL useDesktopUserAgent =
209       [sessionEntry_ navigationItem]->IsOverridingUserAgent();
210   [[[decoder expect] andReturnValue:OCMOCK_VALUE(useDesktopUserAgent)]
211       decodeBoolForKey:web::kSessionEntryUseDesktopUserAgentKey];
212   NSDictionary* requestHeaders =
213       [sessionEntry_ navigationItem]->GetHttpRequestHeaders();
214   [[[decoder expect] andReturn:requestHeaders]
215       decodeObjectForKey:web::kSessionEntryHTTPRequestHeadersKey];
216   NSData* POSTData = [sessionEntry_ navigationItemImpl]->GetPostData();
217   [[[decoder expect] andReturn:POSTData]
218       decodeObjectForKey:web::kSessionEntryPOSTDataKey];
219   BOOL skipResubmitDataConfirmation =
220       [sessionEntry_ navigationItemImpl]->ShouldSkipResubmitDataConfirmation();
221   [[[decoder expect] andReturnValue:OCMOCK_VALUE(skipResubmitDataConfirmation)]
222       decodeBoolForKey:web::kSessionEntrySkipResubmitConfirmationKey];
224   base::scoped_nsobject<CRWSessionEntry> newSessionEntry(
225       [[CRWSessionEntry alloc] initWithCoder:decoder]);
226   web::NavigationItem* newItem = [newSessionEntry navigationItem];
228   EXPECT_OCMOCK_VERIFY(decoder);
229   expectEqualSessionEntries(sessionEntry_, newSessionEntry,
230                             ui::PAGE_TRANSITION_RELOAD);
231   EXPECT_NE(item->GetURL(), newItem->GetURL());
232   EXPECT_EQ(item->GetVirtualURL(), newItem->GetVirtualURL());
235 TEST_F(CRWSessionEntryTest, EncodeDecode) {
236   NSData *data =
237       [NSKeyedArchiver archivedDataWithRootObject:sessionEntry_];
238   id decoded = [NSKeyedUnarchiver unarchiveObjectWithData:data];
240   expectEqualSessionEntries(sessionEntry_, decoded,
241                             ui::PAGE_TRANSITION_RELOAD);
244 TEST_F(CRWSessionEntryTest, EncodeWithCoder) {
245   web::NavigationItem* item = [sessionEntry_ navigationItem];
246   NSString* title = base::SysUTF16ToNSString(item->GetTitle());
248   base::scoped_nsobject<id> coder([[OCMockComplexTypeHelper alloc]
249       initWithRepresentedObject:[OCMockObject mockForClass:[NSCoder class]]]);
251   encodeBytes_length_forKey_block block =
252       ^(const uint8_t* bytes, NSUInteger length, NSString* key) {
253         if ([key isEqualToString:web::kSessionEntryURLKey]) {
254           ASSERT_EQ(item->GetVirtualURL().spec(),
255                     std::string(reinterpret_cast<const char*>(bytes), length));
256           return;
257         } else if ([key isEqualToString:web::kSessionEntryReferrerURLKey]) {
258           ASSERT_EQ(item->GetReferrer().url.spec(),
259                     std::string(reinterpret_cast<const char*>(bytes), length));
260           return;
261         }
262         FAIL();
263       };
264   [coder onSelector:@selector(encodeBytes:length:forKey:)
265       callBlockExpectation:block];
266   [[coder expect] encodeInt:item->GetReferrer().policy
267                      forKey:web::kSessionEntryReferrerPolicyKey];
268   [[coder expect] encodeInt64:item->GetTimestamp().ToInternalValue()
269                        forKey:web::kSessionEntryTimestampKey];
270   [[coder expect] encodeObject:title forKey:web::kSessionEntryTitleKey];
271   const web::PageDisplayState& pageState =
272       [sessionEntry_ navigationItem]->GetPageDisplayState();
273   NSDictionary* serializedPageDisplayState =
274       [CRWSessionEntry dictionaryFromPageDisplayState:pageState];
275   [[coder expect] encodeObject:serializedPageDisplayState
276                         forKey:web::kSessionEntryPageScrollStateKey];
277   BOOL useDesktopUserAgent =
278       [sessionEntry_ navigationItem]->IsOverridingUserAgent();
279   [[coder expect] encodeBool:useDesktopUserAgent
280                       forKey:web::kSessionEntryUseDesktopUserAgentKey];
281   NSDictionary* requestHeaders =
282       [sessionEntry_ navigationItem]->GetHttpRequestHeaders();
283   [[coder expect] encodeObject:requestHeaders
284                         forKey:web::kSessionEntryHTTPRequestHeadersKey];
285   [[coder expect] encodeObject:[sessionEntry_ navigationItemImpl]->GetPostData()
286                         forKey:web::kSessionEntryPOSTDataKey];
287   BOOL skipResubmitDataConfirmation =
288       [sessionEntry_ navigationItemImpl]->ShouldSkipResubmitDataConfirmation();
289   [[coder expect] encodeBool:skipResubmitDataConfirmation
290                       forKey:web::kSessionEntrySkipResubmitConfirmationKey];
291   [sessionEntry_ encodeWithCoder:coder];
292   EXPECT_OCMOCK_VERIFY(coder);
295 TEST_F(CRWSessionEntryTest, CodingEncoding) {
296   web::NavigationItem* item = [sessionEntry_ navigationItem];
297   item->SetVirtualURL(GURL("http://user.friendly"));
298   NSData* data = [NSKeyedArchiver archivedDataWithRootObject:sessionEntry_];
299   EXPECT_TRUE(data != nil);
300   CRWSessionEntry* unarchivedSessionEntry =
301       [NSKeyedUnarchiver unarchiveObjectWithData:data];
302   ASSERT_TRUE(unarchivedSessionEntry != nil);
303   web::NavigationItem* unarchivedItem = [unarchivedSessionEntry navigationItem];
304   expectEqualSessionEntries(sessionEntry_, unarchivedSessionEntry,
305                             ui::PAGE_TRANSITION_RELOAD);
306   EXPECT_EQ(unarchivedItem->GetURL(), item->GetVirtualURL());
307   EXPECT_NE(unarchivedItem->GetURL(), item->GetURL());
310 TEST_F(CRWSessionEntryTest, CopyWithZone) {
311   CRWSessionEntry* sessionEntry2 = [sessionEntry_ copy];
312   EXPECT_NE(sessionEntry_, sessionEntry2);
313   expectEqualSessionEntries(
314       sessionEntry_, sessionEntry2,
315       [sessionEntry_ navigationItem]->GetTransitionType());
318 TEST_F(CRWSessionEntryTest, EmptyVirtualUrl) {
319   EXPECT_EQ(GURL("http://init.test/"),
320             [sessionEntry_ navigationItem]->GetURL());
323 TEST_F(CRWSessionEntryTest, NonEmptyVirtualUrl) {
324   web::NavigationItem* item = [sessionEntry_ navigationItem];
325   item->SetVirtualURL(GURL("http://user.friendly"));
326   EXPECT_EQ(GURL("http://user.friendly/"), item->GetVirtualURL());
327   EXPECT_EQ(GURL("http://init.test/"), item->GetURL());
330 TEST_F(CRWSessionEntryTest, EmptyDescription) {
331   EXPECT_GT([[sessionEntry_ description] length], 0U);