1 // Copyright (c) 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 <string> 6 7 #include "base/bind.h" 8 #include "base/json/json_writer.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/values.h" 11 #include "chrome/test/chromedriver/chrome/log.h" 12 #include "chrome/test/chromedriver/chrome/status.h" 13 #include "chrome/test/chromedriver/command.h" 14 #include "chrome/test/chromedriver/server/http_handler.h" 15 #include "net/http/http_status_code.h" 16 #include "net/server/http_server_request_info.h" 17 #include "net/server/http_server_response_info.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace { 21 22 void DummyCommand( 23 const Status& status, 24 const base::DictionaryValue& params, 25 const std::string& session_id, 26 const CommandCallback& callback) { 27 callback.Run(status, 28 scoped_ptr<base::Value>(new base::FundamentalValue(1)), 29 "session_id"); 30 } 31 32 void OnResponse(net::HttpServerResponseInfo* response_to_set, 33 scoped_ptr<net::HttpServerResponseInfo> response) { 34 *response_to_set = *response; 35 } 36 37 } // namespace 38 39 TEST(HttpHandlerTest, HandleOutsideOfBaseUrl) { 40 Logger log; 41 HttpHandler handler(&log, "base/url/"); 42 net::HttpServerRequestInfo request; 43 request.method = "get"; 44 request.path = "base/path"; 45 request.data = "body"; 46 net::HttpServerResponseInfo response; 47 handler.Handle(request, base::Bind(&OnResponse, &response)); 48 ASSERT_EQ(net::HTTP_BAD_REQUEST, response.status_code()); 49 } 50 51 TEST(HttpHandlerTest, HandleUnknownCommand) { 52 Logger log; 53 HttpHandler handler(&log, "/"); 54 net::HttpServerRequestInfo request; 55 request.method = "get"; 56 request.path = "/path"; 57 net::HttpServerResponseInfo response; 58 handler.Handle(request, base::Bind(&OnResponse, &response)); 59 ASSERT_EQ(net::HTTP_NOT_FOUND, response.status_code()); 60 } 61 62 TEST(HttpHandlerTest, HandleNewSession) { 63 Logger log; 64 HttpHandler handler(&log, "/base/"); 65 handler.command_map_.reset(new HttpHandler::CommandMap()); 66 handler.command_map_->push_back( 67 CommandMapping(kPost, internal::kNewSessionPathPattern, 68 base::Bind(&DummyCommand, Status(kOk)))); 69 net::HttpServerRequestInfo request; 70 request.method = "post"; 71 request.path = "/base/session"; 72 net::HttpServerResponseInfo response; 73 handler.Handle(request, base::Bind(&OnResponse, &response)); 74 ASSERT_EQ(net::HTTP_SEE_OTHER, response.status_code()); 75 ASSERT_NE(std::string::npos, 76 response.Serialize().find("Location:/base/session/")) 77 << response.Serialize(); 78 } 79 80 TEST(HttpHandlerTest, HandleInvalidPost) { 81 Logger log; 82 HttpHandler handler(&log, "/"); 83 handler.command_map_->push_back( 84 CommandMapping(kPost, "path", base::Bind(&DummyCommand, Status(kOk)))); 85 net::HttpServerRequestInfo request; 86 request.method = "post"; 87 request.path = "/path"; 88 request.data = "should be a dictionary"; 89 net::HttpServerResponseInfo response; 90 handler.Handle(request, base::Bind(&OnResponse, &response)); 91 ASSERT_EQ(net::HTTP_BAD_REQUEST, response.status_code()); 92 } 93 94 TEST(HttpHandlerTest, HandleUnimplementedCommand) { 95 Logger log; 96 HttpHandler handler(&log, "/"); 97 handler.command_map_->push_back( 98 CommandMapping(kPost, "path", 99 base::Bind(&DummyCommand, Status(kUnknownCommand)))); 100 net::HttpServerRequestInfo request; 101 request.method = "post"; 102 request.path = "/path"; 103 net::HttpServerResponseInfo response; 104 handler.Handle(request, base::Bind(&OnResponse, &response)); 105 ASSERT_EQ(net::HTTP_NOT_IMPLEMENTED, response.status_code()); 106 } 107 108 TEST(HttpHandlerTest, HandleCommand) { 109 Logger log; 110 HttpHandler handler(&log, "/"); 111 handler.command_map_->push_back( 112 CommandMapping(kPost, "path", base::Bind(&DummyCommand, Status(kOk)))); 113 net::HttpServerRequestInfo request; 114 request.method = "post"; 115 request.path = "/path"; 116 net::HttpServerResponseInfo response; 117 handler.Handle(request, base::Bind(&OnResponse, &response)); 118 ASSERT_EQ(net::HTTP_OK, response.status_code()); 119 base::DictionaryValue body; 120 body.SetInteger("status", kOk); 121 body.SetInteger("value", 1); 122 body.SetString("sessionId", "session_id"); 123 std::string json; 124 base::JSONWriter::Write(&body, &json); 125 ASSERT_STREQ(json.c_str(), response.body().c_str()); 126 } 127 128 TEST(MatchesCommandTest, DiffMethod) { 129 CommandMapping command(kPost, "path", base::Bind(&DummyCommand, Status(kOk))); 130 std::string session_id; 131 base::DictionaryValue params; 132 ASSERT_FALSE(internal::MatchesCommand( 133 "get", "path", command, &session_id, ¶ms)); 134 ASSERT_STREQ("", session_id.c_str()); 135 ASSERT_EQ(0u, params.size()); 136 } 137 138 TEST(MatchesCommandTest, DiffPathLength) { 139 CommandMapping command(kPost, "path/path", 140 base::Bind(&DummyCommand, Status(kOk))); 141 std::string session_id; 142 base::DictionaryValue params; 143 ASSERT_FALSE(internal::MatchesCommand( 144 "post", "path", command, &session_id, ¶ms)); 145 ASSERT_FALSE(internal::MatchesCommand( 146 "post", std::string(), command, &session_id, ¶ms)); 147 ASSERT_FALSE( 148 internal::MatchesCommand("post", "/", command, &session_id, ¶ms)); 149 ASSERT_FALSE(internal::MatchesCommand( 150 "post", "path/path/path", command, &session_id, ¶ms)); 151 } 152 153 TEST(MatchesCommandTest, DiffPaths) { 154 CommandMapping command(kPost, "path/apath", 155 base::Bind(&DummyCommand, Status(kOk))); 156 std::string session_id; 157 base::DictionaryValue params; 158 ASSERT_FALSE(internal::MatchesCommand( 159 "post", "path/bpath", command, &session_id, ¶ms)); 160 } 161 162 TEST(MatchesCommandTest, Substitution) { 163 CommandMapping command(kPost, "path/:sessionId/space/:a/:b", 164 base::Bind(&DummyCommand, Status(kOk))); 165 std::string session_id; 166 base::DictionaryValue params; 167 ASSERT_TRUE(internal::MatchesCommand( 168 "post", "path/1/space/2/3", command, &session_id, ¶ms)); 169 ASSERT_EQ("1", session_id); 170 ASSERT_EQ(2u, params.size()); 171 std::string param; 172 ASSERT_TRUE(params.GetString("a", ¶m)); 173 ASSERT_EQ("2", param); 174 ASSERT_TRUE(params.GetString("b", ¶m)); 175 ASSERT_EQ("3", param); 176 } 177