1
2 #include "utility.hpp"
3
4 #include <boost/system/result.hpp>
5 #include <boost/url/parse.hpp>
6 #include <boost/url/url.hpp>
7 #include <boost/url/url_view.hpp>
8 #include <nlohmann/json.hpp>
9
10 #include <algorithm>
11 #include <ctime>
12 #include <functional>
13 #include <string>
14 #include <string_view>
15
16 #include <gtest/gtest.h>
17
18 namespace crow::utility
19 {
20 namespace
21 {
22
23 using ::crow::utility::getParameterTag;
24
TEST(Utility,Base64DecodeAuthString)25 TEST(Utility, Base64DecodeAuthString)
26 {
27 std::string authString("dXNlcm40bWU6cGFzc3cwcmQ=");
28 std::string result;
29 EXPECT_TRUE(base64Decode(authString, result));
30 EXPECT_EQ(result, "usern4me:passw0rd");
31 }
32
TEST(Utility,Base64DecodeNonAscii)33 TEST(Utility, Base64DecodeNonAscii)
34 {
35 std::string junkString("\xff\xee\xdd\xcc\x01\x11\x22\x33");
36 std::string result;
37 EXPECT_FALSE(base64Decode(junkString, result));
38 }
39
TEST(Utility,Base64EncodeString)40 TEST(Utility, Base64EncodeString)
41 {
42 using namespace std::string_literals;
43 std::string encoded;
44
45 encoded = base64encode("");
46 EXPECT_EQ(encoded, "");
47
48 encoded = base64encode("f");
49 EXPECT_EQ(encoded, "Zg==");
50
51 encoded = base64encode("f0");
52 EXPECT_EQ(encoded, "ZjA=");
53
54 encoded = base64encode("f0\0"s);
55 EXPECT_EQ(encoded, "ZjAA");
56
57 encoded = base64encode("f0\0 "s);
58 EXPECT_EQ(encoded, "ZjAAIA==");
59
60 encoded = base64encode("f0\0 B"s);
61 EXPECT_EQ(encoded, "ZjAAIEI=");
62
63 encoded = base64encode("f0\0 Ba"s);
64 EXPECT_EQ(encoded, "ZjAAIEJh");
65
66 encoded = base64encode("f0\0 Bar"s);
67 EXPECT_EQ(encoded, "ZjAAIEJhcg==");
68 }
69
TEST(Utility,Base64Encoder)70 TEST(Utility, Base64Encoder)
71 {
72 using namespace std::string_literals;
73 std::string data = "f0\0 Bar"s;
74 for (size_t chunkSize = 1; chunkSize < 6; chunkSize++)
75 {
76 std::string_view testString(data);
77 std::string out;
78 Base64Encoder encoder;
79 while (!testString.empty())
80 {
81 size_t thisChunk = std::min(testString.size(), chunkSize);
82 encoder.encode(testString.substr(0, thisChunk), out);
83 testString.remove_prefix(thisChunk);
84 }
85
86 encoder.finalize(out);
87 EXPECT_EQ(out, "ZjAAIEJhcg==");
88 }
89 }
90
TEST(Utility,Base64EncodeDecodeString)91 TEST(Utility, Base64EncodeDecodeString)
92 {
93 using namespace std::string_literals;
94 std::string data("Data fr\0m 90 reading a \nFile"s);
95 std::string encoded = base64encode(data);
96 std::string decoded;
97 EXPECT_TRUE(base64Decode(encoded, decoded));
98 EXPECT_EQ(data, decoded);
99 }
100
TEST(Utility,readUrlSegments)101 TEST(Utility, readUrlSegments)
102 {
103 boost::system::result<boost::urls::url_view> parsed =
104 boost::urls::parse_relative_ref("/redfish/v1/Chassis#/Fans/0/Reading");
105
106 EXPECT_TRUE(readUrlSegments(*parsed, "redfish", "v1", "Chassis"));
107
108 EXPECT_FALSE(readUrlSegments(*parsed, "FOOBAR", "v1", "Chassis"));
109
110 EXPECT_FALSE(readUrlSegments(*parsed, "redfish", "v1"));
111
112 EXPECT_FALSE(
113 readUrlSegments(*parsed, "redfish", "v1", "Chassis", "FOOBAR"));
114
115 std::string out1;
116 std::string out2;
117 std::string out3;
118 EXPECT_TRUE(readUrlSegments(*parsed, "redfish", "v1", std::ref(out1)));
119 EXPECT_EQ(out1, "Chassis");
120
121 out1 = out2 = out3 = "";
122 EXPECT_TRUE(readUrlSegments(*parsed, std::ref(out1), std::ref(out2),
123 std::ref(out3)));
124 EXPECT_EQ(out1, "redfish");
125 EXPECT_EQ(out2, "v1");
126 EXPECT_EQ(out3, "Chassis");
127
128 out1 = out2 = out3 = "";
129 EXPECT_TRUE(readUrlSegments(*parsed, "redfish", std::ref(out1), "Chassis"));
130 EXPECT_EQ(out1, "v1");
131
132 out1 = out2 = out3 = "";
133 EXPECT_TRUE(readUrlSegments(*parsed, std::ref(out1), "v1", std::ref(out2)));
134 EXPECT_EQ(out1, "redfish");
135 EXPECT_EQ(out2, "Chassis");
136
137 EXPECT_FALSE(readUrlSegments(*parsed, "too", "short"));
138
139 EXPECT_FALSE(readUrlSegments(*parsed, "too", "long", "too", "long"));
140
141 EXPECT_FALSE(
142 readUrlSegments(*parsed, std::ref(out1), "v2", std::ref(out2)));
143
144 EXPECT_FALSE(readUrlSegments(*parsed, "redfish", std::ref(out1),
145 std::ref(out2), std::ref(out3)));
146
147 parsed = boost::urls::parse_relative_ref("/absolute/url");
148 EXPECT_TRUE(readUrlSegments(*parsed, "absolute", "url"));
149
150 parsed = boost::urls::parse_relative_ref("not/absolute/url");
151 EXPECT_FALSE(readUrlSegments(*parsed, "not", "absolute", "url"));
152
153 parsed = boost::urls::parse_relative_ref("/excellent/path");
154
155 EXPECT_TRUE(readUrlSegments(*parsed, "excellent", "path", OrMorePaths()));
156 EXPECT_TRUE(readUrlSegments(*parsed, "excellent", OrMorePaths()));
157 EXPECT_TRUE(readUrlSegments(*parsed, OrMorePaths()));
158 }
159
TEST(Router,ParameterTagging)160 TEST(Router, ParameterTagging)
161 {
162 EXPECT_EQ(1, getParameterTag("<str>"));
163 EXPECT_EQ(1, getParameterTag("<string>"));
164 EXPECT_EQ(1, getParameterTag("<path>"));
165 EXPECT_EQ(2, getParameterTag("<str>/<str>"));
166 EXPECT_EQ(2, getParameterTag("<string>/<string>"));
167 EXPECT_EQ(2, getParameterTag("<path>/<path>"));
168 }
169
TEST(URL,JsonEncoding)170 TEST(URL, JsonEncoding)
171 {
172 std::string urlString = "/foo";
173 EXPECT_EQ(nlohmann::json(boost::urls::url(urlString)), urlString);
174 EXPECT_EQ(nlohmann::json(boost::urls::url_view(urlString)), urlString);
175 }
176
TEST(AppendUrlFromPieces,PiecesAreAppendedViaDelimiters)177 TEST(AppendUrlFromPieces, PiecesAreAppendedViaDelimiters)
178 {
179 boost::urls::url url("/redfish/v1/foo");
180 EXPECT_EQ(std::string_view(url.data(), url.size()), "/redfish/v1/foo");
181
182 appendUrlPieces(url, "bar");
183 EXPECT_EQ(std::string_view(url.data(), url.size()), "/redfish/v1/foo/bar");
184
185 appendUrlPieces(url, "/", "bad&string");
186 EXPECT_EQ(std::string_view(url.data(), url.size()),
187 "/redfish/v1/foo/bar/%2F/bad&string");
188 }
189
190 } // namespace
191 } // namespace crow::utility
192