summaryrefslogtreecommitdiffstats
path: root/webkit/glue/glue_serialize_unittest.cc
blob: eebd9bfd700b2710c3f2501afae84bad0ba3034f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// 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