1 #include "async_resp.hpp" // IWYU pragma: keep 2 #include "http_request.hpp" 3 #include "routing.hpp" 4 #include "utility.hpp" 5 6 #include <boost/beast/http/message.hpp> // IWYU pragma: keep 7 #include <boost/beast/http/verb.hpp> 8 9 #include <memory> 10 #include <string> 11 #include <string_view> 12 #include <system_error> 13 14 #include <gtest/gtest.h> // IWYU pragma: keep 15 16 // IWYU pragma: no_include <boost/beast/http/impl/message.hpp> 17 // IWYU pragma: no_include "gtest/gtest_pred_impl.h" 18 // IWYU pragma: no_include <boost/intrusive/detail/list_iterator.hpp> 19 // IWYU pragma: no_include <gtest/gtest-message.h> 20 // IWYU pragma: no_include <gtest/gtest-test-part.h> 21 // IWYU pragma: no_forward_declare bmcweb::AsyncResp 22 23 namespace crow 24 { 25 namespace 26 { 27 28 using ::crow::black_magic::getParameterTag; 29 30 TEST(Router, AllowHeader) 31 { 32 // Callback handler that does nothing 33 auto nullCallback = [](const Request&, 34 const std::shared_ptr<bmcweb::AsyncResp>&) {}; 35 36 Router router; 37 std::error_code ec; 38 39 constexpr std::string_view url = "/foo"; 40 41 Request req{{boost::beast::http::verb::get, url, 11}, ec}; 42 43 // No route should return no methods. 44 router.validate(); 45 EXPECT_EQ(router.findRoute(req).allowHeader, ""); 46 EXPECT_EQ(router.findRoute(req).route.rule, nullptr); 47 48 router.newRuleTagged<getParameterTag(url)>(std::string(url)) 49 .methods(boost::beast::http::verb::get)(nullCallback); 50 router.validate(); 51 EXPECT_EQ(router.findRoute(req).allowHeader, "GET"); 52 EXPECT_NE(router.findRoute(req).route.rule, nullptr); 53 54 Request patchReq{{boost::beast::http::verb::patch, url, 11}, ec}; 55 EXPECT_EQ(router.findRoute(patchReq).route.rule, nullptr); 56 57 router.newRuleTagged<getParameterTag(url)>(std::string(url)) 58 .methods(boost::beast::http::verb::patch)(nullCallback); 59 router.validate(); 60 EXPECT_EQ(router.findRoute(req).allowHeader, "GET, PATCH"); 61 EXPECT_NE(router.findRoute(req).route.rule, nullptr); 62 EXPECT_NE(router.findRoute(patchReq).route.rule, nullptr); 63 } 64 65 TEST(Router, 404) 66 { 67 bool notFoundCalled = false; 68 // Callback handler that does nothing 69 auto nullCallback = 70 [¬FoundCalled](const Request&, 71 const std::shared_ptr<bmcweb::AsyncResp>&) { 72 notFoundCalled = true; 73 }; 74 75 Router router; 76 std::error_code ec; 77 78 constexpr std::string_view url = "/foo/bar"; 79 80 Request req{{boost::beast::http::verb::get, url, 11}, ec}; 81 82 router.newRuleTagged<getParameterTag(url)>("/foo/<path>") 83 .notFound()(nullCallback); 84 router.validate(); 85 { 86 std::shared_ptr<bmcweb::AsyncResp> asyncResp = 87 std::make_shared<bmcweb::AsyncResp>(); 88 89 router.handle(req, asyncResp); 90 } 91 EXPECT_TRUE(notFoundCalled); 92 } 93 94 TEST(Router, 405) 95 { 96 // Callback handler that does nothing 97 auto nullCallback = [](const Request&, 98 const std::shared_ptr<bmcweb::AsyncResp>&) {}; 99 bool called = false; 100 auto notAllowedCallback = 101 [&called](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) { 102 called = true; 103 }; 104 105 Router router; 106 std::error_code ec; 107 108 constexpr std::string_view url = "/foo/bar"; 109 110 Request req{{boost::beast::http::verb::patch, url, 11}, ec}; 111 112 router.newRuleTagged<getParameterTag(url)>(std::string(url)) 113 .methods(boost::beast::http::verb::get)(nullCallback); 114 router.newRuleTagged<getParameterTag(url)>("/foo/<path>") 115 .methodNotAllowed()(notAllowedCallback); 116 router.validate(); 117 { 118 std::shared_ptr<bmcweb::AsyncResp> asyncResp = 119 std::make_shared<bmcweb::AsyncResp>(); 120 121 router.handle(req, asyncResp); 122 } 123 EXPECT_TRUE(called); 124 } 125 } // namespace 126 } // namespace crow 127