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 HttpHandler handler("base/url/"); 41 net::HttpServerRequestInfo request; 42 request.method = "get"; 43 request.path = "base/path"; 44 request.data = "body"; 45 net::HttpServerResponseInfo response; 46 handler.Handle(request, base::Bind(&OnResponse, &response)); 47 ASSERT_EQ(net::HTTP_BAD_REQUEST, response.status_code()); 48 } 49 50 TEST(HttpHandlerTest, HandleUnknownCommand) { 51 HttpHandler handler("/"); 52 net::HttpServerRequestInfo request; 53 request.method = "get"; 54 request.path = "/path"; 55 net::HttpServerResponseInfo response; 56 handler.Handle(request, base::Bind(&OnResponse, &response)); 57 ASSERT_EQ(net::HTTP_NOT_FOUND, response.status_code()); 58 } 59 60 TEST(HttpHandlerTest, HandleNewSession) { 61 HttpHandler handler("/base/"); 62 handler.command_map_.reset(new HttpHandler::CommandMap()); 63 handler.command_map_->push_back( 64 CommandMapping(kPost, internal::kNewSessionPathPattern, 65 base::Bind(&DummyCommand, Status(kOk)))); 66 net::HttpServerRequestInfo request; 67 request.method = "post"; 68 request.path = "/base/session"; 69 net::HttpServerResponseInfo response; 70 handler.Handle(request, base::Bind(&OnResponse, &response)); 71 ASSERT_EQ(net::HTTP_OK, response.status_code()); 72 base::DictionaryValue body; 73 body.SetInteger("status", kOk); 74 body.SetInteger("value", 1); 75 body.SetString("sessionId", "session_id"); 76 std::string json; 77 base::JSONWriter::Write(&body, &json); 78 ASSERT_EQ(json, response.body()); 79 } 80 81 TEST(HttpHandlerTest, HandleInvalidPost) { 82 HttpHandler handler("/"); 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 HttpHandler handler("/"); 96 handler.command_map_->push_back( 97 CommandMapping(kPost, "path", 98 base::Bind(&DummyCommand, Status(kUnknownCommand)))); 99 net::HttpServerRequestInfo request; 100 request.method = "post"; 101 request.path = "/path"; 102 net::HttpServerResponseInfo response; 103 handler.Handle(request, base::Bind(&OnResponse, &response)); 104 ASSERT_EQ(net::HTTP_NOT_IMPLEMENTED, response.status_code()); 105 } 106 107 TEST(HttpHandlerTest, HandleCommand) { 108 HttpHandler handler("/"); 109 handler.command_map_->push_back( 110 CommandMapping(kPost, "path", base::Bind(&DummyCommand, Status(kOk)))); 111 net::HttpServerRequestInfo request; 112 request.method = "post"; 113 request.path = "/path"; 114 net::HttpServerResponseInfo response; 115 handler.Handle(request, base::Bind(&OnResponse, &response)); 116 ASSERT_EQ(net::HTTP_OK, response.status_code()); 117 base::DictionaryValue body; 118 body.SetInteger("status", kOk); 119 body.SetInteger("value", 1); 120 body.SetString("sessionId", "session_id"); 121 std::string json; 122 base::JSONWriter::Write(&body, &json); 123 ASSERT_EQ(json, response.body()); 124 } 125 126 TEST(MatchesCommandTest, DiffMethod) { 127 CommandMapping command(kPost, "path", base::Bind(&DummyCommand, Status(kOk))); 128 std::string session_id; 129 base::DictionaryValue params; 130 ASSERT_FALSE(internal::MatchesCommand( 131 "get", "path", command, &session_id, ¶ms)); 132 ASSERT_TRUE(session_id.empty()); 133 ASSERT_EQ(0u, params.size()); 134 } 135 136 TEST(MatchesCommandTest, DiffPathLength) { 137 CommandMapping command(kPost, "path/path", 138 base::Bind(&DummyCommand, Status(kOk))); 139 std::string session_id; 140 base::DictionaryValue params; 141 ASSERT_FALSE(internal::MatchesCommand( 142 "post", "path", command, &session_id, ¶ms)); 143 ASSERT_FALSE(internal::MatchesCommand( 144 "post", std::string(), command, &session_id, ¶ms)); 145 ASSERT_FALSE( 146 internal::MatchesCommand("post", "/", command, &session_id, ¶ms)); 147 ASSERT_FALSE(internal::MatchesCommand( 148 "post", "path/path/path", command, &session_id, ¶ms)); 149 } 150 151 TEST(MatchesCommandTest, DiffPaths) { 152 CommandMapping command(kPost, "path/apath", 153 base::Bind(&DummyCommand, Status(kOk))); 154 std::string session_id; 155 base::DictionaryValue params; 156 ASSERT_FALSE(internal::MatchesCommand( 157 "post", "path/bpath", command, &session_id, ¶ms)); 158 } 159 160 TEST(MatchesCommandTest, Substitution) { 161 CommandMapping command(kPost, "path/:sessionId/space/:a/:b", 162 base::Bind(&DummyCommand, Status(kOk))); 163 std::string session_id; 164 base::DictionaryValue params; 165 ASSERT_TRUE(internal::MatchesCommand( 166 "post", "path/1/space/2/3", command, &session_id, ¶ms)); 167 ASSERT_EQ("1", session_id); 168 ASSERT_EQ(2u, params.size()); 169 std::string param; 170 ASSERT_TRUE(params.GetString("a", ¶m)); 171 ASSERT_EQ("2", param); 172 ASSERT_TRUE(params.GetString("b", ¶m)); 173 ASSERT_EQ("3", param); 174 } 175