Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 1 | // Copyright 2014 The Chromium OS 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 | |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 5 | #include <string> |
| 6 | #include <vector> |
| 7 | |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 8 | #include <base/values.h> |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 9 | #include <gtest/gtest.h> |
| 10 | |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 11 | #include "buffet/bind_lambda.h" |
| 12 | #include "buffet/http_utils.h" |
| 13 | #include "buffet/http_transport_fake.h" |
| 14 | #include "buffet/mime_utils.h" |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 15 | #include "buffet/string_utils.h" |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 16 | #include "buffet/url_utils.h" |
| 17 | |
Alex Vakulenko | af23b32 | 2014-05-08 16:25:45 -0700 | [diff] [blame] | 18 | using namespace buffet; // NOLINT(build/namespaces) |
| 19 | using namespace buffet::http; // NOLINT(build/namespaces) |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 20 | |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 21 | static const char kFakeUrl[] = "http://localhost"; |
| 22 | static const char kEchoUrl[] = "http://localhost/echo"; |
| 23 | static const char kMethodEchoUrl[] = "http://localhost/echo/method"; |
| 24 | |
| 25 | ///////////////////// Generic helper request handlers ///////////////////////// |
| 26 | // Returns the request data back with the same content type. |
| 27 | static void EchoDataHandler(const fake::ServerRequest& request, |
| 28 | fake::ServerResponse* response) { |
| 29 | response->Reply(status_code::Ok, request.GetData(), |
| 30 | request.GetHeader(request_header::kContentType).c_str()); |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 31 | } |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 32 | |
| 33 | // Returns the request method as a plain text response. |
| 34 | static void EchoMethodHandler(const fake::ServerRequest& request, |
| 35 | fake::ServerResponse* response) { |
| 36 | response->ReplyText(status_code::Ok, request.GetMethod(), mime::text::kPlain); |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 37 | } |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 38 | |
| 39 | /////////////////////////////////////////////////////////////////////////////// |
| 40 | TEST(HttpUtils, SendRequest_BinaryData) { |
| 41 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 42 | transport->AddHandler(kEchoUrl, request_type::kPost, |
| 43 | base::Bind(EchoDataHandler)); |
| 44 | |
| 45 | // Test binary data round-tripping. |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 46 | std::vector<unsigned char> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F}; |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 47 | auto response = http::SendRequest(request_type::kPost, kEchoUrl, |
| 48 | custom_data.data(), custom_data.size(), |
| 49 | mime::application::kOctet_stream, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 50 | HeaderList(), transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 51 | EXPECT_TRUE(response->IsSuccessful()); |
| 52 | EXPECT_EQ(mime::application::kOctet_stream, response->GetContentType()); |
| 53 | EXPECT_EQ(custom_data.size(), response->GetData().size()); |
| 54 | EXPECT_EQ(custom_data, response->GetData()); |
| 55 | } |
| 56 | |
| 57 | TEST(HttpUtils, SendRequest_Post) { |
| 58 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 59 | transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler)); |
| 60 | |
| 61 | // Test binary data round-tripping. |
Alex Vakulenko | a0424dd | 2014-06-13 16:10:17 -0700 | [diff] [blame] | 62 | std::vector<unsigned char> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F}; |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 63 | |
| 64 | // Check the correct HTTP method used. |
| 65 | auto response = http::SendRequest(request_type::kPost, kMethodEchoUrl, |
| 66 | custom_data.data(), custom_data.size(), |
| 67 | mime::application::kOctet_stream, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 68 | HeaderList(), transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 69 | EXPECT_TRUE(response->IsSuccessful()); |
| 70 | EXPECT_EQ(mime::text::kPlain, response->GetContentType()); |
| 71 | EXPECT_EQ(request_type::kPost, response->GetDataAsString()); |
| 72 | } |
| 73 | |
| 74 | TEST(HttpUtils, SendRequest_Get) { |
| 75 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 76 | transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler)); |
| 77 | |
| 78 | auto response = http::SendRequest(request_type::kGet, kMethodEchoUrl, |
| 79 | nullptr, 0, nullptr, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 80 | HeaderList(), transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 81 | EXPECT_TRUE(response->IsSuccessful()); |
| 82 | EXPECT_EQ(mime::text::kPlain, response->GetContentType()); |
| 83 | EXPECT_EQ(request_type::kGet, response->GetDataAsString()); |
| 84 | } |
| 85 | |
| 86 | TEST(HttpUtils, SendRequest_Put) { |
| 87 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 88 | transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler)); |
| 89 | |
| 90 | auto response = http::SendRequest(request_type::kPut, kMethodEchoUrl, |
| 91 | nullptr, 0, nullptr, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 92 | HeaderList(), transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 93 | EXPECT_TRUE(response->IsSuccessful()); |
| 94 | EXPECT_EQ(mime::text::kPlain, response->GetContentType()); |
| 95 | EXPECT_EQ(request_type::kPut, response->GetDataAsString()); |
| 96 | } |
| 97 | |
| 98 | TEST(HttpUtils, SendRequest_NotFound) { |
| 99 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 100 | // Test failed response (URL not found). |
| 101 | auto response = http::SendRequest(request_type::kGet, "http://blah.com", |
| 102 | nullptr, 0, nullptr, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 103 | HeaderList(), transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 104 | EXPECT_FALSE(response->IsSuccessful()); |
| 105 | EXPECT_EQ(status_code::NotFound, response->GetStatusCode()); |
| 106 | } |
| 107 | |
| 108 | TEST(HttpUtils, SendRequest_Headers) { |
| 109 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 110 | |
| 111 | static const char json_echo_url[] = "http://localhost/echo/json"; |
| 112 | auto JsonEchoHandler = [](const fake::ServerRequest& request, |
| 113 | fake::ServerResponse* response) { |
| 114 | base::DictionaryValue json; |
| 115 | json.SetString("method", request.GetMethod()); |
| 116 | json.SetString("data", request.GetDataAsString()); |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 117 | for (const auto& pair : request.GetHeaders()) { |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 118 | json.SetString("header." + pair.first, pair.second); |
| 119 | } |
| 120 | response->ReplyJson(status_code::Ok, &json); |
| 121 | }; |
| 122 | transport->AddHandler(json_echo_url, "*", |
| 123 | base::Bind(JsonEchoHandler)); |
| 124 | auto response = http::SendRequest( |
| 125 | request_type::kPost, json_echo_url, "abcd", 4, |
| 126 | mime::application::kOctet_stream, { |
| 127 | {request_header::kCookie, "flavor=vanilla"}, |
| 128 | {request_header::kIfMatch, "*"}, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 129 | }, transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 130 | EXPECT_TRUE(response->IsSuccessful()); |
Alex Vakulenko | 8e34d39 | 2014-04-29 11:02:56 -0700 | [diff] [blame] | 131 | EXPECT_EQ(mime::application::kJson, |
| 132 | mime::RemoveParameters(response->GetContentType())); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 133 | auto json = ParseJsonResponse(response.get(), nullptr, nullptr); |
| 134 | std::string value; |
| 135 | EXPECT_TRUE(json->GetString("method", &value)); |
| 136 | EXPECT_EQ(request_type::kPost, value); |
| 137 | EXPECT_TRUE(json->GetString("data", &value)); |
| 138 | EXPECT_EQ("abcd", value); |
| 139 | EXPECT_TRUE(json->GetString("header.Cookie", &value)); |
| 140 | EXPECT_EQ("flavor=vanilla", value); |
| 141 | EXPECT_TRUE(json->GetString("header.Content-Type", &value)); |
| 142 | EXPECT_EQ(mime::application::kOctet_stream, value); |
| 143 | EXPECT_TRUE(json->GetString("header.Content-Length", &value)); |
| 144 | EXPECT_EQ("4", value); |
| 145 | EXPECT_TRUE(json->GetString("header.If-Match", &value)); |
| 146 | EXPECT_EQ("*", value); |
| 147 | } |
| 148 | |
| 149 | TEST(HttpUtils, Get) { |
| 150 | // Sends back the "?test=..." portion of URL. |
| 151 | // So if we do GET "http://localhost?test=blah", this handler responds |
| 152 | // with "blah" as text/plain. |
| 153 | auto GetHandler = [](const fake::ServerRequest& request, |
| 154 | fake::ServerResponse* response) { |
| 155 | EXPECT_EQ(request_type::kGet, request.GetMethod()); |
| 156 | EXPECT_EQ("0", request.GetHeader(request_header::kContentLength)); |
| 157 | EXPECT_EQ("", request.GetHeader(request_header::kContentType)); |
| 158 | response->ReplyText(status_code::Ok, request.GetFormField("test"), |
| 159 | mime::text::kPlain); |
| 160 | }; |
| 161 | |
| 162 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 163 | transport->AddHandler(kFakeUrl, request_type::kGet, base::Bind(GetHandler)); |
| 164 | transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler)); |
| 165 | |
| 166 | // Make sure Get/GetAsString actually do the GET request |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 167 | auto response = http::Get(kMethodEchoUrl, transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 168 | EXPECT_TRUE(response->IsSuccessful()); |
| 169 | EXPECT_EQ(mime::text::kPlain, response->GetContentType()); |
| 170 | EXPECT_EQ(request_type::kGet, response->GetDataAsString()); |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 171 | EXPECT_EQ(request_type::kGet, |
| 172 | http::GetAsString(kMethodEchoUrl, transport, nullptr)); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 173 | |
| 174 | for (std::string data : {"blah", "some data", ""}) { |
| 175 | std::string url = url::AppendQueryParam(kFakeUrl, "test", data); |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 176 | EXPECT_EQ(data, http::GetAsString(url, transport, nullptr)); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 177 | } |
| 178 | } |
| 179 | |
| 180 | TEST(HttpUtils, Head) { |
| 181 | auto HeadHandler = [](const fake::ServerRequest& request, |
| 182 | fake::ServerResponse* response) { |
| 183 | EXPECT_EQ(request_type::kHead, request.GetMethod()); |
| 184 | EXPECT_EQ("0", request.GetHeader(request_header::kContentLength)); |
| 185 | EXPECT_EQ("", request.GetHeader(request_header::kContentType)); |
| 186 | response->ReplyText(status_code::Ok, "blah", |
| 187 | mime::text::kPlain); |
| 188 | }; |
| 189 | |
| 190 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 191 | transport->AddHandler(kFakeUrl, request_type::kHead, base::Bind(HeadHandler)); |
| 192 | |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 193 | auto response = http::Head(kFakeUrl, transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 194 | EXPECT_TRUE(response->IsSuccessful()); |
| 195 | EXPECT_EQ(mime::text::kPlain, response->GetContentType()); |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 196 | EXPECT_EQ("", response->GetDataAsString()); // Must not have actual body. |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 197 | EXPECT_EQ("4", response->GetHeader(request_header::kContentLength)); |
| 198 | } |
| 199 | |
| 200 | TEST(HttpUtils, PostBinary) { |
| 201 | auto Handler = [](const fake::ServerRequest& request, |
| 202 | fake::ServerResponse* response) { |
| 203 | EXPECT_EQ(request_type::kPost, request.GetMethod()); |
| 204 | EXPECT_EQ("256", request.GetHeader(request_header::kContentLength)); |
| 205 | EXPECT_EQ(mime::application::kOctet_stream, |
| 206 | request.GetHeader(request_header::kContentType)); |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 207 | const auto& data = request.GetData(); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 208 | EXPECT_EQ(256, data.size()); |
| 209 | |
| 210 | // Sum up all the bytes. |
| 211 | int sum = std::accumulate(data.begin(), data.end(), 0); |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 212 | EXPECT_EQ(32640, sum); // sum(i, i => [0, 255]) = 32640. |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 213 | response->ReplyText(status_code::Ok, "", mime::text::kPlain); |
| 214 | }; |
| 215 | |
| 216 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 217 | transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(Handler)); |
| 218 | |
| 219 | /// Fill the data buffer with bytes from 0x00 to 0xFF. |
| 220 | std::vector<unsigned char> data(256); |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 221 | std::iota(data.begin(), data.end(), 0); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 222 | |
| 223 | auto response = http::PostBinary(kFakeUrl, data.data(), data.size(), |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 224 | transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 225 | EXPECT_TRUE(response->IsSuccessful()); |
| 226 | } |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 227 | |
| 228 | TEST(HttpUtils, PostText) { |
| 229 | std::string fake_data = "Some data"; |
| 230 | auto PostHandler = [fake_data](const fake::ServerRequest& request, |
| 231 | fake::ServerResponse* response) { |
| 232 | EXPECT_EQ(request_type::kPost, request.GetMethod()); |
| 233 | EXPECT_EQ(fake_data.size(), |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 234 | std::stoul(request.GetHeader(request_header::kContentLength))); |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 235 | EXPECT_EQ(mime::text::kPlain, |
| 236 | request.GetHeader(request_header::kContentType)); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 237 | response->ReplyText(status_code::Ok, request.GetDataAsString(), |
| 238 | mime::text::kPlain); |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 239 | }; |
| 240 | |
| 241 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 242 | transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(PostHandler)); |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 243 | |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 244 | auto response = http::PostText(kFakeUrl, fake_data.c_str(), |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 245 | mime::text::kPlain, transport, nullptr); |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 246 | EXPECT_TRUE(response->IsSuccessful()); |
| 247 | EXPECT_EQ(mime::text::kPlain, response->GetContentType()); |
| 248 | EXPECT_EQ(fake_data, response->GetDataAsString()); |
| 249 | } |
| 250 | |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 251 | TEST(HttpUtils, PostFormData) { |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 252 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 253 | transport->AddHandler(kFakeUrl, request_type::kPost, |
| 254 | base::Bind(EchoDataHandler)); |
Alex Vakulenko | 9cd5e27 | 2014-04-25 17:26:11 -0700 | [diff] [blame] | 255 | |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 256 | auto response = http::PostFormData(kFakeUrl, { |
| 257 | {"key", "value"}, |
| 258 | {"field", "field value"}, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 259 | }, transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 260 | EXPECT_TRUE(response->IsSuccessful()); |
| 261 | EXPECT_EQ(mime::application::kWwwFormUrlEncoded, response->GetContentType()); |
| 262 | EXPECT_EQ("key=value&field=field+value", response->GetDataAsString()); |
Alex Vakulenko | a3062c5 | 2014-04-21 17:05:51 -0700 | [diff] [blame] | 263 | } |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 264 | |
| 265 | TEST(HttpUtils, PostPatchJson) { |
| 266 | auto JsonHandler = [](const fake::ServerRequest& request, |
| 267 | fake::ServerResponse* response) { |
Alex Vakulenko | 8e34d39 | 2014-04-29 11:02:56 -0700 | [diff] [blame] | 268 | auto mime_type = mime::RemoveParameters( |
| 269 | request.GetHeader(request_header::kContentType)); |
| 270 | EXPECT_EQ(mime::application::kJson, mime_type); |
| 271 | response->ReplyJson(status_code::Ok, { |
| 272 | {"method", request.GetMethod()}, |
| 273 | {"data", request.GetDataAsString()}, |
| 274 | }); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 275 | }; |
| 276 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 277 | transport->AddHandler(kFakeUrl, "*", base::Bind(JsonHandler)); |
| 278 | |
| 279 | base::DictionaryValue json; |
| 280 | json.SetString("key1", "val1"); |
| 281 | json.SetString("key2", "val2"); |
| 282 | std::string value; |
| 283 | |
| 284 | // Test POST |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 285 | auto response = http::PostJson(kFakeUrl, &json, transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 286 | auto resp_json = http::ParseJsonResponse(response.get(), nullptr, nullptr); |
| 287 | EXPECT_NE(nullptr, resp_json.get()); |
| 288 | EXPECT_TRUE(resp_json->GetString("method", &value)); |
| 289 | EXPECT_EQ(request_type::kPost, value); |
| 290 | EXPECT_TRUE(resp_json->GetString("data", &value)); |
| 291 | EXPECT_EQ("{\"key1\":\"val1\",\"key2\":\"val2\"}", value); |
| 292 | |
| 293 | // Test PATCH |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 294 | response = http::PatchJson(kFakeUrl, &json, transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 295 | resp_json = http::ParseJsonResponse(response.get(), nullptr, nullptr); |
| 296 | EXPECT_NE(nullptr, resp_json.get()); |
| 297 | EXPECT_TRUE(resp_json->GetString("method", &value)); |
| 298 | EXPECT_EQ(request_type::kPatch, value); |
| 299 | EXPECT_TRUE(resp_json->GetString("data", &value)); |
| 300 | EXPECT_EQ("{\"key1\":\"val1\",\"key2\":\"val2\"}", value); |
| 301 | } |
| 302 | |
| 303 | TEST(HttpUtils, ParseJsonResponse) { |
| 304 | auto JsonHandler = [](const fake::ServerRequest& request, |
| 305 | fake::ServerResponse* response) { |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 306 | int status_code = std::stoi(request.GetFormField("code")); |
Alex Vakulenko | 8e34d39 | 2014-04-29 11:02:56 -0700 | [diff] [blame] | 307 | response->ReplyJson(status_code, {{"data", request.GetFormField("value")}}); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 308 | }; |
| 309 | std::shared_ptr<fake::Transport> transport(new fake::Transport); |
| 310 | transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(JsonHandler)); |
| 311 | |
| 312 | // Test valid JSON responses (with success or error codes). |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 313 | for (auto item : {"200;data", "400;wrong", "500;Internal Server error"}) { |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 314 | auto pair = string_utils::SplitAtFirst(item, ';'); |
| 315 | auto response = http::PostFormData(kFakeUrl, { |
| 316 | {"code", pair.first}, |
| 317 | {"value", pair.second}, |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 318 | }, transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 319 | int code = 0; |
| 320 | auto json = http::ParseJsonResponse(response.get(), &code, nullptr); |
| 321 | EXPECT_NE(nullptr, json.get()); |
| 322 | std::string value; |
| 323 | EXPECT_TRUE(json->GetString("data", &value)); |
Alex Vakulenko | 96c84d3 | 2014-06-06 11:07:32 -0700 | [diff] [blame] | 324 | EXPECT_EQ(pair.first, string_utils::ToString(code)); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 325 | EXPECT_EQ(pair.second, value); |
| 326 | } |
| 327 | |
Alex Vakulenko | b3aac25 | 2014-05-07 17:35:24 -0700 | [diff] [blame] | 328 | // Test invalid (non-JSON) response. |
| 329 | auto response = http::Get("http://bad.url", transport, nullptr); |
Alex Vakulenko | 28b31f5 | 2014-04-28 12:40:05 -0700 | [diff] [blame] | 330 | EXPECT_EQ(status_code::NotFound, response->GetStatusCode()); |
| 331 | EXPECT_EQ(mime::text::kHtml, response->GetContentType()); |
| 332 | int code = 0; |
| 333 | auto json = http::ParseJsonResponse(response.get(), &code, nullptr); |
| 334 | EXPECT_EQ(nullptr, json.get()); |
| 335 | EXPECT_EQ(status_code::NotFound, code); |
| 336 | } |
| 337 | |