blob: 23725416af66451458f13cfda112e14b914e05b2 [file] [log] [blame]
Nan Zhoud5c80ad2022-07-11 01:16:31 +00001#include "async_resp.hpp" // IWYU pragma: keep
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 Zhoud5c80ad2022-07-11 01:16:31 +00006#include <boost/beast/http/message.hpp> // IWYU pragma: keep
Nan Zhoudff2f9b2022-06-26 23:50:39 +00007#include <boost/beast/http/verb.hpp>
8
9#include <memory>
10#include <string>
11#include <string_view>
12#include <system_error>
13
Nan Zhoud5c80ad2022-07-11 01:16:31 +000014#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
Ed Tanous88a03c52022-03-14 10:16:07 -070022
Nan Zhouef740262022-06-26 23:55:13 +000023namespace crow
24{
25namespace
26{
27
Ed Tanous47488a92023-06-26 18:19:33 -070028using ::crow::utility::getParameterTag;
Nan Zhouef740262022-06-26 23:55:13 +000029
Ed Tanous88a03c52022-03-14 10:16:07 -070030TEST(Router, AllowHeader)
31{
32 // Callback handler that does nothing
Nan Zhouef740262022-06-26 23:55:13 +000033 auto nullCallback = [](const Request&,
Ed Tanous88a03c52022-03-14 10:16:07 -070034 const std::shared_ptr<bmcweb::AsyncResp>&) {};
35
Nan Zhouef740262022-06-26 23:55:13 +000036 Router router;
Ed Tanous88a03c52022-03-14 10:16:07 -070037 std::error_code ec;
38
Ed Tanous26ccae32023-02-16 10:28:44 -080039 constexpr std::string_view url = "/foo";
Ed Tanous88a03c52022-03-14 10:16:07 -070040
Nan Zhouef740262022-06-26 23:55:13 +000041 Request req{{boost::beast::http::verb::get, url, 11}, ec};
Ed Tanous88a03c52022-03-14 10:16:07 -070042
43 // No route should return no methods.
44 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070045 EXPECT_EQ(router.findRoute(req).allowHeader, "");
46 EXPECT_EQ(router.findRoute(req).route.rule, nullptr);
Ed Tanous88a03c52022-03-14 10:16:07 -070047
Nan Zhouef740262022-06-26 23:55:13 +000048 router.newRuleTagged<getParameterTag(url)>(std::string(url))
Ed Tanous88a03c52022-03-14 10:16:07 -070049 .methods(boost::beast::http::verb::get)(nullCallback);
50 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070051 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);
Ed Tanous88a03c52022-03-14 10:16:07 -070056
Nan Zhouef740262022-06-26 23:55:13 +000057 router.newRuleTagged<getParameterTag(url)>(std::string(url))
Ed Tanous88a03c52022-03-14 10:16:07 -070058 .methods(boost::beast::http::verb::patch)(nullCallback);
59 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070060 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
Ed Tanousd9e89df2024-03-27 14:08:59 -070065TEST(Router, OverlapingRoutes)
66{
67 // Callback handler that does nothing
68 auto fooCallback = [](const Request&,
69 const std::shared_ptr<bmcweb::AsyncResp>&) {
70 EXPECT_FALSE(true);
71 };
72 bool barCalled = false;
73 auto foobarCallback =
74 [&barCalled](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&,
75 const std::string& bar) {
76 barCalled = true;
77 EXPECT_EQ(bar, "bar");
78 };
79
80 Router router;
81 std::error_code ec;
82
83 router.newRuleTagged<getParameterTag("/foo/<str>")>("/foo/<str>")(
84 foobarCallback);
85 router.newRuleTagged<getParameterTag("/foo")>("/foo")(fooCallback);
86 router.validate();
87 {
88 constexpr std::string_view url = "/foo/bar";
89
Jonathan Doman102a4cd2024-04-15 16:56:23 -070090 auto req = std::make_shared<Request>(
91 Request::Body{boost::beast::http::verb::get, url, 11}, ec);
Ed Tanousd9e89df2024-03-27 14:08:59 -070092
93 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
94 std::make_shared<bmcweb::AsyncResp>();
95
96 router.handle(req, asyncResp);
97 }
98 EXPECT_TRUE(barCalled);
99}
100
Ed Tanous44e45182022-07-26 16:47:23 -0700101TEST(Router, 404)
102{
103 bool notFoundCalled = false;
104 // Callback handler that does nothing
105 auto nullCallback =
106 [&notFoundCalled](const Request&,
107 const std::shared_ptr<bmcweb::AsyncResp>&) {
108 notFoundCalled = true;
109 };
110
111 Router router;
112 std::error_code ec;
113
Ed Tanous26ccae32023-02-16 10:28:44 -0800114 constexpr std::string_view url = "/foo/bar";
Ed Tanous44e45182022-07-26 16:47:23 -0700115
Jonathan Doman102a4cd2024-04-15 16:56:23 -0700116 auto req = std::make_shared<Request>(
117 Request::Body{boost::beast::http::verb::get, url, 11}, ec);
Ed Tanous44e45182022-07-26 16:47:23 -0700118
119 router.newRuleTagged<getParameterTag(url)>("/foo/<path>")
120 .notFound()(nullCallback);
121 router.validate();
122 {
123 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
124 std::make_shared<bmcweb::AsyncResp>();
125
126 router.handle(req, asyncResp);
127 }
128 EXPECT_TRUE(notFoundCalled);
Nan Zhouef740262022-06-26 23:55:13 +0000129}
Ed Tanous759cf102022-07-31 16:36:52 -0700130
131TEST(Router, 405)
132{
133 // Callback handler that does nothing
134 auto nullCallback = [](const Request&,
135 const std::shared_ptr<bmcweb::AsyncResp>&) {};
136 bool called = false;
137 auto notAllowedCallback =
138 [&called](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
139 called = true;
140 };
141
142 Router router;
143 std::error_code ec;
144
Ed Tanous26ccae32023-02-16 10:28:44 -0800145 constexpr std::string_view url = "/foo/bar";
Ed Tanous759cf102022-07-31 16:36:52 -0700146
Jonathan Doman102a4cd2024-04-15 16:56:23 -0700147 auto req = std::make_shared<Request>(
148 Request::Body{boost::beast::http::verb::patch, url, 11}, ec);
Ed Tanous759cf102022-07-31 16:36:52 -0700149
150 router.newRuleTagged<getParameterTag(url)>(std::string(url))
151 .methods(boost::beast::http::verb::get)(nullCallback);
152 router.newRuleTagged<getParameterTag(url)>("/foo/<path>")
153 .methodNotAllowed()(notAllowedCallback);
154 router.validate();
155 {
156 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
157 std::make_shared<bmcweb::AsyncResp>();
158
159 router.handle(req, asyncResp);
160 }
161 EXPECT_TRUE(called);
162}
Nan Zhouef740262022-06-26 23:55:13 +0000163} // namespace
Ed Tanous44e45182022-07-26 16:47:23 -0700164} // namespace crow