1 /*
2 * Copyright (c) 2025 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 #include "gtest/gtest.h"
17 #include "gmock/gmock.h"
18
19 #include "system_notifier.h"
20 #include "control_cmd_parser.h"
21 #include "dfs_error.h"
22 #include "device_manager.h"
23 #include "utils_log.h"
24 #include "parameter.h"
25 #include <nlohmann/json.hpp>
26
27 namespace {
28 int32_t g_publishNotification = 0;
29 int32_t g_cancelNotification = 0;
30 } // namespace
31
32 namespace OHOS {
33 namespace Storage {
34 namespace DistributedFile {
35
CreateLocalLiveView(const std::string & networkId)36 int32_t SystemNotifier::CreateLocalLiveView(const std::string &networkId)
37 {
38 return g_publishNotification;
39 }
40
DestroyNotifyByNetworkId(const std::string & networkId)41 int32_t SystemNotifier::DestroyNotifyByNetworkId(const std::string &networkId)
42 {
43 return g_cancelNotification;
44 }
45
46 namespace Test {
47 using namespace testing;
48 using namespace testing::ext;
49 using OHOS::FileManagement::ERR_BAD_VALUE;
50 using OHOS::FileManagement::ERR_OK;
51
52 class ControlCmdParserTest : public testing::Test {
53 public:
SetUpTestCase()54 static void SetUpTestCase()
55 {
56 GTEST_LOG_(INFO) << "ControlCmdParserTest SetUpTestCase";
57 }
58
TearDownTestCase()59 static void TearDownTestCase()
60 {
61 GTEST_LOG_(INFO) << "ControlCmdParserTest TearDownTestCase";
62 }
63
SetUp()64 void SetUp()
65 {
66 GTEST_LOG_(INFO) << "ControlCmdParserTest SetUp";
67 g_publishNotification = 0;
68 g_cancelNotification = 0;
69 }
70
TearDown(void)71 void TearDown(void)
72 {
73 GTEST_LOG_(INFO) << "ControlCmdParserTest TearDown";
74 }
75 };
76 /**
77 * @tc.name: ControlCmdParserTest_ParseValidJson_001
78 * @tc.desc: Verify ParseFromJson with valid complete input
79 * @tc.type: FUNC
80 * @tc.require: I7TDJK
81 */
82 HWTEST_F(ControlCmdParserTest, ParseValidJson_001, TestSize.Level1)
83 {
84 std::string validJson = R"({
85 "version": 1,
86 "msgId": 1001,
87 "msgType": 1,
88 "msgBody": "testbody",
89 "networkId": "test-network"
90 })";
91
92 ControlCmd cmd;
93 EXPECT_TRUE(ControlCmdParser::ParseFromJson(validJson, cmd));
94 EXPECT_EQ(cmd.version, 1);
95 EXPECT_EQ(cmd.msgId, 1001);
96 EXPECT_EQ(cmd.msgType, 1);
97 EXPECT_EQ(cmd.msgBody, "testbody");
98 EXPECT_EQ(cmd.networkId, "test-network");
99 }
100
101 /**
102 * @tc.name: ControlCmdParserTest_ParseEmptyString_002
103 * @tc.desc: Verify ParseFromJson with empty input string
104 * @tc.type: FUNC
105 * @tc.require: I7TDJK
106 */
107 HWTEST_F(ControlCmdParserTest, ParseEmptyString_002, TestSize.Level1)
108 {
109 ControlCmd cmd;
110 EXPECT_FALSE(ControlCmdParser::ParseFromJson("", cmd));
111 }
112
113 /**
114 * @tc.name: ControlCmdParserTest_ParseInvalidSyntax_003
115 * @tc.desc: Verify ParseFromJson with invalid JSON syntax
116 * @tc.type: FUNC
117 * @tc.require: I7TDJK
118 */
119 HWTEST_F(ControlCmdParserTest, ParseInvalidSyntax_003, TestSize.Level1)
120 {
121 std::string invalidJson = R"({
122 "version": 1,
123 "msgId": 1001,
124 "msgType": 1,
125 "msgBody": "testbody",
126 "networkId": "test-network",
127 })";
128
129 ControlCmd cmd;
130 EXPECT_FALSE(ControlCmdParser::ParseFromJson(invalidJson, cmd));
131 }
132
133 /**
134 * @tc.name: ControlCmdParserTest_MissingMsgId_004
135 * @tc.desc: Verify ParseFromJson with missing msgId field
136 * @tc.type: FUNC
137 * @tc.require: I7TDJK
138 */
139 HWTEST_F(ControlCmdParserTest, MissingMsgId_004, TestSize.Level1)
140 {
141 std::string missingMsgId = R"({
142 "version": 1,
143 "msgType": 1,
144 "msgBody": "testbody",
145 "networkId": "test-network"
146 })";
147
148 ControlCmd cmd;
149 EXPECT_FALSE(ControlCmdParser::ParseFromJson(missingMsgId, cmd));
150 }
151
152 /**
153 * @tc.name: ControlCmdParserTest_MissingMsgType_005
154 * @tc.desc: Verify ParseFromJson with missing msgType field
155 * @tc.type: FUNC
156 * @tc.require: I7TDJK
157 */
158 HWTEST_F(ControlCmdParserTest, MissingMsgType_005, TestSize.Level1)
159 {
160 std::string missingMsgType = R"({
161 "version": 1,
162 "msgId": 1001,
163 "msgBody": "testbody",
164 "networkId": "test-network"
165 })";
166
167 ControlCmd cmd;
168 EXPECT_FALSE(ControlCmdParser::ParseFromJson(missingMsgType, cmd));
169 }
170
171 /**
172 * @tc.name: ControlCmdParserTest_MsgIdTypeMismatch_006
173 * @tc.desc: Verify ParseFromJson with msgId type mismatch
174 * @tc.type: FUNC
175 * @tc.require: I7TDJK
176 */
177 HWTEST_F(ControlCmdParserTest, MsgIdTypeMismatch_006, TestSize.Level1)
178 {
179 std::string wrongTypeMsgId = R"({
180 "version": 1,
181 "msgId": "1001",
182 "msgType": 1,
183 "msgBody": "testbody",
184 "networkId": "test-network"
185 })";
186
187 ControlCmd cmd;
188 EXPECT_FALSE(ControlCmdParser::ParseFromJson(wrongTypeMsgId, cmd));
189 }
190
191 /**
192 * @tc.name: ControlCmdParserTest_MsgTypeTypeMismatch_007
193 * @tc.desc: Verify ParseFromJson with msgType type mismatch
194 * @tc.type: FUNC
195 * @tc.require: I7TDJK
196 */
197 HWTEST_F(ControlCmdParserTest, MsgTypeTypeMismatch_007, TestSize.Level1)
198 {
199 std::string wrongTypeMsgType = R"({
200 "version": 1,
201 "msgId": 1001,
202 "msgType": true,
203 "msgBody": "testbody",
204 "networkId": "test-network"
205 })";
206
207 ControlCmd cmd;
208 EXPECT_FALSE(ControlCmdParser::ParseFromJson(wrongTypeMsgType, cmd));
209 }
210
211 /**
212 * @tc.name: ControlCmdParserTest_VersionOutOfRange_008
213 * @tc.desc: Verify ParseFromJson with version out of range
214 * @tc.type: FUNC
215 * @tc.require: I7TDJK
216 */
217 HWTEST_F(ControlCmdParserTest, VersionOutOfRange_008, TestSize.Level1)
218 {
219 std::string versionOutOfRange = R"({
220 "version": 70000,
221 "msgId": 1001,
222 "msgType": 1,
223 "msgBody": "testbody",
224 "networkId": "test-network"
225 })";
226
227 ControlCmd cmd;
228 EXPECT_TRUE(ControlCmdParser::ParseFromJson(versionOutOfRange, cmd));
229 }
230
231 /**
232 * @tc.name: ControlCmdParserTest_MinimalValidInput_009
233 * @tc.desc: Verify ParseFromJson with minimal valid input
234 * @tc.type: FUNC
235 * @tc.require: I7TDJK
236 */
237 HWTEST_F(ControlCmdParserTest, MinimalValidInput_009, TestSize.Level1)
238 {
239 std::string minimalValid = R"({
240 "msgId": 1001,
241 "msgType": 1
242 })";
243
244 ControlCmd cmd;
245 EXPECT_TRUE(ControlCmdParser::ParseFromJson(minimalValid, cmd));
246 EXPECT_EQ(cmd.msgId, 1001);
247 EXPECT_EQ(cmd.msgType, 1);
248 }
249
250 /**
251 * @tc.name: ControlCmdParserTest_MsgBodyTypeMismatch_010
252 * @tc.desc: Verify ParseFromJson with msgBody type mismatch
253 * @tc.type: FUNC
254 * @tc.require: I7TDJK
255 */
256 HWTEST_F(ControlCmdParserTest, MsgBodyTypeMismatch_010, TestSize.Level1)
257 {
258 std::string wrongTypeMsgBody = R"({
259 "msgId": 1001,
260 "msgType": 1,
261 "msgBody": 12345,
262 "networkId": "test-network"
263 })";
264
265 ControlCmd cmd;
266 EXPECT_TRUE(ControlCmdParser::ParseFromJson(wrongTypeMsgBody, cmd));
267 }
268
269 /**
270 * @tc.name: ControlCmdParserTest_NegativeVersion_011
271 * @tc.desc: Verify ParseFromJson with negative version number
272 * @tc.type: FUNC
273 * @tc.require: I7TDJK
274 */
275 HWTEST_F(ControlCmdParserTest, NegativeVersion_011, TestSize.Level1)
276 {
277 std::string negativeVersion = R"({
278 "version": -1,
279 "msgId": 1001,
280 "msgType": 1,
281 "msgBody": "testbody",
282 "networkId": "test-network"
283 })";
284
285 ControlCmd cmd;
286 EXPECT_TRUE(ControlCmdParser::ParseFromJson(negativeVersion, cmd));
287 }
288
289 /**
290 * @tc.name: SerializeToJson_ValidInput
291 * @tc.desc: Test SerializeToJson with valid ControlCmd
292 * @tc.type: FUNC
293 * @tc.require: I7TDJK
294 */
295 HWTEST_F(ControlCmdParserTest, SerializeToJson_ValidInput, TestSize.Level1)
296 {
297 ControlCmd cmd;
298 cmd.version = 1;
299 cmd.msgId = 1001;
300 cmd.msgType = 1;
301 cmd.msgBody = "test body";
302 cmd.networkId = "test-network";
303
304 std::string jsonStr;
305 EXPECT_TRUE(ControlCmdParser::SerializeToJson(cmd, jsonStr));
306 EXPECT_FALSE(jsonStr.empty());
307
308 // Verify the serialized JSON can be parsed back
309 ControlCmd parsedCmd;
310 EXPECT_TRUE(ControlCmdParser::ParseFromJson(jsonStr, parsedCmd));
311 EXPECT_EQ(parsedCmd.version, cmd.version);
312 EXPECT_EQ(parsedCmd.msgId, cmd.msgId);
313 EXPECT_EQ(parsedCmd.msgType, cmd.msgType);
314 EXPECT_EQ(parsedCmd.msgBody, cmd.msgBody);
315 EXPECT_EQ(parsedCmd.networkId, cmd.networkId);
316 }
317
318 /**
319 * @tc.name: HandleRequest_CheckAllowConnect_Success
320 * @tc.desc: Test HandleRequest with CMD_CHECK_ALLOW_CONNECT when device type matches
321 * @tc.type: FUNC
322 * @tc.require: I7TDJK
323 */
324 HWTEST_F(ControlCmdParserTest, HandleRequest_CheckAllowConnect_Success, TestSize.Level1)
325 {
326 ControlCmd inCmd;
327 ControlCmd outCmd;
328 inCmd.msgType = ControlCmdType::CMD_CHECK_ALLOW_CONNECT;
329 inCmd.msgId = 1001;
330
331 EXPECT_TRUE(ControlCmdParser::HandleRequest(inCmd, outCmd));
332 EXPECT_EQ(outCmd.msgType, ControlCmdType::CMD_MSG_RESPONSE);
333 EXPECT_EQ(outCmd.msgId, inCmd.msgId);
334 EXPECT_EQ(outCmd.msgBody, "false");
335 }
336
337 /**
338 * @tc.name: HandleRequest_PublishNotification_Success
339 * @tc.desc: Test HandleRequest with CMD_PUBLISH_NOTIFICATION when successful
340 * @tc.type: FUNC
341 * @tc.require: I7TDJK
342 */
343 HWTEST_F(ControlCmdParserTest, HandleRequest_PublishNotification, TestSize.Level1)
344 {
345 ControlCmd inCmd;
346 ControlCmd outCmd;
347 inCmd.msgType = ControlCmdType::CMD_PUBLISH_NOTIFICATION;
348 inCmd.networkId = "test-network";
349
350 EXPECT_TRUE(ControlCmdParser::HandleRequest(inCmd, outCmd));
351
352 g_publishNotification = 1;
353 EXPECT_FALSE(ControlCmdParser::HandleRequest(inCmd, outCmd));
354 }
355
356 /**
357 * @tc.name: HandleRequest_CancelNotification_Success
358 * @tc.desc: Test HandleRequest with CMD_CANCEL_NOTIFICATION when successful
359 * @tc.type: FUNC
360 * @tc.require: I7TDJK
361 */
362 HWTEST_F(ControlCmdParserTest, HandleRequest_CancelNotification_Success, TestSize.Level1)
363 {
364 ControlCmd inCmd;
365 ControlCmd outCmd;
366 inCmd.msgType = ControlCmdType::CMD_CANCEL_NOTIFICATION;
367 inCmd.networkId = "test-network";
368
369 EXPECT_TRUE(ControlCmdParser::HandleRequest(inCmd, outCmd));
370
371 g_cancelNotification = 1;
372 EXPECT_FALSE(ControlCmdParser::HandleRequest(inCmd, outCmd));
373 }
374
375 /**
376 * @tc.name: HandleRequest_DisconnectByRemote_NoCallback
377 * @tc.desc: Test HandleRequest with CMD_ACTIVE_DISCONNECT when no callback is registered
378 * @tc.type: FUNC
379 * @tc.require: I7TDJK
380 */
381 HWTEST_F(ControlCmdParserTest, HandleRequest_DisconnectByRemote_NoCallback, TestSize.Level1)
382 {
383 ControlCmd inCmd;
384 inCmd.msgType = ControlCmdType::CMD_ACTIVE_DISCONNECT;
385
386 ControlCmd outCmd;
387 EXPECT_FALSE(ControlCmdParser::HandleRequest(inCmd, outCmd));
388 }
389
390 /**
391 * @tc.name: HandleRequest_DisconnectByRemote_WithCallback
392 * @tc.desc: Test HandleRequest with CMD_ACTIVE_DISCONNECT when callback is registered
393 * @tc.type: FUNC
394 * @tc.require: I7TDJK
395 */
396 HWTEST_F(ControlCmdParserTest, HandleRequest_DisconnectByRemote_WithCallback, TestSize.Level1)
397 {
398 ControlCmd inCmd;
399 inCmd.msgType = ControlCmdType::CMD_ACTIVE_DISCONNECT;
400 inCmd.msgBody = "disconnect-msg";
401
402 ControlCmd outCmd;
403
404 bool callbackCalled = false;
__anonb20a85220202(std::string msg) 405 auto callback = [&callbackCalled](std::string msg) {
406 callbackCalled = true;
407 EXPECT_EQ(msg, "disconnect-msg");
408 };
409
410 ControlCmdParser::RegisterDisconnectCallback(callback);
411 EXPECT_TRUE(ControlCmdParser::HandleRequest(inCmd, outCmd));
412 EXPECT_TRUE(callbackCalled);
413 }
414
415 /**
416 * @tc.name: HandleRequest_UnknownType
417 * @tc.desc: Test HandleRequest with unknown message type
418 * @tc.type: FUNC
419 * @tc.require: I7TDJK
420 */
421 HWTEST_F(ControlCmdParserTest, HandleRequest_UnknownType, TestSize.Level1)
422 {
423 ControlCmd inCmd;
424 inCmd.msgType = 999; // Unknown type
425
426 ControlCmd outCmd;
427 EXPECT_FALSE(ControlCmdParser::HandleRequest(inCmd, outCmd));
428 }
429
430 } // namespace Test
431 } // namespace DistributedFile
432 } // namespace Storage
433 } // namespace OHOS