1 #include "redfish_aggregator.hpp"
2 
3 #include <nlohmann/json.hpp>
4 
5 #include <gtest/gtest.h> // IWYU pragma: keep
6 
7 namespace redfish
8 {
9 namespace
10 {
11 
12 TEST(IsPropertyUri, SupportedPropertyReturnsTrue)
13 {
14     EXPECT_TRUE(isPropertyUri("@Redfish.ActionInfo"));
15     EXPECT_TRUE(isPropertyUri("@odata.id"));
16     EXPECT_TRUE(isPropertyUri("Image"));
17     EXPECT_TRUE(isPropertyUri("MetricProperty"));
18     EXPECT_TRUE(isPropertyUri("TaskMonitor"));
19     EXPECT_TRUE(isPropertyUri("target"));
20 }
21 
22 TEST(IsPropertyUri, CaseInsensitiveURIReturnsTrue)
23 {
24     EXPECT_TRUE(isPropertyUri("AdditionalDataURI"));
25     EXPECT_TRUE(isPropertyUri("DataSourceUri"));
26     EXPECT_TRUE(isPropertyUri("uri"));
27     EXPECT_TRUE(isPropertyUri("URI"));
28 }
29 
30 TEST(IsPropertyUri, SpeificallyIgnoredPropertyReturnsFalse)
31 {
32     EXPECT_FALSE(isPropertyUri("@odata.context"));
33     EXPECT_FALSE(isPropertyUri("Destination"));
34     EXPECT_FALSE(isPropertyUri("HostName"));
35     EXPECT_FALSE(isPropertyUri("OriginOfCondition"));
36 }
37 
38 TEST(IsPropertyUri, UnsupportedPropertyReturnsFalse)
39 {
40     EXPECT_FALSE(isPropertyUri("Name"));
41     EXPECT_FALSE(isPropertyUri("Health"));
42     EXPECT_FALSE(isPropertyUri("Id"));
43 }
44 
45 TEST(addPrefixToItem, ValidURIs)
46 {
47     nlohmann::json jsonRequest;
48     constexpr std::array validRoots{"Cables",
49                                     "Chassis",
50                                     "Fabrics",
51                                     "PowerEquipment/FloorPDUs",
52                                     "Systems",
53                                     "TaskService/Tasks",
54                                     "TelemetryService/LogService/Entries",
55                                     "UpdateService/SoftwareInventory"};
56 
57     // We're only testing prefix fixing so it's alright that some of the
58     // resulting URIs will not actually be possible as defined by the schema
59     constexpr std::array validIDs{"1",
60                                   "1/",
61                                   "Test",
62                                   "Test/",
63                                   "Extra_Test",
64                                   "Extra_Test/",
65                                   "Extra_Test/Sensors",
66                                   "Extra_Test/Sensors/",
67                                   "Extra_Test/Sensors/power_sensor",
68                                   "Extra_Test/Sensors/power_sensor/"};
69 
70     // Construct URIs which should have prefix fixing applied
71     for (const auto& root : validRoots)
72     {
73         for (const auto& id : validIDs)
74         {
75             std::string initial("/redfish/v1/" + std::string(root) + "/");
76             std::string correct(initial + "asdfjkl_" + std::string(id));
77             initial += id;
78             jsonRequest["@odata.id"] = initial;
79             addPrefixToItem(jsonRequest["@odata.id"], "asdfjkl");
80             EXPECT_EQ(jsonRequest["@odata.id"], correct);
81         }
82     }
83 }
84 
85 TEST(addPrefixToItem, UnsupportedURIs)
86 {
87     nlohmann::json jsonRequest;
88     constexpr std::array invalidRoots{
89         "FakeCollection",           "JsonSchemas",
90         "PowerEquipment",           "TaskService",
91         "TelemetryService/Entries", "UpdateService"};
92 
93     constexpr std::array validIDs{"1",
94                                   "1/",
95                                   "Test",
96                                   "Test/",
97                                   "Extra_Test",
98                                   "Extra_Test/",
99                                   "Extra_Test/Sensors",
100                                   "Extra_Test/Sensors/",
101                                   "Extra_Test/Sensors/power_sensor",
102                                   "Extra_Test/Sensors/power_sensor/"};
103 
104     // Construct URIs which should NOT have prefix fixing applied
105     for (const auto& root : invalidRoots)
106     {
107         for (const auto& id : validIDs)
108         {
109             std::string initial("/redfish/v1/" + std::string(root) + "/");
110             std::string correct(initial + "asdfjkl_" + std::string(id));
111             initial += id;
112             jsonRequest["@odata.id"] = initial;
113             addPrefixToItem(jsonRequest["@odata.id"], "asdfjkl");
114             EXPECT_EQ(jsonRequest["@odata.id"], initial);
115         }
116     }
117 }
118 
119 TEST(addPrefixToItem, TopLevelCollections)
120 {
121     nlohmann::json jsonRequest;
122     constexpr std::array validRoots{"Cables",
123                                     "Chassis/",
124                                     "Fabrics",
125                                     "JsonSchemas",
126                                     "PowerEquipment/FloorPDUs",
127                                     "Systems",
128                                     "TaskService/Tasks",
129                                     "TelemetryService/LogService/Entries",
130                                     "TelemetryService/LogService/Entries/",
131                                     "UpdateService/SoftwareInventory/"};
132 
133     // Construct URIs for top level collections.  Prefixes should NOT be
134     // applied to any of the URIs
135     for (const auto& root : validRoots)
136     {
137         std::string initial("/redfish/v1/" + std::string(root));
138         jsonRequest["@odata.id"] = initial;
139         addPrefixToItem(jsonRequest["@odata.id"], "perfix");
140         EXPECT_EQ(jsonRequest["@odata.id"], initial);
141     }
142 }
143 
144 TEST(addPrefixes, ParseJsonObject)
145 {
146     nlohmann::json parameter;
147     parameter["Name"] = "/redfish/v1/Chassis/fakeName";
148     parameter["@odata.id"] = "/redfish/v1/Chassis/fakeChassis";
149 
150     addPrefixes(parameter, "abcd");
151     EXPECT_EQ(parameter["Name"], "/redfish/v1/Chassis/fakeName");
152     EXPECT_EQ(parameter["@odata.id"], "/redfish/v1/Chassis/abcd_fakeChassis");
153 }
154 
155 TEST(addPrefixes, ParseJsonArray)
156 {
157     nlohmann::json array = nlohmann::json::parse(R"(
158     {
159       "Conditions": [
160         {
161           "Message": "This is a test",
162           "@odata.id": "/redfish/v1/Chassis/TestChassis"
163         },
164         {
165           "Message": "This is also a test",
166           "@odata.id": "/redfish/v1/Chassis/TestChassis2"
167         }
168       ]
169     }
170     )",
171                                                  nullptr, false);
172 
173     addPrefixes(array, "5B42");
174     EXPECT_EQ(array["Conditions"][0]["@odata.id"],
175               "/redfish/v1/Chassis/5B42_TestChassis");
176     EXPECT_EQ(array["Conditions"][1]["@odata.id"],
177               "/redfish/v1/Chassis/5B42_TestChassis2");
178 }
179 
180 TEST(addPrefixes, ParseJsonObjectNestedArray)
181 {
182     nlohmann::json objWithArray = nlohmann::json::parse(R"(
183     {
184       "Status": {
185         "Conditions": [
186           {
187             "Message": "This is a test",
188             "MessageId": "Test",
189             "OriginOfCondition": {
190               "@odata.id": "/redfish/v1/Chassis/TestChassis"
191             },
192             "Severity": "Critical"
193           }
194         ],
195         "Health": "Critical",
196         "State": "Enabled"
197       }
198     }
199     )",
200                                                         nullptr, false);
201 
202     addPrefixes(objWithArray, "5B42");
203     nlohmann::json& array = objWithArray["Status"]["Conditions"];
204     EXPECT_EQ(array[0]["OriginOfCondition"]["@odata.id"],
205               "/redfish/v1/Chassis/5B42_TestChassis");
206 }
207 
208 // Attempts to perform prefix fixing on a response with response code "result".
209 // Fixing should always occur
210 void assertProcessResponse(unsigned result)
211 {
212     nlohmann::json jsonResp;
213     jsonResp["@odata.id"] = "/redfish/v1/Chassis/TestChassis";
214     jsonResp["Name"] = "Test";
215 
216     crow::Response resp;
217     resp.body() =
218         jsonResp.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
219     resp.addHeader("Content-Type", "application/json");
220     resp.result(result);
221 
222     auto asyncResp = std::make_shared<bmcweb::AsyncResp>();
223     RedfishAggregator::processResponse("prefix", asyncResp, resp);
224 
225     EXPECT_EQ(asyncResp->res.jsonValue["Name"], "Test");
226     EXPECT_EQ(asyncResp->res.jsonValue["@odata.id"],
227               "/redfish/v1/Chassis/prefix_TestChassis");
228     EXPECT_EQ(asyncResp->res.resultInt(), result);
229 }
230 
231 TEST(processResponse, validResponseCodes)
232 {
233     assertProcessResponse(100);
234     assertProcessResponse(200);
235     assertProcessResponse(204);
236     assertProcessResponse(300);
237     assertProcessResponse(404);
238     assertProcessResponse(405);
239     assertProcessResponse(500);
240     assertProcessResponse(507);
241 }
242 
243 } // namespace
244 } // namespace redfish
245