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 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 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 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 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 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 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 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 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 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