12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/log.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h"
13a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/test/chromedriver/command.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/server/http_handler.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/http/http_status_code.h"
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "net/server/http_server_request_info.h"
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/server/http_server_response_info.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22a3f7b4e666c476898878fa745f637129375cd889Ben Murdochvoid DummyCommand(
23a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const Status& status,
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::DictionaryValue& params,
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& session_id,
26a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const CommandCallback& callback) {
27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  callback.Run(status,
28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch               scoped_ptr<base::Value>(new base::FundamentalValue(1)),
29a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch               "session_id");
30a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
31a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OnResponse(net::HttpServerResponseInfo* response_to_set,
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                scoped_ptr<net::HttpServerResponseInfo> response) {
34a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  *response_to_set = *response;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(HttpHandlerTest, HandleOutsideOfBaseUrl) {
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  HttpHandler handler("base/url/");
41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  net::HttpServerRequestInfo request;
42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.method = "get";
43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.path = "base/path";
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.data = "body";
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  net::HttpServerResponseInfo response;
46a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  handler.Handle(request, base::Bind(&OnResponse, &response));
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(net::HTTP_BAD_REQUEST, response.status_code());
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(HttpHandlerTest, HandleUnknownCommand) {
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  HttpHandler handler("/");
52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  net::HttpServerRequestInfo request;
53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.method = "get";
54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.path = "/path";
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  net::HttpServerResponseInfo response;
56a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  handler.Handle(request, base::Bind(&OnResponse, &response));
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(net::HTTP_NOT_FOUND, response.status_code());
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(HttpHandlerTest, HandleNewSession) {
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  HttpHandler handler("/base/");
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  handler.command_map_.reset(new HttpHandler::CommandMap());
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  handler.command_map_->push_back(
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kPost, internal::kNewSessionPathPattern,
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&DummyCommand, Status(kOk))));
66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  net::HttpServerRequestInfo request;
67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.method = "post";
68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.path = "/base/session";
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  net::HttpServerResponseInfo response;
70a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  handler.Handle(request, base::Bind(&OnResponse, &response));
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(net::HTTP_OK, response.status_code());
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::DictionaryValue body;
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  body.SetInteger("status", kOk);
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  body.SetInteger("value", 1);
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  body.SetString("sessionId", "session_id");
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string json;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::JSONWriter::Write(&body, &json);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(json, response.body());
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(HttpHandlerTest, HandleInvalidPost) {
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  HttpHandler handler("/");
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  handler.command_map_->push_back(
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kPost, "path", base::Bind(&DummyCommand, Status(kOk))));
85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  net::HttpServerRequestInfo request;
86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.method = "post";
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.path = "/path";
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.data = "should be a dictionary";
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  net::HttpServerResponseInfo response;
90a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  handler.Handle(request, base::Bind(&OnResponse, &response));
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(net::HTTP_BAD_REQUEST, response.status_code());
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(HttpHandlerTest, HandleUnimplementedCommand) {
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  HttpHandler handler("/");
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  handler.command_map_->push_back(
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kPost, "path",
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     base::Bind(&DummyCommand, Status(kUnknownCommand))));
99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  net::HttpServerRequestInfo request;
100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.method = "post";
101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.path = "/path";
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  net::HttpServerResponseInfo response;
103a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  handler.Handle(request, base::Bind(&OnResponse, &response));
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(net::HTTP_NOT_IMPLEMENTED, response.status_code());
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(HttpHandlerTest, HandleCommand) {
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  HttpHandler handler("/");
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  handler.command_map_->push_back(
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CommandMapping(kPost, "path", base::Bind(&DummyCommand, Status(kOk))));
111ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  net::HttpServerRequestInfo request;
112ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.method = "post";
113ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  request.path = "/path";
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  net::HttpServerResponseInfo response;
115a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  handler.Handle(request, base::Bind(&OnResponse, &response));
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ASSERT_EQ(net::HTTP_OK, response.status_code());
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue body;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  body.SetInteger("status", kOk);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  body.SetInteger("value", 1);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  body.SetString("sessionId", "session_id");
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string json;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::JSONWriter::Write(&body, &json);
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(json, response.body());
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MatchesCommandTest, DiffMethod) {
127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CommandMapping command(kPost, "path", base::Bind(&DummyCommand, Status(kOk)));
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string session_id;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(internal::MatchesCommand(
131ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      "get", "path", command, &session_id, &params));
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(session_id.empty());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(0u, params.size());
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MatchesCommandTest, DiffPathLength) {
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CommandMapping command(kPost, "path/path",
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::Bind(&DummyCommand, Status(kOk)));
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string session_id;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(internal::MatchesCommand(
142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      "post", "path", command, &session_id, &params));
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(internal::MatchesCommand(
144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      "post", std::string(), command, &session_id, &params));
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(
146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      internal::MatchesCommand("post", "/", command, &session_id, &params));
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(internal::MatchesCommand(
148ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      "post", "path/path/path", command, &session_id, &params));
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MatchesCommandTest, DiffPaths) {
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CommandMapping command(kPost, "path/apath",
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::Bind(&DummyCommand, Status(kOk)));
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string session_id;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(internal::MatchesCommand(
157ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      "post", "path/bpath", command, &session_id, &params));
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MatchesCommandTest, Substitution) {
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CommandMapping command(kPost, "path/:sessionId/space/:a/:b",
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::Bind(&DummyCommand, Status(kOk)));
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string session_id;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(internal::MatchesCommand(
166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      "post", "path/1/space/2/3", command, &session_id, &params));
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ("1", session_id);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2u, params.size());
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string param;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(params.GetString("a", &param));
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ("2", param);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(params.GetString("b", &param));
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ("3", param);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
175