| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <string> |
| |
| #include "base/pickle.h" |
| #include "base/string_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebHTTPBody.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebPoint.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h" |
| #include "webkit/glue/glue_serialize.h" |
| #include "webkit/glue/web_io_operators.h" |
| |
| using WebKit::WebData; |
| using WebKit::WebHistoryItem; |
| using WebKit::WebHTTPBody; |
| using WebKit::WebPoint; |
| using WebKit::WebString; |
| using WebKit::WebUChar; |
| using WebKit::WebVector; |
| |
| namespace { |
| class GlueSerializeTest : public testing::Test { |
| public: |
| // Makes a FormData with some random data. |
| WebHTTPBody MakeFormData() { |
| WebHTTPBody http_body; |
| http_body.initialize(); |
| |
| const char d1[] = "first data block"; |
| http_body.appendData(WebData(d1, sizeof(d1)-1)); |
| |
| http_body.appendFile(WebString::fromUTF8("file.txt")); |
| |
| const char d2[] = "data the second"; |
| http_body.appendData(WebData(d2, sizeof(d2)-1)); |
| |
| return http_body; |
| } |
| |
| // Constructs a HistoryItem with some random data and an optional child. |
| WebHistoryItem MakeHistoryItem(bool with_form_data, bool pregnant) { |
| WebHistoryItem item; |
| item.initialize(); |
| |
| item.setURLString(WebString::fromUTF8("urlString")); |
| item.setOriginalURLString(WebString::fromUTF8("originalURLString")); |
| item.setTarget(WebString::fromUTF8("target")); |
| item.setParent(WebString::fromUTF8("parent")); |
| item.setTitle(WebString::fromUTF8("title")); |
| item.setAlternateTitle(WebString::fromUTF8("alternateTitle")); |
| item.setLastVisitedTime(13.37); |
| item.setScrollOffset(WebPoint(42, -42)); |
| item.setIsTargetItem(true); |
| item.setVisitCount(42*42); |
| |
| WebVector<WebString> document_state(size_t(3)); |
| document_state[0] = WebString::fromUTF8("state1"); |
| document_state[1] = WebString::fromUTF8("state2"); |
| document_state[2] = WebString::fromUTF8("state AWESOME"); |
| item.setDocumentState(document_state); |
| |
| // Form Data |
| if (with_form_data) { |
| item.setHTTPBody(MakeFormData()); |
| item.setHTTPContentType(WebString::fromUTF8("formContentType")); |
| } |
| |
| // Setting the FormInfo causes the referrer to be set, so we set the |
| // referrer after setting the form info. |
| item.setReferrer(WebString::fromUTF8("referrer")); |
| |
| // Children |
| if (pregnant) |
| item.appendToChildren(MakeHistoryItem(false, false)); |
| |
| return item; |
| } |
| |
| // Checks that a == b. |
| void HistoryItemExpectEqual(const WebHistoryItem& a, |
| const WebHistoryItem& b) { |
| EXPECT_EQ(string16(a.urlString()), string16(b.urlString())); |
| EXPECT_EQ(string16(a.originalURLString()), string16(b.originalURLString())); |
| EXPECT_EQ(string16(a.target()), string16(b.target())); |
| EXPECT_EQ(string16(a.parent()), string16(b.parent())); |
| EXPECT_EQ(string16(a.title()), string16(b.title())); |
| EXPECT_EQ(string16(a.alternateTitle()), string16(b.alternateTitle())); |
| EXPECT_EQ(a.lastVisitedTime(), b.lastVisitedTime()); |
| EXPECT_EQ(a.scrollOffset(), b.scrollOffset()); |
| EXPECT_EQ(a.isTargetItem(), b.isTargetItem()); |
| EXPECT_EQ(a.visitCount(), b.visitCount()); |
| EXPECT_EQ(string16(a.referrer()), string16(b.referrer())); |
| |
| const WebVector<WebString>& a_docstate = a.documentState(); |
| const WebVector<WebString>& b_docstate = b.documentState(); |
| EXPECT_EQ(a_docstate.size(), b_docstate.size()); |
| for (size_t i = 0, c = a_docstate.size(); i < c; ++i) |
| EXPECT_EQ(string16(a_docstate[i]), string16(b_docstate[i])); |
| |
| // Form Data |
| const WebHTTPBody& a_body = a.httpBody(); |
| const WebHTTPBody& b_body = b.httpBody(); |
| EXPECT_EQ(!a_body.isNull(), !b_body.isNull()); |
| if (!a_body.isNull() && !b_body.isNull()) { |
| EXPECT_EQ(a_body.elementCount(), b_body.elementCount()); |
| WebHTTPBody::Element a_elem, b_elem; |
| for (size_t i = 0; a_body.elementAt(i, a_elem) && |
| b_body.elementAt(i, b_elem); ++i) { |
| EXPECT_EQ(a_elem.type, b_elem.type); |
| if (a_elem.type == WebHTTPBody::Element::TypeData) { |
| EXPECT_EQ(std::string(a_elem.data.data(), a_elem.data.size()), |
| std::string(b_elem.data.data(), b_elem.data.size())); |
| } else { |
| EXPECT_EQ(string16(a_elem.filePath), string16(b_elem.filePath)); |
| } |
| } |
| } |
| EXPECT_EQ(string16(a.httpContentType()), string16(b.httpContentType())); |
| |
| // Children |
| const WebVector<WebHistoryItem>& a_children = a.children(); |
| const WebVector<WebHistoryItem>& b_children = b.children(); |
| EXPECT_EQ(a_children.size(), b_children.size()); |
| for (size_t i = 0, c = a_children.size(); i < c; ++i) |
| HistoryItemExpectEqual(a_children[i], b_children[i]); |
| } |
| }; |
| |
| // Test old versions of serialized data to ensure that newer versions of code |
| // can still read history items written by previous versions. |
| TEST_F(GlueSerializeTest, BackwardsCompatibleTest) { |
| const WebHistoryItem& item = MakeHistoryItem(false, false); |
| |
| // Make sure version 3 (current version) can read versions 1 and 2. |
| for (int i = 1; i <= 2; i++) { |
| std::string serialized_item; |
| webkit_glue::HistoryItemToVersionedString(item, i, &serialized_item); |
| const WebHistoryItem& deserialized_item = |
| webkit_glue::HistoryItemFromString(serialized_item); |
| ASSERT_FALSE(item.isNull()); |
| ASSERT_FALSE(deserialized_item.isNull()); |
| HistoryItemExpectEqual(item, deserialized_item); |
| } |
| } |
| |
| // Makes sure that a HistoryItem remains intact after being serialized and |
| // deserialized. |
| TEST_F(GlueSerializeTest, HistoryItemSerializeTest) { |
| const WebHistoryItem& item = MakeHistoryItem(true, true); |
| const std::string& serialized_item = webkit_glue::HistoryItemToString(item); |
| const WebHistoryItem& deserialized_item = |
| webkit_glue::HistoryItemFromString(serialized_item); |
| |
| ASSERT_FALSE(item.isNull()); |
| ASSERT_FALSE(deserialized_item.isNull()); |
| HistoryItemExpectEqual(item, deserialized_item); |
| } |
| |
| // Checks that broken messages don't take out our process. |
| TEST_F(GlueSerializeTest, BadMessagesTest) { |
| { |
| Pickle p; |
| // Version 1 |
| p.WriteInt(1); |
| // Empty strings. |
| for (int i = 0; i < 6; ++i) |
| p.WriteInt(-1); |
| // Bad real number. |
| p.WriteInt(-1); |
| std::string s(static_cast<const char*>(p.data()), p.size()); |
| webkit_glue::HistoryItemFromString(s); |
| } |
| { |
| double d = 0; |
| Pickle p; |
| // Version 1 |
| p.WriteInt(1); |
| // Empty strings. |
| for (int i = 0; i < 6; ++i) |
| p.WriteInt(-1); |
| // More misc fields. |
| p.WriteData(reinterpret_cast<const char*>(&d), sizeof(d)); |
| p.WriteInt(1); |
| p.WriteInt(1); |
| p.WriteInt(0); |
| p.WriteInt(0); |
| p.WriteInt(-1); |
| p.WriteInt(0); |
| // WebForm |
| p.WriteInt(1); |
| p.WriteInt(WebHTTPBody::Element::TypeData); |
| std::string s(static_cast<const char*>(p.data()), p.size()); |
| webkit_glue::HistoryItemFromString(s); |
| } |
| } |
| |
| } // namespace |