blob: 63b7c11409f201fe537d575b1e4896166e153c1e [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Ed Tanous478b7ad2024-07-15 19:11:54 -07003#include "async_resp.hpp"
Ed Tanous88a03c52022-03-14 10:16:07 -07004#include "http_request.hpp"
5#include "routing.hpp"
Nan Zhoudff2f9b2022-06-26 23:50:39 +00006#include "utility.hpp"
Ed Tanous88a03c52022-03-14 10:16:07 -07007
Nan Zhoudff2f9b2022-06-26 23:50:39 +00008#include <boost/beast/http/verb.hpp>
9
10#include <memory>
11#include <string>
12#include <string_view>
13#include <system_error>
14
Ed Tanous478b7ad2024-07-15 19:11:54 -070015#include <gtest/gtest.h>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000016
Nan Zhoud5c80ad2022-07-11 01:16:31 +000017// IWYU pragma: no_forward_declare bmcweb::AsyncResp
Ed Tanous88a03c52022-03-14 10:16:07 -070018
Nan Zhouef740262022-06-26 23:55:13 +000019namespace crow
20{
21namespace
22{
23
Ed Tanous47488a92023-06-26 18:19:33 -070024using ::crow::utility::getParameterTag;
Nan Zhouef740262022-06-26 23:55:13 +000025
Ed Tanous88a03c52022-03-14 10:16:07 -070026TEST(Router, AllowHeader)
27{
28 // Callback handler that does nothing
Patrick Williamsbd79bce2024-08-16 15:22:20 -040029 auto nullCallback =
30 [](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {};
Ed Tanous88a03c52022-03-14 10:16:07 -070031
Nan Zhouef740262022-06-26 23:55:13 +000032 Router router;
Ed Tanous88a03c52022-03-14 10:16:07 -070033 std::error_code ec;
34
Ed Tanous26ccae32023-02-16 10:28:44 -080035 constexpr std::string_view url = "/foo";
Ed Tanous88a03c52022-03-14 10:16:07 -070036
Nan Zhouef740262022-06-26 23:55:13 +000037 Request req{{boost::beast::http::verb::get, url, 11}, ec};
Ed Tanous88a03c52022-03-14 10:16:07 -070038
39 // No route should return no methods.
40 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070041 EXPECT_EQ(router.findRoute(req).allowHeader, "");
42 EXPECT_EQ(router.findRoute(req).route.rule, nullptr);
Ed Tanous88a03c52022-03-14 10:16:07 -070043
Nan Zhouef740262022-06-26 23:55:13 +000044 router.newRuleTagged<getParameterTag(url)>(std::string(url))
Ed Tanous88a03c52022-03-14 10:16:07 -070045 .methods(boost::beast::http::verb::get)(nullCallback);
46 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070047 EXPECT_EQ(router.findRoute(req).allowHeader, "GET");
48 EXPECT_NE(router.findRoute(req).route.rule, nullptr);
49
50 Request patchReq{{boost::beast::http::verb::patch, url, 11}, ec};
51 EXPECT_EQ(router.findRoute(patchReq).route.rule, nullptr);
Ed Tanous88a03c52022-03-14 10:16:07 -070052
Nan Zhouef740262022-06-26 23:55:13 +000053 router.newRuleTagged<getParameterTag(url)>(std::string(url))
Ed Tanous88a03c52022-03-14 10:16:07 -070054 .methods(boost::beast::http::verb::patch)(nullCallback);
55 router.validate();
Ed Tanous44e45182022-07-26 16:47:23 -070056 EXPECT_EQ(router.findRoute(req).allowHeader, "GET, PATCH");
57 EXPECT_NE(router.findRoute(req).route.rule, nullptr);
58 EXPECT_NE(router.findRoute(patchReq).route.rule, nullptr);
59}
60
Ed Tanousd9e89df2024-03-27 14:08:59 -070061TEST(Router, OverlapingRoutes)
62{
63 // Callback handler that does nothing
Patrick Williamsbd79bce2024-08-16 15:22:20 -040064 auto fooCallback =
65 [](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
66 EXPECT_FALSE(true);
67 };
Ed Tanousd9e89df2024-03-27 14:08:59 -070068 bool barCalled = false;
69 auto foobarCallback =
70 [&barCalled](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&,
71 const std::string& bar) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040072 barCalled = true;
73 EXPECT_EQ(bar, "bar");
74 };
Ed Tanousd9e89df2024-03-27 14:08:59 -070075
76 Router router;
77 std::error_code ec;
78
79 router.newRuleTagged<getParameterTag("/foo/<str>")>("/foo/<str>")(
80 foobarCallback);
81 router.newRuleTagged<getParameterTag("/foo")>("/foo")(fooCallback);
82 router.validate();
83 {
84 constexpr std::string_view url = "/foo/bar";
85
Jonathan Doman102a4cd2024-04-15 16:56:23 -070086 auto req = std::make_shared<Request>(
87 Request::Body{boost::beast::http::verb::get, url, 11}, ec);
Ed Tanousd9e89df2024-03-27 14:08:59 -070088
89 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
90 std::make_shared<bmcweb::AsyncResp>();
91
92 router.handle(req, asyncResp);
93 }
94 EXPECT_TRUE(barCalled);
95}
96
Ed Tanous44e45182022-07-26 16:47:23 -070097TEST(Router, 404)
98{
99 bool notFoundCalled = false;
100 // Callback handler that does nothing
101 auto nullCallback =
102 [&notFoundCalled](const Request&,
103 const std::shared_ptr<bmcweb::AsyncResp>&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400104 notFoundCalled = true;
105 };
Ed Tanous44e45182022-07-26 16:47:23 -0700106
107 Router router;
108 std::error_code ec;
109
Ed Tanous26ccae32023-02-16 10:28:44 -0800110 constexpr std::string_view url = "/foo/bar";
Ed Tanous44e45182022-07-26 16:47:23 -0700111
Jonathan Doman102a4cd2024-04-15 16:56:23 -0700112 auto req = std::make_shared<Request>(
113 Request::Body{boost::beast::http::verb::get, url, 11}, ec);
Ed Tanous44e45182022-07-26 16:47:23 -0700114
115 router.newRuleTagged<getParameterTag(url)>("/foo/<path>")
116 .notFound()(nullCallback);
117 router.validate();
118 {
119 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
120 std::make_shared<bmcweb::AsyncResp>();
121
122 router.handle(req, asyncResp);
123 }
124 EXPECT_TRUE(notFoundCalled);
Nan Zhouef740262022-06-26 23:55:13 +0000125}
Ed Tanous759cf102022-07-31 16:36:52 -0700126
127TEST(Router, 405)
128{
129 // Callback handler that does nothing
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400130 auto nullCallback =
131 [](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {};
Ed Tanous759cf102022-07-31 16:36:52 -0700132 bool called = false;
133 auto notAllowedCallback =
134 [&called](const Request&, const std::shared_ptr<bmcweb::AsyncResp>&) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400135 called = true;
136 };
Ed Tanous759cf102022-07-31 16:36:52 -0700137
138 Router router;
139 std::error_code ec;
140
Ed Tanous26ccae32023-02-16 10:28:44 -0800141 constexpr std::string_view url = "/foo/bar";
Ed Tanous759cf102022-07-31 16:36:52 -0700142
Jonathan Doman102a4cd2024-04-15 16:56:23 -0700143 auto req = std::make_shared<Request>(
144 Request::Body{boost::beast::http::verb::patch, url, 11}, ec);
Ed Tanous759cf102022-07-31 16:36:52 -0700145
146 router.newRuleTagged<getParameterTag(url)>(std::string(url))
147 .methods(boost::beast::http::verb::get)(nullCallback);
148 router.newRuleTagged<getParameterTag(url)>("/foo/<path>")
149 .methodNotAllowed()(notAllowedCallback);
150 router.validate();
151 {
152 std::shared_ptr<bmcweb::AsyncResp> asyncResp =
153 std::make_shared<bmcweb::AsyncResp>();
154
155 router.handle(req, asyncResp);
156 }
157 EXPECT_TRUE(called);
158}
Nan Zhouef740262022-06-26 23:55:13 +0000159} // namespace
Ed Tanous44e45182022-07-26 16:47:23 -0700160} // namespace crow