1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef OMIT_JSON
17 #include <algorithm>
18 #include <gtest/gtest.h>
19 #include "db_errno.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "json_object.h"
22
23 using namespace std;
24 using namespace testing::ext;
25 using namespace DistributedDB;
26
27 namespace {
28 const int MAX_DEPTH_FOR_TEST = 10;
29 const int STRING1_DEPTH = 12;
30 const int STRING3_DEPTH = 6;
31
32 // nest depth = 12 and valid.
33 const string JSON_STRING1 = "{\"#14\":[[{\"#11\":{\"#8\":[{\"#5\":[[{\"#2\":[{\"#0\":\"value_\"},\"value_\"],"
34 "\"#3\":\"value_\"},\"value_\"],\"value_\"],\"#6\":\"value_\"},\"value_\"],\"#9\":\"value_\"},"
35 "\"#12\":\"value_\"},\"value_\"],\"value_\"],\"#15\":{\"#18\":{\"#16\":\"value_\"},\"#19\":\"value_\"}}";
36
37 // nest depth = 12 and invalid happens in nest depth = 2.
38 const string JSON_STRING2 = "{\"#17\":[\"just for mistake pls.[{\"#14\":[[{\"#11\":{\"#8\":{\"#5\":[{\"#2\":"
39 "{\"#0\":\"value_\"},\"#3\":\"value_\"},\"value_\"],\"#6\":\"value_\"},\"#9\":\"value_\"},"
40 "\"#12\":\"value_\"},\"value_\"],\"value_\"],\"#15\":\"value_\"},\"value_\"],\"value_\"],"
41 "\"#18\":{\"#21\":{\"#19\":\"value_\"},\"#22\":\"value_\"}}";
42
43 // nest depth = 6 and valid.
44 const string JSON_STRING3 = "{\"#5\":[{\"#2\":[[{\"#0\":\"value_\"},\"value_\"],\"value_\"],\"#3\":\"value_\"},"
45 "\"value_\"],\"#6\":{\"#7\":\"value_\",\"#8\":\"value_\"}}";
46
47 // nest depth = 6 and invalid happens in nest depth = 3.
48 const string JSON_STRING4 = "{\"#6\":[{\"#3\":\"just for mistake pls.[{\"#0\":[\"value_\"],\"#1\":\"value_\"},"
49 "\"value_\"],\"#4\":\"value_\"},\"value_\"],\"#7\":{\"#8\":\"value_\",\"#9\":\"value_\"}}";
50
51 // nest depth = 15 and invalid happens in nest depth = 11.
52 const string JSON_STRING5 = "{\"#35\":[{\"#29\":{\"#23\":{\"#17\":{\"#11\":{\"#8\":[{\"#5\":[{\"#2\":"
53 "\"just for mistake pls.[[[{\"#0\":\"value_\"},\"value_\"],\"value_\"],\"value_\"],\"#3\":\"value_\"},"
54 "\"value_\"],\"#6\":\"value_\"},\"value_\"],\"#9\":\"value_\"},\"#12\":{\"#13\":\"value_\","
55 "\"#14\":\"value_\"}},\"#18\":{\"#19\":\"value_\",\"#20\":\"value_\"}},\"#24\":{\"#25\":\"value_\","
56 "\"#26\":\"value_\"}},\"#30\":{\"#31\":\"value_\",\"#32\":\"value_\"}},\"value_\"],\"#36\":"
57 "{\"#37\":[\"value_\"],\"#38\":\"value_\"}}";
58
59 uint32_t g_oriMaxNestDepth = 0;
60 }
61
62 class DistributedDBJsonPrecheckUnitTest : public testing::Test {
63 public:
64 static void SetUpTestCase(void);
65 static void TearDownTestCase(void);
66 void SetUp();
TearDown()67 void TearDown() {};
68 };
69
SetUpTestCase(void)70 void DistributedDBJsonPrecheckUnitTest::SetUpTestCase(void)
71 {
72 /**
73 * @tc.setup: Specifies a maximum nesting depth of 10.
74 */
75 g_oriMaxNestDepth = JsonObject::SetMaxNestDepth(MAX_DEPTH_FOR_TEST);
76 }
77
TearDownTestCase(void)78 void DistributedDBJsonPrecheckUnitTest::TearDownTestCase(void)
79 {
80 /**
81 * @tc.teardown: Reset nesting depth to origin value.
82 */
83 JsonObject::SetMaxNestDepth(g_oriMaxNestDepth);
84 }
85
SetUp()86 void DistributedDBJsonPrecheckUnitTest::SetUp()
87 {
88 DistributedDBUnitTest::DistributedDBToolsUnitTest::PrintTestCaseInfo();
89 }
90
91 /**
92 * @tc.name: Precheck Valid String 001
93 * @tc.desc: json string is legal
94 * @tc.type: FUNC
95 * @tc.require:
96 * @tc.author: yiguang
97 */
98 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseValidString001, TestSize.Level1)
99 {
100 /**
101 * @tc.steps: step1. Check legal json string with nesting depth of 12.
102 * @tc.expected: step1. return value = 12.
103 */
104 int errCode = E_OK;
105 int stepOne = static_cast<int>(JsonObject::CalculateNestDepth(JSON_STRING1, errCode));
106 EXPECT_TRUE(errCode == E_OK);
107 EXPECT_TRUE(stepOne == STRING1_DEPTH);
108
109 /**
110 * @tc.steps: step2. Parsing of legal json string with nesting depth greater than 10 failed.
111 * @tc.expected: step2. Parsing result failed.
112 */
113 JsonObject tempObj;
114 LOGI("ori json is %s", JSON_STRING1.c_str());
115 int stepTwo = tempObj.Parse(JSON_STRING1);
116 EXPECT_TRUE(stepTwo != E_OK);
117 std::string json = R"([{"field1":"123"}])";
118 std::vector<uint8_t> data(json.begin(), json.end());
119 EXPECT_EQ(tempObj.Parse(data), -E_JSON_PARSE_FAIL);
120 EXPECT_EQ(tempObj.Parse(json), -E_JSON_PARSE_FAIL);
121 }
122
123 /**
124 * @tc.name: Precheck Valid String 002
125 * @tc.desc: json string is legal
126 * @tc.type: FUNC
127 * @tc.require:
128 * @tc.author: yiguang
129 */
130 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseValidString002, TestSize.Level1)
131 {
132 /**
133 * @tc.steps: step1. Check legal json string with nesting depth of 6.
134 * @tc.expected: step1. return value = 6.
135 */
136 int errCode = E_OK;
137 int stepOne = static_cast<int>(JsonObject::CalculateNestDepth(JSON_STRING3, errCode));
138 EXPECT_TRUE(errCode == E_OK);
139 EXPECT_TRUE(stepOne == STRING3_DEPTH);
140
141 /**
142 * @tc.steps: step2. Parsing of legal json string with nesting depth less than 10 success.
143 * @tc.expected: step2. Parsing result success.
144 */
145 JsonObject tempObj;
146 LOGI("ori json is %s", JSON_STRING3.c_str());
147 int stepTwo = tempObj.Parse(JSON_STRING3);
148 EXPECT_TRUE(stepTwo == E_OK);
149 }
150
151 /**
152 * @tc.name: Precheck invalid String 001
153 * @tc.desc: The json string has been detected illegal before exceeding the specified nesting depth.
154 * @tc.type: FUNC
155 * @tc.require:
156 * @tc.author: yiguang
157 */
158 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseInvalidString001, TestSize.Level1)
159 {
160 /**
161 * @tc.steps: step1. Parsing of illegal json string with nesting depth greater than 10 success.
162 * @tc.expected: step1. Parsing result failed.
163 */
164 JsonObject tempObj;
165 LOGI("ori json is %s", JSON_STRING2.c_str());
166 int stepOne = tempObj.Parse(JSON_STRING2);
167 EXPECT_TRUE(stepOne != E_OK);
168 }
169
170 /**
171 * @tc.name: Precheck invalid String 002
172 * @tc.desc: The json string has been detected illegal before exceeding the specified nesting depth.
173 * @tc.type: FUNC
174 * @tc.require:
175 * @tc.author: yiguang
176 */
177 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseInvalidString002, TestSize.Level1)
178 {
179 /**
180 * @tc.steps: step1. Parsing of illegal json string with nesting depth less than 10 success.
181 * @tc.expected: step1. Parsing result failed.
182 */
183 JsonObject tempObj;
184 LOGI("ori json is %s", JSON_STRING4.c_str());
185 int stepOne = tempObj.Parse(JSON_STRING4);
186 EXPECT_TRUE(stepOne != E_OK);
187 }
188
189 /**
190 * @tc.name: Precheck invalid String 003
191 * @tc.desc: The json string has been detected illegal before exceeding the specified nesting depth.
192 * @tc.type: FUNC
193 * @tc.require:
194 * @tc.author: yiguang
195 */
196 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseInvalidString003, TestSize.Level1)
197 {
198 /**
199 * @tc.steps: step1. Detect illegal json string with nesting depth greater than 10.
200 * @tc.expected: step1. return value > 10.
201 */
202 int errCode = E_OK;
203 LOGI("ori json is %s", JSON_STRING5.c_str());
204 int stepOne = static_cast<int>(JsonObject::CalculateNestDepth(JSON_STRING5, errCode));
205 EXPECT_TRUE(errCode == E_OK);
206 EXPECT_TRUE(stepOne > MAX_DEPTH_FOR_TEST);
207
208 /**
209 * @tc.steps: step2. Parsing of illegal json string with nesting depth greater than 10 success.
210 * @tc.expected: step2. Parsing result failed.
211 */
212 JsonObject tempObj;
213 int stepTwo = tempObj.Parse(JSON_STRING5);
214 EXPECT_TRUE(stepTwo != E_OK);
215 }
216
217 /**
218 * @tc.name: ParseDuplicativeString001
219 * @tc.desc: The json string has more than one field with same name.
220 * @tc.type: FUNC
221 * @tc.require:
222 * @tc.author: zqq
223 */
224 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseDuplicativeString001, TestSize.Level0)
225 {
226 /**
227 * @tc.steps: step1. Parse json.
228 * @tc.expected: step1. return ok.
229 */
230 std::string json = R"({"field1":"123", "field2": true, "field1": 123})";
231 LOGI("ori json is %s", json.c_str());
232 JsonObject object;
233 EXPECT_EQ(object.JsonObject::Parse(json), E_OK);
234 /**
235 * @tc.steps: step2. Check field.
236 * @tc.expected: step2. field1 is 123, field2 is True.
237 */
238 FieldValue value;
239 EXPECT_EQ(object.GetFieldValueByFieldPath({"field1"}, value), E_OK);
240 EXPECT_EQ(value.integerValue, 123);
241 EXPECT_EQ(object.GetFieldValueByFieldPath({"field2"}, value), E_OK);
242 EXPECT_TRUE(value.boolValue);
243 }
244
245 /**
246 * @tc.name: ParseString001
247 * @tc.desc: Parse none obj json string.
248 * @tc.type: FUNC
249 * @tc.require:
250 * @tc.author: zqq
251 */
252 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseString001, TestSize.Level0)
253 {
254 std::string nonJson = R"("field1":123)";
255 LOGI("ori json is %s", nonJson.c_str());
256 JsonObject object;
257 std::vector<uint8_t> data(nonJson.begin(), nonJson.end());
258 EXPECT_EQ(object.Parse(data), -E_JSON_PARSE_FAIL);
259 EXPECT_TRUE(object.ToString().empty());
260 }
261
262 /**
263 * @tc.name: ParseString002
264 * @tc.desc: Parse double and long.
265 * @tc.type: FUNC
266 * @tc.require:
267 * @tc.author: zqq
268 */
269 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseString002, TestSize.Level0)
270 {
271 std::string json = R"({"field1":429496729500, "field2":11.1})";
272 LOGI("ori json is %s", json.c_str());
273 JsonObject object;
274 std::vector<uint8_t> data(json.begin(), json.end());
275 EXPECT_EQ(object.Parse(data), E_OK);
276 FieldValue value;
277 EXPECT_EQ(object.GetFieldValueByFieldPath({"field1"}, value), E_OK);
278 EXPECT_EQ(value.longValue, 429496729500);
279 EXPECT_EQ(object.GetFieldValueByFieldPath({"field2"}, value), E_OK);
280 EXPECT_NE(value.doubleValue, 0);
281 }
282
283 /**
284 * @tc.name: ParseString003
285 * @tc.desc: Parse obj.
286 * @tc.type: FUNC
287 * @tc.require:
288 * @tc.author: zqq
289 */
290 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseString003, TestSize.Level0)
291 {
292 std::string json = R"({"field1":42949672950, "field2":{"field3":123}})";
293 LOGI("ori json is %s", json.c_str());
294 JsonObject object;
295 std::vector<uint8_t> data(json.begin(), json.end());
296 EXPECT_EQ(object.Parse(data), E_OK);
297 std::set<FieldPath> outSubPath;
298 std::map<FieldPath, FieldType> outSubPathType;
299 EXPECT_EQ(object.GetSubFieldPath({"field1"}, outSubPath), -E_NOT_SUPPORT);
300 EXPECT_EQ(object.GetSubFieldPathAndType({"field1"}, outSubPathType), -E_NOT_SUPPORT);
301 EXPECT_EQ(object.GetSubFieldPath({"field2"}, outSubPath), E_OK);
302 EXPECT_EQ(object.GetSubFieldPathAndType({"field2"}, outSubPathType), E_OK);
303 std::set<FieldPath> actualPath = {{"field2", "field3"}};
304 EXPECT_EQ(outSubPath, actualPath);
305 FieldPath inPath;
306 EXPECT_EQ(object.GetSubFieldPath(inPath, outSubPath), E_OK);
307 EXPECT_EQ(object.GetSubFieldPathAndType(inPath, outSubPathType), E_OK);
308 }
309
310 /**
311 * @tc.name: ParseString004
312 * @tc.desc: Parse array.
313 * @tc.type: FUNC
314 * @tc.require:
315 * @tc.author: zqq
316 */
317 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseString004, TestSize.Level0)
318 {
319 std::string json = R"({"field1":["123"], "field3":"field3"})";
320 LOGI("ori json is %s", json.c_str());
321 JsonObject object;
322 std::vector<uint8_t> data(json.begin(), json.end());
323 EXPECT_EQ(object.Parse(data), E_OK);
324 size_t size = 0u;
325 EXPECT_EQ(object.GetArraySize({"field3"}, size), -E_NOT_SUPPORT);
326 EXPECT_EQ(object.GetArraySize({"field1"}, size), E_OK);
327 EXPECT_EQ(size, 1u);
328 FieldPath inPath;
329 EXPECT_EQ(object.GetArraySize(inPath, size), -E_NOT_SUPPORT);
330 std::vector<std::vector<std::string>> content;
331 EXPECT_EQ(object.GetArrayContentOfStringOrStringArray({"field1"}, content), E_OK);
332 std::vector<std::vector<std::string>> actual = {{"123"}};
333 EXPECT_EQ(content, actual);
334 EXPECT_EQ(object.GetArrayContentOfStringOrStringArray(inPath, content), -E_NOT_SUPPORT);
335 }
336
337 /**
338 * @tc.name: ParseString005
339 * @tc.desc: Parse array.
340 * @tc.type: FUNC
341 * @tc.require:
342 * @tc.author: zqq
343 */
344 HWTEST_F(DistributedDBJsonPrecheckUnitTest, ParseString005, TestSize.Level0)
345 {
346 std::string json = R"({"field1":["123", null, ["456", 789]], "field3":"field3"})";
347 LOGI("ori json is %s", json.c_str());
348 JsonObject object;
349 EXPECT_EQ(object.Parse(json), E_OK);
350 std::vector<std::vector<std::string>> content;
351 EXPECT_EQ(object.GetArrayContentOfStringOrStringArray({"field1"}, content), -E_NOT_SUPPORT);
352
353 json = R"({"field1":[["456", "789"], []], "field3":"field3"})";
354 object = {};
355 EXPECT_EQ(object.Parse(json), E_OK);
356 EXPECT_EQ(object.GetArrayContentOfStringOrStringArray({"field1"}, content), E_OK);
357 EXPECT_EQ(content.size(), 1u);
358 }
359
360 /**
361 * @tc.name: BuildObj001
362 * @tc.desc: Build json obj.
363 * @tc.type: FUNC
364 * @tc.require:
365 * @tc.author: zqq
366 */
367 HWTEST_F(DistributedDBJsonPrecheckUnitTest, BuildObj001, TestSize.Level0)
368 {
369 LOGI("ori json is empty");
370 JsonObject obj;
371 FieldValue val;
372 val.boolValue = true;
373 EXPECT_EQ(obj.InsertField({"bool_field"}, FieldType::LEAF_FIELD_BOOL, val), E_OK);
374 val.stringValue = "str";
375 EXPECT_EQ(obj.InsertField({"str_field"}, FieldType::LEAF_FIELD_STRING, val), E_OK);
376 val.integerValue = INT32_MAX;
377 EXPECT_EQ(obj.InsertField({"int_field"}, FieldType::LEAF_FIELD_INTEGER, val), E_OK);
378 val.longValue = INT64_MAX;
379 EXPECT_EQ(obj.InsertField({"long_field"}, FieldType::LEAF_FIELD_LONG, val), E_OK);
380 val.doubleValue = 3.1415;
381 EXPECT_EQ(obj.InsertField({"double_field"}, FieldType::LEAF_FIELD_DOUBLE, val), E_OK);
382 EXPECT_EQ(obj.InsertField({"null_field"}, FieldType::LEAF_FIELD_NULL, val), E_OK);
383 EXPECT_EQ(obj.InsertField({"array_field"}, FieldType::LEAF_FIELD_ARRAY, val), -E_INVALID_ARGS);
384 EXPECT_EQ(obj.InsertField({"obj_field"}, FieldType::LEAF_FIELD_OBJECT, val), E_OK);
385 EXPECT_EQ(obj.InsertField({"array_field"}, FieldType::LEAF_FIELD_OBJECT, val), E_OK);
386 EXPECT_EQ(obj.InsertField({"array_field", "array_inner"}, FieldType::LEAF_FIELD_OBJECT, val), E_OK);
387 EXPECT_EQ(obj.InsertField({"array_field", "array_inner", "inner"}, FieldType::LEAF_FIELD_OBJECT, val), E_OK);
388 EXPECT_EQ(obj.DeleteField({"obj_field"}), E_OK);
389 LOGI("json is %s", obj.ToString().c_str());
390 }
391
392 /**
393 * @tc.name: BuildObj002
394 * @tc.desc: Build json obj.
395 * @tc.type: FUNC
396 * @tc.require:
397 * @tc.author: zqq
398 */
399 HWTEST_F(DistributedDBJsonPrecheckUnitTest, BuildObj002, TestSize.Level0)
400 {
401 std::string json = R"({"array_field":[]})";
402 LOGI("ori json is %s", json.c_str());
403 JsonObject obj;
404 EXPECT_EQ(obj.Parse(json), E_OK);
405 FieldValue val;
406 val.stringValue = "str";
407 EXPECT_EQ(obj.InsertField({"array_field1"}, FieldType::LEAF_FIELD_STRING, val, true), E_OK);
408 EXPECT_EQ(obj.InsertField({"array_field2"}, FieldType::LEAF_FIELD_STRING, val), E_OK);
409 EXPECT_EQ(obj.InsertField({"array_field"}, FieldType::LEAF_FIELD_STRING, val, true), E_OK);
410 EXPECT_EQ(obj.InsertField({"array_field"}, FieldType::LEAF_FIELD_STRING, val), E_OK);
411 LOGI("json is %s", obj.ToString().c_str());
412 }
413
414 /**
415 * @tc.name: BuildObj003
416 * @tc.desc: Build json obj by insert invalid obj.
417 * @tc.type: FUNC
418 * @tc.author: zqq
419 */
420 HWTEST_F(DistributedDBJsonPrecheckUnitTest, BuildObj003, TestSize.Level0)
421 {
422 JsonObject invalidOriObj;
423 JsonObject invalidInsertObj;
424 EXPECT_EQ(invalidOriObj.InsertField({}, invalidInsertObj), -E_INVALID_ARGS);
425 JsonObject validInsertObj;
426 std::string json = R"({"field1":"field1Val"})";
427 validInsertObj.Parse(json);
428 EXPECT_EQ(invalidOriObj.InsertField({}, validInsertObj), -E_INVALID_ARGS);
429 FieldPath invalidPath;
430 invalidPath.resize(101); // 101 is invalid depth
431 EXPECT_EQ(invalidOriObj.InsertField(invalidPath, invalidInsertObj), -E_INVALID_ARGS);
432 EXPECT_EQ(invalidOriObj.InsertField(invalidPath, validInsertObj), -E_INVALID_ARGS);
433 }
434
435 /**
436 * @tc.name: BuildObj004
437 * @tc.desc: Build json valid obj by insert valid obj.
438 * @tc.type: FUNC
439 * @tc.author: zqq
440 */
441 HWTEST_F(DistributedDBJsonPrecheckUnitTest, BuildObj004, TestSize.Level0)
442 {
443 JsonObject validOriObj;
444 std::string json = R"({"field1":"field1Val", "array":[]})";
445 validOriObj.Parse(json);
446 JsonObject insertVal;
447 insertVal.Parse(json);
448 EXPECT_EQ(validOriObj.InsertField({"field2"}, insertVal), E_OK);
449 JsonObject inValidOriObj;
450 EXPECT_EQ(inValidOriObj.InsertField({"field2"}, insertVal), E_OK);
451 EXPECT_EQ(validOriObj.InsertField({"array"}, insertVal), E_OK);
452 EXPECT_EQ(validOriObj.InsertField({"array"}, insertVal, false), E_OK);
453 EXPECT_EQ(validOriObj.InsertField({"field3"}, insertVal, false), E_OK);
454 EXPECT_EQ(validOriObj.InsertField({"field1"}, insertVal), -E_JSON_INSERT_PATH_EXIST);
455 }
456 #endif