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