Home | History | Annotate | Download | only in server
      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, &params));
    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, &params));
    145   ASSERT_FALSE(internal::MatchesCommand(
    146       "post", std::string(), command, &session_id, &params));
    147   ASSERT_FALSE(
    148       internal::MatchesCommand("post", "/", command, &session_id, &params));
    149   ASSERT_FALSE(internal::MatchesCommand(
    150       "post", "path/path/path", command, &session_id, &params));
    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, &params));
    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, &params));
    169   ASSERT_EQ("1", session_id);
    170   ASSERT_EQ(2u, params.size());
    171   std::string param;
    172   ASSERT_TRUE(params.GetString("a", &param));
    173   ASSERT_EQ("2", param);
    174   ASSERT_TRUE(params.GetString("b", &param));
    175   ASSERT_EQ("3", param);
    176 }
    177