xref: /openbmc/bmcweb/test/http/router_test.cpp (revision e9cc1bc9)
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::utility::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         [&notFoundCalled](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