1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/pickle.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebHTTPBody.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/glue_serialize.h"
14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "webkit/glue/web_io_operators.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebData;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebHistoryItem;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebHTTPBody;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebPoint;
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebString;
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebUChar;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebVector;
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass GlueSerializeTest : public testing::Test {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Makes a FormData with some random data.
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebHTTPBody MakeFormData() {
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WebHTTPBody http_body;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    http_body.initialize();
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char d1[] = "first data block";
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    http_body.appendData(WebData(d1, sizeof(d1)-1));
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    http_body.appendFile(WebString::fromUTF8("file.txt"));
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const char d2[] = "data the second";
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    http_body.appendData(WebData(d2, sizeof(d2)-1));
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return http_body;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Constructs a HistoryItem with some random data and an optional child.
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebHistoryItem MakeHistoryItem(bool with_form_data, bool pregnant) {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WebHistoryItem item;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.initialize();
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setURLString(WebString::fromUTF8("urlString"));
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setOriginalURLString(WebString::fromUTF8("originalURLString"));
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setTarget(WebString::fromUTF8("target"));
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setParent(WebString::fromUTF8("parent"));
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setTitle(WebString::fromUTF8("title"));
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setAlternateTitle(WebString::fromUTF8("alternateTitle"));
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setLastVisitedTime(13.37);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setScrollOffset(WebPoint(42, -42));
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setIsTargetItem(true);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setVisitCount(42*42);
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WebVector<WebString> document_state(size_t(3));
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    document_state[0] = WebString::fromUTF8("state1");
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    document_state[1] = WebString::fromUTF8("state2");
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    document_state[2] = WebString::fromUTF8("state AWESOME");
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setDocumentState(document_state);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Form Data
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (with_form_data) {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      item.setHTTPBody(MakeFormData());
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      item.setHTTPContentType(WebString::fromUTF8("formContentType"));
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Setting the FormInfo causes the referrer to be set, so we set the
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // referrer after setting the form info.
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    item.setReferrer(WebString::fromUTF8("referrer"));
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Children
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pregnant)
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      item.appendToChildren(MakeHistoryItem(false, false));
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return item;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Checks that a == b.
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void HistoryItemExpectEqual(const WebHistoryItem& a,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              const WebHistoryItem& b) {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.urlString()), string16(b.urlString()));
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.originalURLString()), string16(b.originalURLString()));
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.target()), string16(b.target()));
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.parent()), string16(b.parent()));
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.title()), string16(b.title()));
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.alternateTitle()), string16(b.alternateTitle()));
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(a.lastVisitedTime(), b.lastVisitedTime());
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(a.scrollOffset(), b.scrollOffset());
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(a.isTargetItem(), b.isTargetItem());
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(a.visitCount(), b.visitCount());
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.referrer()), string16(b.referrer()));
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebVector<WebString>& a_docstate = a.documentState();
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebVector<WebString>& b_docstate = b.documentState();
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(a_docstate.size(), b_docstate.size());
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0, c = a_docstate.size(); i < c; ++i)
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(string16(a_docstate[i]), string16(b_docstate[i]));
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Form Data
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebHTTPBody& a_body = a.httpBody();
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebHTTPBody& b_body = b.httpBody();
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(!a_body.isNull(), !b_body.isNull());
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!a_body.isNull() && !b_body.isNull()) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(a_body.elementCount(), b_body.elementCount());
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      WebHTTPBody::Element a_elem, b_elem;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (size_t i = 0; a_body.elementAt(i, a_elem) &&
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         b_body.elementAt(i, b_elem); ++i) {
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        EXPECT_EQ(a_elem.type, b_elem.type);
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (a_elem.type == WebHTTPBody::Element::TypeData) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          EXPECT_EQ(std::string(a_elem.data.data(), a_elem.data.size()),
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    std::string(b_elem.data.data(), b_elem.data.size()));
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        } else {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          EXPECT_EQ(string16(a_elem.filePath), string16(b_elem.filePath));
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(string16(a.httpContentType()), string16(b.httpContentType()));
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Children
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebVector<WebHistoryItem>& a_children = a.children();
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebVector<WebHistoryItem>& b_children = b.children();
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(a_children.size(), b_children.size());
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0, c = a_children.size(); i < c; ++i)
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      HistoryItemExpectEqual(a_children[i], b_children[i]);
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test old versions of serialized data to ensure that newer versions of code
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// can still read history items written by previous versions.
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(GlueSerializeTest, BackwardsCompatibleTest) {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const WebHistoryItem& item = MakeHistoryItem(false, false);
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure version 3 (current version) can read versions 1 and 2.
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 1; i <= 2; i++) {
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string serialized_item;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    webkit_glue::HistoryItemToVersionedString(item, i, &serialized_item);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const WebHistoryItem& deserialized_item =
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        webkit_glue::HistoryItemFromString(serialized_item);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_FALSE(item.isNull());
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_FALSE(deserialized_item.isNull());
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HistoryItemExpectEqual(item, deserialized_item);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure that a HistoryItem remains intact after being serialized and
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// deserialized.
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(GlueSerializeTest, HistoryItemSerializeTest) {
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const WebHistoryItem& item = MakeHistoryItem(true, true);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string& serialized_item = webkit_glue::HistoryItemToString(item);
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const WebHistoryItem& deserialized_item =
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      webkit_glue::HistoryItemFromString(serialized_item);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(item.isNull());
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(deserialized_item.isNull());
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HistoryItemExpectEqual(item, deserialized_item);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Checks that broken messages don't take out our process.
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(GlueSerializeTest, BadMessagesTest) {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Pickle p;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Version 1
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(1);
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Empty strings.
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < 6; ++i)
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      p.WriteInt(-1);
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Bad real number.
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(-1);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string s(static_cast<const char*>(p.data()), p.size());
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    webkit_glue::HistoryItemFromString(s);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    double d = 0;
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Pickle p;
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Version 1
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(1);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Empty strings.
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < 6; ++i)
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      p.WriteInt(-1);
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // More misc fields.
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteData(reinterpret_cast<const char*>(&d), sizeof(d));
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(1);
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(1);
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(0);
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(0);
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(-1);
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(0);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // WebForm
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(1);
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    p.WriteInt(WebHTTPBody::Element::TypeData);
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string s(static_cast<const char*>(p.data()), p.size());
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    webkit_glue::HistoryItemFromString(s);
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
201