123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #include <config.h>
- #include <cc/data.h>
- #include <http/post_request_json.h>
- #include <http/tests/request_test.h>
- #include <gtest/gtest.h>
- #include <map>
- using namespace isc::data;
- using namespace isc::http;
- using namespace isc::http::test;
- namespace {
- /// @brief Test fixture class for @ref PostHttpRequestJson.
- class PostHttpRequestJsonTest :
- public HttpRequestTestBase<PostHttpRequestJson> {
- public:
- /// @brief Constructor.
- PostHttpRequestJsonTest()
- : HttpRequestTestBase<PostHttpRequestJson>(),
- json_body_("{ \"service\": \"dhcp4\", \"param1\": \"foo\" }") {
- }
- /// @brief Sets new JSON body for the HTTP request context.
- ///
- /// If the body parameter is empty, it will use the value of
- /// @ref json_body_ member. Otherwise, it will assign the body
- /// provided as parameter.
- ///
- /// @param body new body value.
- void setBody(const std::string& body = "") {
- request_.context()->body_ = body.empty() ? json_body_ : body;
- }
- /// @brief Default value of the JSON body.
- std::string json_body_;
- };
- // This test verifies that PostHttpRequestJson class only accepts
- // POST messages.
- TEST_F(PostHttpRequestJsonTest, requiredPost) {
- // Use a GET method that is not supported.
- setContextBasics("GET", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- ASSERT_THROW(request_.create(), HttpRequestError);
- // Now use POST. It should be accepted.
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- EXPECT_NO_THROW(request_.create());
- }
- // This test verifies that PostHttpRequest requires "Content-Length"
- // header equal to "application/json".
- TEST_F(PostHttpRequestJsonTest, requireContentTypeJson) {
- // Specify "Content-Type" other than "application/json".
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "text/html");
- ASSERT_THROW(request_.create(), HttpRequestError);
- // This time specify correct "Content-Type". It should pass.
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- EXPECT_NO_THROW(request_.create());
- }
- // This test verifies that PostHttpRequest requires "Content-Length"
- // header.
- TEST_F(PostHttpRequestJsonTest, requireContentLength) {
- // "Content-Length" is not specified initially. It should fail.
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Type", "text/html");
- ASSERT_THROW(request_.create(), HttpRequestError);
- // Specify "Content-Length". It should pass.
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- }
- // This test verifies that JSON body can be retrieved from the
- // HTTP request.
- TEST_F(PostHttpRequestJsonTest, getBodyAsJson) {
- // Create HTTP POST request with JSON body.
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- setBody();
- ASSERT_NO_THROW(request_.finalize());
- // Try to retrieve pointer to the root element of the JSON body.
- ConstElementPtr json = request_.getBodyAsJson();
- ASSERT_TRUE(json);
- // Iterate over JSON values and store them in a simple map.
- std::map<std::string, std::string> config_values;
- for (auto config_element = json->mapValue().begin();
- config_element != json->mapValue().end();
- ++config_element) {
- ASSERT_FALSE(config_element->first.empty());
- ASSERT_TRUE(config_element->second);
- config_values[config_element->first] = config_element->second->stringValue();
- }
- // Verify the values.
- EXPECT_EQ("dhcp4", config_values["service"]);
- EXPECT_EQ("foo", config_values["param1"]);
- }
- // This test verifies that an attempt to parse/retrieve malformed
- // JSON structure will cause an exception.
- TEST_F(PostHttpRequestJsonTest, getBodyAsJsonMalformed) {
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- // No colon before 123.
- setBody("{ \"command\" 123 }" );
- EXPECT_THROW(request_.finalize(), HttpRequestJsonError);
- }
- // This test verifies that NULL pointer is returned when trying to
- // retrieve root element of the empty JSON structure.
- TEST_F(PostHttpRequestJsonTest, getEmptyJsonBody) {
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- ASSERT_NO_THROW(request_.finalize());
- ConstElementPtr json = request_.getBodyAsJson();
- EXPECT_FALSE(json);
- }
- // This test verifies that the specific JSON element can be retrieved.
- TEST_F(PostHttpRequestJsonTest, getJsonElement) {
- setContextBasics("POST", "/isc/org", std::make_pair(1, 0));
- addHeaderToContext("Content-Length", json_body_.length());
- addHeaderToContext("Content-Type", "application/json");
- setBody();
- ASSERT_NO_THROW(request_.finalize());
- ConstElementPtr element;
- ASSERT_NO_THROW(element = request_.getJsonElement("service"));
- ASSERT_TRUE(element);
- EXPECT_EQ("dhcp4", element->stringValue());
- // An attempt to retrieve non-existing element should return NULL.
- EXPECT_FALSE(request_.getJsonElement("bar"));
- }
- }
|