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