1// Copyright 2013 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.
4
5#include "net/base/url_util.h"
6
7#include "testing/gtest/include/gtest/gtest.h"
8#include "url/gurl.h"
9
10namespace net {
11namespace {
12
13TEST(UrlUtilTest, AppendQueryParameter) {
14  // Appending a name-value pair to a URL without a query component.
15  EXPECT_EQ("http://example.com/path?name=value",
16            AppendQueryParameter(GURL("http://example.com/path"),
17                                 "name", "value").spec());
18
19  // Appending a name-value pair to a URL with a query component.
20  // The original component should be preserved, and the new pair should be
21  // appended with '&'.
22  EXPECT_EQ("http://example.com/path?existing=one&name=value",
23            AppendQueryParameter(GURL("http://example.com/path?existing=one"),
24                                 "name", "value").spec());
25
26  // Appending a name-value pair with unsafe characters included. The
27  // unsafe characters should be escaped.
28  EXPECT_EQ("http://example.com/path?existing=one&na+me=v.alue%3D",
29            AppendQueryParameter(GURL("http://example.com/path?existing=one"),
30                                 "na me", "v.alue=").spec());
31
32}
33
34TEST(UrlUtilTest, AppendOrReplaceQueryParameter) {
35  // Appending a name-value pair to a URL without a query component.
36  EXPECT_EQ("http://example.com/path?name=value",
37            AppendOrReplaceQueryParameter(GURL("http://example.com/path"),
38                                 "name", "value").spec());
39
40  // Appending a name-value pair to a URL with a query component.
41  // The original component should be preserved, and the new pair should be
42  // appended with '&'.
43  EXPECT_EQ("http://example.com/path?existing=one&name=value",
44      AppendOrReplaceQueryParameter(
45          GURL("http://example.com/path?existing=one"),
46          "name", "value").spec());
47
48  // Appending a name-value pair with unsafe characters included. The
49  // unsafe characters should be escaped.
50  EXPECT_EQ("http://example.com/path?existing=one&na+me=v.alue%3D",
51      AppendOrReplaceQueryParameter(
52          GURL("http://example.com/path?existing=one"),
53          "na me", "v.alue=").spec());
54
55  // Replace value of an existing paramater.
56  EXPECT_EQ("http://example.com/path?existing=one&name=new",
57      AppendOrReplaceQueryParameter(
58          GURL("http://example.com/path?existing=one&name=old"),
59          "name", "new").spec());
60
61  // Replace a name-value pair with unsafe characters included. The
62  // unsafe characters should be escaped.
63  EXPECT_EQ("http://example.com/path?na+me=n.ew%3D&existing=one",
64      AppendOrReplaceQueryParameter(
65          GURL("http://example.com/path?na+me=old&existing=one"),
66          "na me", "n.ew=").spec());
67
68  // Replace the value of first parameter with this name only.
69  EXPECT_EQ("http://example.com/path?name=new&existing=one&name=old",
70      AppendOrReplaceQueryParameter(
71          GURL("http://example.com/path?name=old&existing=one&name=old"),
72          "name", "new").spec());
73
74  // Preserve the content of the original params regarless of our failure to
75  // interpret them correctly.
76  EXPECT_EQ("http://example.com/path?bar&name=new&left=&"
77            "=right&=&&name=again",
78      AppendOrReplaceQueryParameter(
79          GURL("http://example.com/path?bar&name=old&left=&"
80                "=right&=&&name=again"),
81          "name", "new").spec());
82}
83
84TEST(UrlUtilTest, GetValueForKeyInQuery) {
85  GURL url("http://example.com/path?name=value&boolParam&"
86           "url=http://test.com/q?n1%3Dv1%26n2");
87  std::string value;
88
89  // False when getting a non-existent query param.
90  EXPECT_FALSE(GetValueForKeyInQuery(url, "non-exist", &value));
91
92  // True when query param exist.
93  EXPECT_TRUE(GetValueForKeyInQuery(url, "name", &value));
94  EXPECT_EQ("value", value);
95
96  EXPECT_TRUE(GetValueForKeyInQuery(url, "boolParam", &value));
97  EXPECT_EQ("", value);
98
99  EXPECT_TRUE(GetValueForKeyInQuery(url, "url", &value));
100  EXPECT_EQ("http://test.com/q?n1=v1&n2", value);
101}
102
103TEST(UrlUtilTest, GetValueForKeyInQueryInvalidURL) {
104  GURL url("http://%01/?test");
105  std::string value;
106
107  // Always false when parsing an invalid URL.
108  EXPECT_FALSE(GetValueForKeyInQuery(url, "test", &value));
109}
110
111TEST(UrlUtilTest, ParseQuery) {
112  const GURL url("http://example.com/path?name=value&boolParam&"
113                 "url=http://test.com/q?n1%3Dv1%26n2&"
114                 "multikey=value1&multikey=value2&multikey");
115  QueryIterator it(url);
116
117  ASSERT_FALSE(it.IsAtEnd());
118  EXPECT_EQ("name", it.GetKey());
119  EXPECT_EQ("value", it.GetValue());
120  EXPECT_EQ("value", it.GetUnescapedValue());
121  it.Advance();
122
123  ASSERT_FALSE(it.IsAtEnd());
124  EXPECT_EQ("boolParam", it.GetKey());
125  EXPECT_EQ("", it.GetValue());
126  EXPECT_EQ("", it.GetUnescapedValue());
127  it.Advance();
128
129  ASSERT_FALSE(it.IsAtEnd());
130  EXPECT_EQ("url", it.GetKey());
131  EXPECT_EQ("http://test.com/q?n1%3Dv1%26n2", it.GetValue());
132  EXPECT_EQ("http://test.com/q?n1=v1&n2", it.GetUnescapedValue());
133  it.Advance();
134
135  ASSERT_FALSE(it.IsAtEnd());
136  EXPECT_EQ("multikey", it.GetKey());
137  EXPECT_EQ("value1", it.GetValue());
138  EXPECT_EQ("value1", it.GetUnescapedValue());
139  it.Advance();
140
141  ASSERT_FALSE(it.IsAtEnd());
142  EXPECT_EQ("multikey", it.GetKey());
143  EXPECT_EQ("value2", it.GetValue());
144  EXPECT_EQ("value2", it.GetUnescapedValue());
145  it.Advance();
146
147  ASSERT_FALSE(it.IsAtEnd());
148  EXPECT_EQ("multikey", it.GetKey());
149  EXPECT_EQ("", it.GetValue());
150  EXPECT_EQ("", it.GetUnescapedValue());
151  it.Advance();
152
153  EXPECT_TRUE(it.IsAtEnd());
154}
155
156TEST(UrlUtilTest, ParseQueryInvalidURL) {
157  const GURL url("http://%01/?test");
158  QueryIterator it(url);
159  EXPECT_TRUE(it.IsAtEnd());
160}
161
162}  // namespace
163}  // namespace net
164