1f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved. 2f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko// Use of this source code is governed by a BSD-style license that can be 3f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko// found in the LICENSE file. 4f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 59ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/http_request.h> 6f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 7f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko#include <string> 8f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 9f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko#include <base/callback.h> 109ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/bind_lambda.h> 119ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/mock_connection.h> 129ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/http/mock_transport.h> 139ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/mime_utils.h> 149ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/streams/mock_stream.h> 15f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko#include <gmock/gmock.h> 16f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko#include <gtest/gtest.h> 17f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 18f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkousing testing::DoAll; 19f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkousing testing::Invoke; 20f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkousing testing::Return; 21f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkousing testing::SetArgPointee; 22f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkousing testing::Unused; 23f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkousing testing::WithArg; 24f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkousing testing::_; 25f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 269ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 27f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkonamespace http { 28f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 29f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoMATCHER_P(ContainsStringData, str, "") { 3080663bf89f5ba2c0646f196371a1fa92123855c6Alex Vakulenko if (arg->GetSize() != str.size()) 31f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko return false; 32f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 33f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko std::string data; 34f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko char buf[100]; 35f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko size_t read = 0; 3680663bf89f5ba2c0646f196371a1fa92123855c6Alex Vakulenko while (arg->ReadBlocking(buf, sizeof(buf), &read, nullptr) && read > 0) { 37f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko data.append(buf, read); 38f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko } 39f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko return data == str; 40f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 41f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 42f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenkoclass HttpRequestTest : public testing::Test { 43f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko public: 44f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko void SetUp() override { 45f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko transport_ = std::make_shared<MockTransport>(); 46f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko connection_ = std::make_shared<MockConnection>(transport_); 47f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko } 48f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 49f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko void TearDown() override { 50f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko // Having shared pointers to mock objects (some of methods in these tests 51f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko // return shared pointers to connection and transport) could cause the 52f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko // test expectations to hold on to the mock object without releasing them 53f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko // at the end of a test, causing Mock's object leak detection to erroneously 54f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko // detect mock object "leaks". Verify and clear the expectations manually 55f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko // and explicitly to ensure the shared pointer refcounters are not 56f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko // preventing the mocks to be destroyed at the end of each test. 57f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko testing::Mock::VerifyAndClearExpectations(connection_.get()); 58f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko connection_.reset(); 59f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko testing::Mock::VerifyAndClearExpectations(transport_.get()); 60f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko transport_.reset(); 61f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko } 62f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 63f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko protected: 64f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko std::shared_ptr<MockTransport> transport_; 65f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko std::shared_ptr<MockConnection> connection_; 66f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko}; 67f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 68f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoTEST_F(HttpRequestTest, Defaults) { 69f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request{"http://www.foo.bar", request_type::kPost, transport_}; 70f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_TRUE(request.GetContentType().empty()); 71f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_TRUE(request.GetReferer().empty()); 72f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_TRUE(request.GetUserAgent().empty()); 73f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ("*/*", request.GetAccept()); 74f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ("http://www.foo.bar", request.GetRequestURL()); 75f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ(request_type::kPost, request.GetRequestMethod()); 76f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 77f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request2{"http://www.foo.bar/baz", request_type::kGet, transport_}; 78f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ("http://www.foo.bar/baz", request2.GetRequestURL()); 79f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ(request_type::kGet, request2.GetRequestMethod()); 80f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 81f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 82f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoTEST_F(HttpRequestTest, ContentType) { 83f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request{"http://www.foo.bar", request_type::kPost, transport_}; 84f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.SetContentType(mime::image::kJpeg); 85f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ(mime::image::kJpeg, request.GetContentType()); 86f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 87f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 88f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoTEST_F(HttpRequestTest, Referer) { 89f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request{"http://www.foo.bar", request_type::kPost, transport_}; 90f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.SetReferer("http://www.foo.bar/baz"); 91f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ("http://www.foo.bar/baz", request.GetReferer()); 92f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 93f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 94f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoTEST_F(HttpRequestTest, UserAgent) { 95f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request{"http://www.foo.bar", request_type::kPost, transport_}; 96f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.SetUserAgent("FooBar Browser"); 97f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ("FooBar Browser", request.GetUserAgent()); 98f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 99f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 100f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoTEST_F(HttpRequestTest, Accept) { 101f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request{"http://www.foo.bar", request_type::kPost, transport_}; 102f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.SetAccept("text/*, text/html, text/html;level=1, */*"); 103f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ("text/*, text/html, text/html;level=1, */*", request.GetAccept()); 104f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 105f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 106f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoTEST_F(HttpRequestTest, GetResponseAndBlock) { 107f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request{"http://www.foo.bar", request_type::kPost, transport_}; 108f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.SetUserAgent("FooBar Browser"); 109f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.SetReferer("http://www.foo.bar/baz"); 110f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.SetAccept("text/*, text/html, text/html;level=1, */*"); 111f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.AddHeader(request_header::kAcceptEncoding, "compress, gzip"); 112f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.AddHeaders({ 11305d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko {request_header::kAcceptLanguage, "da, en-gb;q=0.8, en;q=0.7"}, 11405d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko {request_header::kConnection, "close"}, 115f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko }); 116f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.AddRange(-10); 117f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.AddRange(100, 200); 118f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.AddRange(300); 119f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko std::string req_body{"Foo bar baz"}; 120f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request.AddHeader(request_header::kContentType, mime::text::kPlain); 121f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 122f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_CALL(*transport_, CreateConnection( 123f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko "http://www.foo.bar", 124f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko request_type::kPost, 125f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko HeaderList{ 126f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko {request_header::kAcceptEncoding, "compress, gzip"}, 127f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko {request_header::kAcceptLanguage, "da, en-gb;q=0.8, en;q=0.7"}, 128f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko {request_header::kConnection, "close"}, 129f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko {request_header::kContentType, mime::text::kPlain}, 130f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko {request_header::kRange, "bytes=-10,100-200,300-"}, 131f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko {request_header::kAccept, "text/*, text/html, text/html;level=1, */*"}, 132f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko }, 133f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko "FooBar Browser", 134f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko "http://www.foo.bar/baz", 135f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko nullptr)).WillOnce(Return(connection_)); 136f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 137f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_CALL(*connection_, MockSetRequestData(ContainsStringData(req_body), _)) 138f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko .WillOnce(Return(true)); 139f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 14005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko EXPECT_TRUE( 14105d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko request.AddRequestBody(req_body.data(), req_body.size(), nullptr)); 142f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 14305d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko EXPECT_CALL(*connection_, FinishRequest(_)).WillOnce(Return(true)); 144f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko auto resp = request.GetResponseAndBlock(nullptr); 145f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_NE(nullptr, resp.get()); 146f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 147f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 148f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex VakulenkoTEST_F(HttpRequestTest, GetResponse) { 149f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko Request request{"http://foo.bar", request_type::kGet, transport_}; 150f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 151f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko std::string resp_data{"FooBar response body"}; 152f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko auto read_data = 153f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko [&resp_data](void* buffer, Unused, size_t* read, Unused) -> bool { 154f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko memcpy(buffer, resp_data.data(), resp_data.size()); 155f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko *read = resp_data.size(); 156f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko return true; 157f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko }; 158f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 159ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko auto success_callback = 160fdf77f8331d2e4cbed4a7bec7fa42e605bdafba4Alex Vakulenko [this, &resp_data](RequestID request_id, std::unique_ptr<Response> resp) { 161ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko EXPECT_EQ(23, request_id); 162f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_CALL(*connection_, GetResponseStatusCode()) 163f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko .WillOnce(Return(status_code::Partial)); 164f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ(status_code::Partial, resp->GetStatusCode()); 165f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 166f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_CALL(*connection_, GetResponseStatusText()) 167f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko .WillOnce(Return("Partial completion")); 168f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ("Partial completion", resp->GetStatusText()); 169f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 170f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_CALL(*connection_, GetResponseHeader(response_header::kContentType)) 171f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko .WillOnce(Return(mime::text::kHtml)); 172f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_EQ(mime::text::kHtml, resp->GetContentType()); 173f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 17420d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko EXPECT_EQ(resp_data, resp->ExtractDataAsString()); 175f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko }; 176f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 177f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko auto finish_request_async = 178f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko [this, &read_data, &resp_data](const SuccessCallback& success_callback) { 17920d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko std::unique_ptr<MockStream> mock_stream{new MockStream}; 18020d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko EXPECT_CALL(*mock_stream, ReadBlocking(_, _, _, _)) 181f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko .WillOnce(Invoke(read_data)) 182f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko .WillOnce(DoAll(SetArgPointee<2>(0), Return(true))); 18320d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko 18420d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko EXPECT_CALL(*connection_, MockExtractDataStream(_)) 18520d497f58d7abdec1e011cb1efadb45e53e5af0bAlex Vakulenko .WillOnce(Return(mock_stream.release())); 186fdf77f8331d2e4cbed4a7bec7fa42e605bdafba4Alex Vakulenko std::unique_ptr<Response> resp{new Response{connection_}}; 187fdf77f8331d2e4cbed4a7bec7fa42e605bdafba4Alex Vakulenko success_callback.Run(23, std::move(resp)); 188f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko }; 189f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 19005d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko EXPECT_CALL( 19105d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko *transport_, 19205d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko CreateConnection("http://foo.bar", request_type::kGet, _, "", "", _)) 193f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko .WillOnce(Return(connection_)); 194f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 195f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko EXPECT_CALL(*connection_, FinishRequestAsync(_, _)) 196ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko .WillOnce(DoAll(WithArg<0>(Invoke(finish_request_async)), Return(23))); 197f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 198ac3059d5edad2af5a75184d1e31133e712c91f60Alex Vakulenko EXPECT_EQ(23, request.GetResponse(base::Bind(success_callback), {})); 199f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} 200f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko 201f5effe9e46e479e6fdc4f6928da545d48dcd3997Alex Vakulenko} // namespace http 2029ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 203