Buffet: Implement fake HTTP transport to help write unit tests

Created fake Transport and Connection classes to help test
HTTP communications in Buffet. Now, when a fake transport
class is created a number of HTTP request handlers can be
registered, which will be called when a request to a web
server is made. These handlers can reply to the caller on
server's behalf and can provide response based on the
request data and parameters.

Removed 'static' from http::Request::range_value_omitted due
to a build break in debug (-O0) build. Static members should
be generally initialized in a .cc file, not header.

Fixed a bug in chromeos::url::GetQueryStringParameters() when
called on an empty string.

Finally, added 'bind_lamda.h' header file that adds the
ability to use lambdas in base::Bind() calls.

BUG=chromium:367377
TEST=Unit tests pass.

Change-Id: Ib4c070f676069f208b9df4da069ff3a29f8f656f
Reviewed-on: https://chromium-review.googlesource.com/197157
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/http_utils_unittest.cc b/buffet/http_utils_unittest.cc
index ab137a7..c04f498 100644
--- a/buffet/http_utils_unittest.cc
+++ b/buffet/http_utils_unittest.cc
@@ -2,12 +2,56 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "buffet/http_utils.h"
-
 #include <gtest/gtest.h>
 
+#include "buffet/bind_lambda.h"
+#include "buffet/http_utils.h"
+#include "buffet/http_transport_fake.h"
+#include "buffet/mime_utils.h"
+#include "buffet/url_utils.h"
+
+using namespace chromeos;
 using namespace chromeos::http;
 
-TEST(HttpUtils, SendRequest) {
-  // TODO(avakulenko)
+static const char fake_url[] = "http://localhost";
+
+TEST(HttpUtils, PostText) {
+  std::string fake_data = "Some data";
+  auto PostHandler = [fake_data](const fake::ServerRequest& request,
+                                 fake::ServerResponse* response) {
+    EXPECT_EQ(request_type::kPost, request.GetMethod());
+    EXPECT_EQ(fake_data.size(),
+              atoi(request.GetHeader(request_header::kContentLength).c_str()));
+    EXPECT_EQ(mime::text::kPlain,
+              request.GetHeader(request_header::kContentType));
+    response->Reply(status_code::Ok, request.GetData(), mime::text::kPlain);
+  };
+
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(fake_url, request_type::kPost, base::Bind(PostHandler));
+
+  auto response = http::PostText(fake_url, fake_data.c_str(),
+                                 mime::text::kPlain, transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
+  EXPECT_EQ(fake_data, response->GetDataAsString());
+}
+
+TEST(HttpUtils, Get) {
+  auto GetHandler = [](const fake::ServerRequest& request,
+                       fake::ServerResponse* response) {
+    EXPECT_EQ(request_type::kGet, request.GetMethod());
+    EXPECT_EQ("0", request.GetHeader(request_header::kContentLength));
+    EXPECT_EQ("", request.GetHeader(request_header::kContentType));
+    response->ReplyText(status_code::Ok, request.GetFormField("test"),
+                       mime::text::kPlain);
+  };
+
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(fake_url, request_type::kGet, base::Bind(GetHandler));
+
+  for (std::string data : {"blah", "some data", ""}) {
+    std::string url = url::AppendQueryParam(fake_url, "test", data);
+    EXPECT_EQ(data, http::GetAsString(url, transport));
+  }
 }