-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
23 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,151 +1,56 @@ | ||
#include "cgimap/api06/handler_utils.hpp" | ||
#include "cgimap/api06/id_version_io.hpp" | ||
#include <iostream> | ||
#include <sstream> | ||
#include <string> | ||
#include <map> | ||
#include "test_request.hpp" | ||
|
||
namespace { | ||
|
||
struct test_request : public request { | ||
test_request() = default; | ||
|
||
/// implementation of request interface | ||
virtual ~test_request() = default; | ||
const char *get_param(const char *key) const override { | ||
std::string key_str(key); | ||
auto itr = m_params.find(key_str); | ||
if (itr != m_params.end()) { | ||
return itr->second.c_str(); | ||
} else { | ||
return NULL; | ||
} | ||
} | ||
|
||
const std::string get_payload() override { | ||
return ""; | ||
} | ||
|
||
void dispose() override {} | ||
|
||
/// getters and setters for the input headers and output response | ||
void set_header(const std::string &k, const std::string &v) { | ||
m_params.insert(std::make_pair(k, v)); | ||
} | ||
std::stringstream &buffer() { assert(false); } | ||
|
||
std::chrono::system_clock::time_point get_current_time() const override { | ||
return std::chrono::system_clock::time_point(); | ||
} | ||
|
||
protected: | ||
void write_header_info(int status, const http::headers_t &headers) override {} | ||
output_buffer& get_buffer_internal() override { | ||
throw std::runtime_error("test_request::get_buffer_internal unimplemented."); | ||
} | ||
void finish_internal() override {} | ||
|
||
private: | ||
std::map<std::string, std::string> m_params; | ||
}; | ||
#define CATCH_CONFIG_MAIN | ||
#include <catch2/catch.hpp> | ||
|
||
std::vector<api06::id_version> parse_query_str(std::string query_str) { | ||
test_request req; | ||
req.set_header("REQUEST_METHOD", "GET"); | ||
req.set_header("QUERY_STRING", query_str); | ||
req.set_header("PATH_INFO", "/api/0.6/nodes"); | ||
|
||
return api06::parse_id_list_params(req, "nodes"); | ||
} | ||
|
||
void test_parse_returns_no_duplicates() { | ||
TEST_CASE("Id list returns no duplicates", "[idlist]") { | ||
// the container returned from parse_id_list_params should not contain any duplicates. | ||
std::string query_str = "nodes=1,1,1,1"; | ||
|
||
// the container returned from parse_id_list_params should not contain | ||
// any duplicates. | ||
std::vector<api06::id_version> ids = parse_query_str(query_str); | ||
|
||
if (ids.size() != 1) { | ||
std::ostringstream err; | ||
err << "Parsing " << query_str << " as a list of nodes should " | ||
<< "discard duplicates, but got: {"; | ||
for (api06::id_version id : ids) { | ||
err << id << ", "; | ||
} | ||
err << "}\n"; | ||
throw std::runtime_error(err.str()); | ||
} | ||
auto ids = parse_query_str(query_str); | ||
CHECK(ids.size() == 1); | ||
} | ||
|
||
void test_parse_negative_nodes() { | ||
TEST_CASE("Id list parse negative nodes", "[idlist]") { | ||
|
||
std::string query_str = | ||
"nodes=-1875196430,1970729486,-715595887,153329585,276538320,276538320," | ||
"276538320,276538320,557671215,268800768,268800768,272134694,416571249," | ||
"4118507737,639141976,-120408340,4118507737,4118507737,-176459559," | ||
"-176459559,-176459559,416571249,-176459559,-176459559,-176459559," | ||
"557671215"; | ||
|
||
std::vector<api06::id_version> ids = parse_query_str(query_str); | ||
auto ids = parse_query_str(query_str); | ||
|
||
// maximum ID that postgres can handle is 2^63-1, so that should never | ||
// be returned by the parsing function. | ||
const osm_nwr_id_t max_id = std::numeric_limits<int64_t>::max(); | ||
for (api06::id_version idv : ids) { | ||
if (idv.id > max_id) { | ||
throw std::runtime_error("Found ID > max allowed ID in parsed list."); | ||
} | ||
CHECK (idv.id < max_id); | ||
} | ||
} | ||
|
||
void test_parse_garbage() { | ||
std::string query_str = | ||
"nodes=\xf5"; | ||
|
||
// may not crash | ||
std::vector<api06::id_version> ids = parse_query_str(query_str); | ||
|
||
TEST_CASE("Id list with garbage", "[idlist]") { | ||
std::string query_str = "nodes=\xf5"; | ||
REQUIRE_NOTHROW(parse_query_str(query_str)); | ||
} | ||
|
||
void test_parse_history() { | ||
TEST_CASE("Id list with history", "[idlist]") { | ||
std::string query_str = "nodes=1,1v1"; | ||
auto ids = parse_query_str(query_str); | ||
|
||
std::vector<api06::id_version> ids = parse_query_str(query_str); | ||
|
||
if (ids.size() != 2) { | ||
throw std::runtime_error("Expected ID list of size 2."); | ||
} | ||
|
||
// NOTE: ID list is uniqued and sorted, which puts the "latest" version | ||
// at the end. | ||
if (ids[0] != api06::id_version(1, 1)) { | ||
std::ostringstream out; | ||
out << "Expected ID=1, version=1 to be the first element, but got " | ||
<< ids[0] << "."; | ||
throw std::runtime_error(out.str()); | ||
} | ||
|
||
if (ids[1] != api06::id_version(1)) { | ||
throw std::runtime_error("Expected ID=1, latest version to be the second element."); | ||
} | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
int main(int argc, char *argv[]) { | ||
try { | ||
test_parse_returns_no_duplicates(); | ||
test_parse_negative_nodes(); | ||
test_parse_history(); | ||
test_parse_garbage(); | ||
|
||
} catch (const std::exception &e) { | ||
std::cout << "Error: " << e.what() << std::endl; | ||
return 1; | ||
|
||
} catch (...) { | ||
std::cout << "Unknown exception type." << std::endl; | ||
return 99; | ||
} | ||
CHECK(ids.size() == 2); | ||
|
||
return 0; | ||
// NOTE: ID list is uniqued and sorted, which puts the "latest" version at the end. | ||
CHECK(ids[0] == api06::id_version(1, 1)); | ||
CHECK(ids[1] == api06::id_version(1)); | ||
} |