• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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