OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 "base/format_macros.h" | |
6 #include "base/json/json_reader.h" | |
7 #include "base/memory/scoped_ptr.h" | |
8 #include "base/strings/stringprintf.h" | |
9 #include "base/values.h" | |
10 #include "chrome/test/webdriver/commands/response.h" | |
11 #include "chrome/test/webdriver/http_response.h" | |
12 #include "chrome/test/webdriver/webdriver_dispatch.h" | |
13 #include "chrome/test/webdriver/webdriver_session_manager.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 #include "third_party/mongoose/mongoose.h" | |
16 | |
17 namespace webdriver { | |
18 | |
19 namespace { | |
20 | |
21 void ExpectHeaderValue(const HttpResponse& response, const std::string& name, | |
22 const std::string& expected_value) { | |
23 std::string actual_value; | |
24 EXPECT_TRUE(response.GetHeader(name, &actual_value)); | |
25 EXPECT_EQ(expected_value, actual_value); | |
26 } | |
27 | |
28 void ExpectHttpStatus(int expected_status, | |
29 const Response& command_response, | |
30 HttpResponse* const http_response) { | |
31 internal::PrepareHttpResponse(command_response, http_response); | |
32 EXPECT_EQ(expected_status, http_response->status()); | |
33 } | |
34 | |
35 void ExpectInternalError(ErrorCode command_status, | |
36 Response* command_response, | |
37 HttpResponse* const http_response) { | |
38 command_response->SetStatus(command_status); | |
39 http_response->set_status(HttpResponse::kOk); // Reset to detect changes. | |
40 ExpectHttpStatus(HttpResponse::kInternalServerError, | |
41 *command_response, http_response); | |
42 } | |
43 | |
44 } // namespace | |
45 | |
46 TEST(DispatchTest, CorrectlyConvertsResponseCodesToHttpStatusCodes) { | |
47 HttpResponse http_response; | |
48 | |
49 Response command_response; | |
50 command_response.SetValue(new base::StringValue("foobar")); | |
51 | |
52 command_response.SetStatus(kSuccess); | |
53 ExpectHttpStatus(HttpResponse::kOk, command_response, &http_response); | |
54 | |
55 command_response.SetStatus(kSeeOther); | |
56 ExpectHttpStatus(HttpResponse::kSeeOther, command_response, &http_response); | |
57 ExpectHeaderValue(http_response, "location", "foobar"); | |
58 http_response.ClearHeaders(); | |
59 | |
60 command_response.SetStatus(kBadRequest); | |
61 ExpectHttpStatus(HttpResponse::kBadRequest, command_response, | |
62 &http_response); | |
63 | |
64 command_response.SetStatus(kSessionNotFound); | |
65 ExpectHttpStatus(HttpResponse::kNotFound, command_response, | |
66 &http_response); | |
67 | |
68 base::ListValue* methods = new base::ListValue; | |
69 methods->Append(new base::StringValue("POST")); | |
70 methods->Append(new base::StringValue("GET")); | |
71 command_response.SetValue(methods); | |
72 command_response.SetStatus(kMethodNotAllowed); | |
73 ExpectHttpStatus(HttpResponse::kMethodNotAllowed, command_response, | |
74 &http_response); | |
75 ExpectHeaderValue(http_response, "allow", "POST,GET"); | |
76 http_response.ClearHeaders(); | |
77 | |
78 ExpectInternalError(kNoSuchElement, &command_response, &http_response); | |
79 ExpectInternalError(kNoSuchFrame, &command_response, &http_response); | |
80 ExpectInternalError(kUnknownCommand, &command_response, &http_response); | |
81 ExpectInternalError(kStaleElementReference, &command_response, | |
82 &http_response); | |
83 ExpectInternalError(kInvalidElementState, &command_response, &http_response); | |
84 ExpectInternalError(kUnknownError, &command_response, &http_response); | |
85 ExpectInternalError(kElementNotSelectable, &command_response, | |
86 &http_response); | |
87 ExpectInternalError(kXPathLookupError, &command_response, &http_response); | |
88 ExpectInternalError(kNoSuchWindow, &command_response, &http_response); | |
89 ExpectInternalError(kInvalidCookieDomain, &command_response, &http_response); | |
90 ExpectInternalError(kUnableToSetCookie, &command_response, &http_response); | |
91 ExpectInternalError(kInternalServerError, &command_response, &http_response); | |
92 } | |
93 | |
94 TEST(DispatchTest, | |
95 ReturnsAnErrorOnNonStringMethodsListedOnAMethodNotAllowedResponse) { | |
96 base::ListValue* methods = new base::ListValue; | |
97 methods->Append(new base::StringValue("POST")); | |
98 methods->Append(new base::DictionaryValue); | |
99 methods->Append(new base::StringValue("GET")); | |
100 methods->Append(new base::DictionaryValue); | |
101 methods->Append(new base::StringValue("DELETE")); | |
102 | |
103 Response command_response; | |
104 command_response.SetStatus(kMethodNotAllowed); | |
105 command_response.SetValue(methods); | |
106 | |
107 HttpResponse http_response; | |
108 ExpectHttpStatus(HttpResponse::kInternalServerError, command_response, | |
109 &http_response); | |
110 } | |
111 | |
112 TEST(DispatchTest, ReturnsCommandResponseAsJson) { | |
113 const std::string kExpectedData = "{\"status\":0,\"value\":\"foobar\"}"; | |
114 | |
115 Response command_response; | |
116 command_response.SetStatus(kSuccess); | |
117 command_response.SetValue(new base::StringValue("foobar")); | |
118 | |
119 HttpResponse http_response; | |
120 internal::PrepareHttpResponse(command_response, &http_response); | |
121 EXPECT_EQ(HttpResponse::kOk, http_response.status()); | |
122 ExpectHeaderValue(http_response, "content-type", | |
123 "application/json; charset=utf-8"); | |
124 | |
125 // We do not know whether the response status or value will be | |
126 // encoded first, so we have to parse the response body to | |
127 // verify it is correct. | |
128 int error_code; | |
129 std::string error_message; | |
130 scoped_ptr<base::Value> parsed_response(base::JSONReader::ReadAndReturnError( | |
131 http_response.body(), base::JSON_PARSE_RFC, &error_code, &error_message)); | |
132 | |
133 ASSERT_TRUE(parsed_response.get() != NULL) << error_message; | |
134 ASSERT_TRUE(parsed_response->IsType(base::Value::TYPE_DICTIONARY)) | |
135 << "Response should be a dictionary: " << http_response.body(); | |
136 | |
137 base::DictionaryValue* dict = | |
138 static_cast<base::DictionaryValue*>(parsed_response.get()); | |
139 EXPECT_EQ(2u, dict->size()); | |
140 EXPECT_TRUE(dict->HasKey("status")); | |
141 EXPECT_TRUE(dict->HasKey("value")); | |
142 | |
143 int status = -1; | |
144 EXPECT_TRUE(dict->GetInteger("status", &status)); | |
145 EXPECT_EQ(kSuccess, static_cast<ErrorCode>(status)); | |
146 | |
147 std::string value; | |
148 EXPECT_TRUE(dict->GetStringASCII("value", &value)); | |
149 EXPECT_EQ("foobar", value); | |
150 } | |
151 | |
152 class ParseRequestInfoTest : public testing::Test { | |
153 public: | |
154 static char kGet[]; | |
155 static char kTestPath[]; | |
156 | |
157 ParseRequestInfoTest() {} | |
158 virtual ~ParseRequestInfoTest() {} | |
159 | |
160 virtual void TearDown() { | |
161 SessionManager::GetInstance()->set_url_base(std::string()); | |
162 } | |
163 | |
164 private: | |
165 DISALLOW_COPY_AND_ASSIGN(ParseRequestInfoTest); | |
166 }; | |
167 | |
168 char ParseRequestInfoTest::kGet[] = "GET"; | |
169 char ParseRequestInfoTest::kTestPath[] = "/foo/bar/baz"; | |
170 | |
171 TEST_F(ParseRequestInfoTest, ParseRequestWithEmptyUrlBase) { | |
172 struct mg_request_info request_info; | |
173 request_info.request_method = kGet; | |
174 request_info.uri = kTestPath; | |
175 | |
176 std::string method; | |
177 std::vector<std::string> path_segments; | |
178 base::DictionaryValue* parameters; | |
179 Response response; | |
180 | |
181 SessionManager::GetInstance()->set_url_base(std::string()); | |
182 EXPECT_TRUE(internal::ParseRequestInfo( | |
183 &request_info, | |
184 NULL, // NULL is ok because GET not POST is used | |
185 &method, | |
186 &path_segments, | |
187 ¶meters, | |
188 &response)); | |
189 EXPECT_EQ("GET", method); | |
190 ASSERT_EQ(4u, path_segments.size()); | |
191 EXPECT_EQ("", path_segments[0]); | |
192 EXPECT_EQ("foo", path_segments[1]); | |
193 EXPECT_EQ("bar", path_segments[2]); | |
194 EXPECT_EQ("baz", path_segments[3]); | |
195 } | |
196 | |
197 TEST_F(ParseRequestInfoTest, ParseRequestStripsNonEmptyUrlBaseFromPath) { | |
198 struct mg_request_info request_info; | |
199 request_info.request_method = kGet; | |
200 request_info.uri = kTestPath; | |
201 | |
202 std::string method; | |
203 std::vector<std::string> path_segments; | |
204 base::DictionaryValue* parameters; | |
205 Response response; | |
206 | |
207 SessionManager::GetInstance()->set_url_base("/foo"); | |
208 EXPECT_TRUE(internal::ParseRequestInfo( | |
209 &request_info, | |
210 NULL, // NULL is ok because GET not POST is used | |
211 &method, | |
212 &path_segments, | |
213 ¶meters, | |
214 &response)); | |
215 EXPECT_EQ("GET", method); | |
216 ASSERT_EQ(3u, path_segments.size()); | |
217 EXPECT_EQ("", path_segments[0]); | |
218 EXPECT_EQ("bar", path_segments[1]); | |
219 EXPECT_EQ("baz", path_segments[2]); | |
220 } | |
221 | |
222 } // namespace webdriver | |
OLD | NEW |