blob: 54308724b24ab2d50bbe04d206f3ee25bc096be7 [file] [log] [blame]
Ed Tanous478b7ad2024-07-15 19:11:54 -07001#include "async_resp.hpp"
Ed Tanous88a03c52022-03-14 10:16:07 -07002#include "http_request.hpp"
3#include "routing.hpp"
Nan Zhoudff2f9b2022-06-26 23:50:39 +00004#include "utility.hpp"
Ed Tanous88a03c52022-03-14 10:16:07 -07005
Nan Zhoudff2f9b2022-06-26 23:50:39 +00006#include <boost/beast/http/verb.hpp>
7
8#include <memory>
9#include <string>
10#include <string_view>
11#include <system_error>
12
Ed Tanous478b7ad2024-07-15 19:11:54 -070013#include <gtest/gtest.h>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000014
Nan Zhoud5c80ad2022-07-11 01:16:31 +000015// IWYU pragma: no_forward_declare bmcweb::AsyncResp
Ed Tanous88a03c52022-03-14 10:16:07 -070016
Nan Zhouef740262022-06-26 23:55:13 +000017namespace crow
18{
19namespace
20{
21
Ed Tanous47488a92023-06-26 18:19:33 -070022using ::crow::utility::getParameterTag;
Nan Zhouef740262022-06-26 23:55:13 +000023
Ed Tanous88a03c52022-03-14 10:16:07 -070024TEST(Router, AllowHeader)
25{
26 // Callback handler that does nothing
Patrick Williamsbd79bce2024-08-16 15:22:20 -040027 auto nullCallback =
28 [](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {};
Ed Tanous88a03c52022-03-14 10:16:07 -070029
Nan Zhouef740262022-06-26 23:55:13 +000030 Router router;
Ed Tanous88a03c52022-03-14 10:16:07 -070031 std::error_code ec;
32
Ed Tanous26ccae32023-02-16 10:28:44 -080033 constexpr std::string_view url = "/foo";
Ed Tanous88a03c52022-03-14 10:16:07 -070034
Nan Zhouef740262022-06-26 23:55:13 +000035 Request req{{boost::beast::http::verb::get, url, 11}, ec};
Ed Tanous88a03c52022-03-14 10:16:07 -070036
37 // No route should return no methods.
38 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070039 EXPECT_EQ(router.findRoute(req).allowHeader, "");
40 EXPECT_EQ(router.findRoute(req).route.rule, nullptr);
Ed Tanous88a03c52022-03-14 10:16:07 -070041
Nan Zhouef740262022-06-26 23:55:13 +000042 router.newRuleTagged<getParameterTag(url)>(std::string(url))
Ed Tanous88a03c52022-03-14 10:16:07 -070043 .methods(boost::beast::http::verb::get)(nullCallback);
44 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070045 EXPECT_EQ(router.findRoute(req).allowHeader, "GET");
46 EXPECT_NE(router.findRoute(req).route.rule, nullptr);
47
48 Request patchReq{{boost::beast::http::verb::patch, url, 11}, ec};
49 EXPECT_EQ(router.findRoute(patchReq).route.rule, nullptr);
Ed Tanous88a03c52022-03-14 10:16:07 -070050
Nan Zhouef740262022-06-26 23:55:13 +000051 router.newRuleTagged<getParameterTag(url)>(std::string(url))
Ed Tanous88a03c52022-03-14 10:16:07 -070052 .methods(boost::beast::http::verb::patch)(nullCallback);
53 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070054 EXPECT_EQ(router.findRoute(req).allowHeader, "GET, PATCH");
55 EXPECT_NE(router.findRoute(req).route.rule, nullptr);
56 EXPECT_NE(router.findRoute(patchReq).route.rule, nullptr);
57}
58
Ed Tanousd9e89df2024-03-27 14:08:59 -070059TEST(Router, OverlapingRoutes)
60{
61 // Callback handler that does nothing
Patrick Williamsbd79bce2024-08-16 15:22:20 -040062 auto fooCallback =
63 [](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
64 EXPECT_FALSE(true);
65 };
Ed Tanousd9e89df2024-03-27 14:08:59 -070066 bool barCalled = false;
67 auto foobarCallback =
68 [&barCalled](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&,
69 const std::string& bar) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040070 barCalled = true;
71 EXPECT_EQ(bar, "bar");
72 };
Ed Tanousd9e89df2024-03-27 14:08:59 -070073
74 Router router;
75 std::error_code ec;
76
77 router.newRuleTagged<getParameterTag("/foo/<str>")>("/foo/<str>")(
78 foobarCallback);
79 router.newRuleTagged<getParameterTag("/foo")>("/foo")(fooCallback);
80 router.validate();
81 {
82 constexpr std::string_view url = "/foo/bar";
83
Jonathan Doman102a4cd2024-04-15 16:56:23 -070084 auto req = std::make_shared<Request>(
85 Request::Body{boost::beast::http::verb::get, url, 11}, ec);
Ed Tanousd9e89df2024-03-27 14:08:59 -070086
87 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
88 std::make_shared<bmcweb::AsyncResp>();
89
90 router.handle(req, asyncResp);
91 }
92 EXPECT_TRUE(barCalled);
93}
94
Ed Tanous44e45182022-07-26 16:47:23 -070095TEST(Router, 404)
96{
97 bool notFoundCalled = false;
98 // Callback handler that does nothing
99 auto nullCallback =
100 [&notFoundCalled](const Request&,
101 const std::shared_ptr<bmcweb::AsyncResp>&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400102 notFoundCalled = true;
103 };
Ed Tanous44e45182022-07-26 16:47:23 -0700104
105 Router router;
106 std::error_code ec;
107
Ed Tanous26ccae32023-02-16 10:28:44 -0800108 constexpr std::string_view url = "/foo/bar";
Ed Tanous44e45182022-07-26 16:47:23 -0700109
Jonathan Doman102a4cd2024-04-15 16:56:23 -0700110 auto req = std::make_shared<Request>(
111 Request::Body{boost::beast::http::verb::get, url, 11}, ec);
Ed Tanous44e45182022-07-26 16:47:23 -0700112
113 router.newRuleTagged<getParameterTag(url)>("/foo/<path>")
114 .notFound()(nullCallback);
115 router.validate();
116 {
117 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
118 std::make_shared<bmcweb::AsyncResp>();
119
120 router.handle(req, asyncResp);
121 }
122 EXPECT_TRUE(notFoundCalled);
Nan Zhouef740262022-06-26 23:55:13 +0000123}
Ed Tanous759cf102022-07-31 16:36:52 -0700124
125TEST(Router, 405)
126{
127 // Callback handler that does nothing
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400128 auto nullCallback =
129 [](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {};
Ed Tanous759cf102022-07-31 16:36:52 -0700130 bool called = false;
131 auto notAllowedCallback =
132 [&called](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400133 called = true;
134 };
Ed Tanous759cf102022-07-31 16:36:52 -0700135
136 Router router;
137 std::error_code ec;
138
Ed Tanous26ccae32023-02-16 10:28:44 -0800139 constexpr std::string_view url = "/foo/bar";
Ed Tanous759cf102022-07-31 16:36:52 -0700140
Jonathan Doman102a4cd2024-04-15 16:56:23 -0700141 auto req = std::make_shared<Request>(
142 Request::Body{boost::beast::http::verb::patch, url, 11}, ec);
Ed Tanous759cf102022-07-31 16:36:52 -0700143
144 router.newRuleTagged<getParameterTag(url)>(std::string(url))
145 .methods(boost::beast::http::verb::get)(nullCallback);
146 router.newRuleTagged<getParameterTag(url)>("/foo/<path>")
147 .methodNotAllowed()(notAllowedCallback);
148 router.validate();
149 {
150 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
151 std::make_shared<bmcweb::AsyncResp>();
152
153 router.handle(req, asyncResp);
154 }
155 EXPECT_TRUE(called);
156}
Nan Zhouef740262022-06-26 23:55:13 +0000157} // namespace
Ed Tanous44e45182022-07-26 16:47:23 -0700158} // namespace crow