1/*
2 * Copyright (c) 2024 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 <string>
17#include <thread>
18#include <fstream>
19#include <cstdio>
20#include <unistd.h>
21#include "gtest/gtest.h"
22#define private public
23#include "CommandLineInterface.h"
24#include "CommandLineFactory.h"
25#include "CommandParser.h"
26#include "SharedData.h"
27#include "MockGlobalResult.h"
28#include "VirtualScreen.h"
29
30namespace {
31    std::string g_configPath = R"(
32        {
33        "setting": {
34        "1.0.0": {
35        "KeepScreenOnState": {
36            "args": {
37            "KeepScreenOnState": true
38            }
39        },
40        "BrightnessMode": {
41            "args": {
42            "BrightnessMode": 0
43            }
44        },
45        "Brightness": {
46            "args": {
47            "Brightness": 170
48            }
49        },
50        "WearingState": {
51            "args": {
52            "WearingState": true
53            }
54        },
55        "Barometer": {
56            "args": {
57            "Barometer": 101325
58            }
59        },
60        "HeartRate": {
61            "args": {
62            "HeartRate": 100
63            }
64        },
65        "StepCount": {
66            "args": {
67            "StepCount": 0
68            }
69        },
70        "Location": {
71            "args": {
72            "latitude": 39.914417,
73            "longitude": 116.39647
74            }
75        },
76        "ChargeMode": {
77            "args": {
78            "ChargeMode": 0
79            }
80        },
81        "Power": {
82            "args": {
83            "Power": 0.1
84            }
85        },
86        "Language": {
87            "args": {
88            "Language": "en-US"
89            }
90        }
91        },
92        "1.0.1": {
93        "Language": {
94            "args": {
95            "Language": "zh-CN"
96            }
97        }
98        }
99        },
100        "frontend": {
101        "1.0.0": {
102        "Resolution": {
103            "args": {
104            "Resolution": "454*454"
105            }
106        },
107        "DeviceType": {
108            "args": {
109            "DeviceType": "liteWearable"
110            }
111        }
112        }
113        }
114        }
115    )";
116
117    // 测试复制构造函数是否被删除
118    TEST(CommandLineInterfaceTest, DefaultConstructorDeletedTest)
119    {
120        EXPECT_TRUE(std::is_copy_constructible<CommandLineInterface>::value == false);
121    }
122
123    // 测试赋值运算符是否被删除
124    TEST(CommandLineInterfaceTest, AssignmentOperatorDeletedTest)
125    {
126        EXPECT_TRUE(std::is_copy_assignable<CommandLineInterface>::value == false);
127    }
128
129    TEST(CommandLineInterfaceTest, GetInstanceTest)
130    {
131        CommandLineInterface& instance1 = CommandLineInterface::GetInstance();
132        CommandLineInterface& instance2 = CommandLineInterface::GetInstance();
133        EXPECT_EQ(&instance1, &instance2);
134    }
135
136    TEST(CommandLineInterfaceTest, InitPipeTest)
137    {
138        CommandLineInterface::GetInstance().InitPipe("phone");
139        EXPECT_TRUE(CommandLineInterface::isPipeConnected);
140    }
141
142    TEST(CommandLineInterfaceTest, ProcessCommandTest)
143    {
144        // normal
145        g_input = false;
146        CommandLineInterface::GetInstance().ProcessCommand();
147        EXPECT_TRUE(g_input);
148        // socket is null
149        g_input = false;
150        std::unique_ptr<LocalSocket> temp = std::move(CommandLineInterface::GetInstance().socket);
151        CommandLineInterface::GetInstance().socket = nullptr;
152        CommandLineInterface::GetInstance().ProcessCommand();
153        EXPECT_FALSE(g_input);
154        CommandLineInterface::GetInstance().socket = std::move(temp);
155        // isFirstWsSend
156        g_input = false;
157        CommandLineInterface::GetInstance().isPipeConnected = true;
158        VirtualScreen::isWebSocketListening = true;
159        CommandLineInterface::GetInstance().isFirstWsSend = true;
160        CommandLineInterface::GetInstance().ProcessCommand();
161        EXPECT_FALSE(CommandLineInterface::GetInstance().isFirstWsSend);
162        EXPECT_TRUE(g_input);
163    }
164
165    TEST(CommandLineInterfaceTest, ProcessCommandMessageTest)
166    {
167        // normal
168        g_output = false;
169        std::string msg = R"({"type" : "action", "command" : "MousePress", "version" : "1.0.1"})";
170        CommandLineInterface::GetInstance().ProcessCommandMessage(msg);
171        EXPECT_TRUE(g_output);
172        // json parse failed
173        g_output = false;
174        std::string msg0 = R"({"type" : "aaaaa", "command" : "MousePress", "bbbb" : "1.0.1", "args" : {}})";
175        CommandLineInterface::GetInstance().ProcessCommandMessage("");
176        EXPECT_FALSE(g_output);
177        // json args invalid
178        g_output = false;
179        std::string msg1 = R"({"type" : "aaaaa", "command" : "MousePress", "bbbb" : "1.0.1"})";
180        CommandLineInterface::GetInstance().ProcessCommandMessage(msg1);
181        EXPECT_FALSE(g_output);
182        // cmd type error
183        g_output = false;
184        std::string msg2 = R"({"type" : "aaaaa", "command" : "MousePress", "version" : "1.0.1"})";
185        CommandLineInterface::GetInstance().ProcessCommandMessage(msg2);
186        EXPECT_FALSE(g_output);
187        // static card
188        g_output = false;
189        CommandParser::GetInstance().staticCard = true;
190        CommandLineInterface::GetInstance().ProcessCommandMessage(msg);
191        CommandParser::GetInstance().staticCard = false;
192        EXPECT_FALSE(g_output);
193    }
194
195    TEST(CommandLineInterfaceTest, ProcessCommandValidateTest)
196    {
197        CommandLineInterface& instance = CommandLineInterface::GetInstance();
198        std::string msg = "{}";
199        Json2::Value jsonData1 = JsonReader::ParseJsonData2(msg);
200        EXPECT_FALSE(instance.ProcessCommandValidate(false, jsonData1, "Failed to parse the JSON"));
201        msg = "[]";
202        Json2::Value jsonData2 = JsonReader::ParseJsonData2(msg);
203        EXPECT_FALSE(instance.ProcessCommandValidate(true, jsonData2, "Command is not a object"));
204        msg = R"({"type" : "action", "command" : "MousePress"})";
205        Json2::Value jsonData3 = JsonReader::ParseJsonData2(msg);
206        EXPECT_FALSE(instance.ProcessCommandValidate(true, jsonData3, "Command error"));
207        msg = R"({"type" : "action", "command" : "MousePress", "version" : "s.0.1"})";
208        Json2::Value jsonData4 = JsonReader::ParseJsonData2(msg);
209        EXPECT_FALSE(instance.ProcessCommandValidate(true, jsonData4, "Invalid command version"));
210        msg = R"({"type" : "action", "command" : "MousePress", "version" : "1.0.1"})";
211        Json2::Value jsonData5 = JsonReader::ParseJsonData2(msg);
212        EXPECT_TRUE(instance.ProcessCommandValidate(true, jsonData5, ""));
213    }
214
215    TEST(CommandLineInterfaceTest, GetCommandTypeTest)
216    {
217        CommandLineInterface& instance = CommandLineInterface::GetInstance();
218        EXPECT_EQ(instance.GetCommandType(""), CommandLine::CommandType::INVALID);
219        EXPECT_EQ(instance.GetCommandType("set"), CommandLine::CommandType::SET);
220        EXPECT_EQ(instance.GetCommandType("get"), CommandLine::CommandType::GET);
221        EXPECT_EQ(instance.GetCommandType("action"), CommandLine::CommandType::ACTION);
222    }
223
224    TEST(CommandLineInterfaceTest, InitTest)
225    {
226        CommandLineInterface& instance = CommandLineInterface::GetInstance();
227        instance.Init("phone");
228        EXPECT_TRUE(CommandLineFactory::typeMap.size() > 0);
229        EXPECT_TRUE(CommandLineInterface::isPipeConnected);
230    }
231
232    TEST(CommandLineInterfaceTest, IsStaticIgnoreCmdTest)
233    {
234        CommandLineInterface& instance = CommandLineInterface::GetInstance();
235        std::string msg = "Language";
236        EXPECT_FALSE(instance.IsStaticIgnoreCmd(msg));
237        std::string msg1 = "Language1";
238        EXPECT_TRUE(instance.IsStaticIgnoreCmd(msg1));
239    }
240
241    void InitSharedData(std::string deviceType)
242    {
243        if (deviceType == "liteWearable" || "smartVersion") {
244            SharedData<bool>(SharedDataType::KEEP_SCREEN_ON, true);
245            SharedData<uint8_t>(SharedDataType::BATTERY_STATUS, (uint8_t)ChargeState::NOCHARGE,
246                                (uint8_t)ChargeState::NOCHARGE, (uint8_t)ChargeState::CHARGING);
247            // The brightness ranges from 1 to 255. The default value is 255.
248            SharedData<uint8_t>(SharedDataType::BRIGHTNESS_VALUE, 255, 1, 255);
249            SharedData<uint8_t>(SharedDataType::BRIGHTNESS_MODE, (uint8_t)BrightnessMode::MANUAL,
250                                (uint8_t)BrightnessMode::MANUAL, (uint8_t)BrightnessMode::AUTO);
251            // The value ranges from 0 to 999999. The default value is 0.
252            SharedData<uint32_t>(SharedDataType::SUMSTEP_VALUE, 0, 0, 999999);
253            // The volume ranges from 0.0 to 1.0. The default value is 1.0.
254            SharedData<double>(SharedDataType::VOLUME_VALUE, 1.0, 0.0, 1.0);
255            // Battery level range: 0.0–1.0; default: 1.0
256            SharedData<double>(SharedDataType::BATTERY_LEVEL, 1.0, 0.0, 1.0);
257            // Heart rate range: 0 to 255. The default value is 80.
258            SharedData<uint8_t>(SharedDataType::HEARTBEAT_VALUE, 80, 0, 255);
259            SharedData<std::string>(SharedDataType::LANGUAGE, "zh-CN");
260            // The value ranges from 180 to 180. The default value is 0.
261            SharedData<double>(SharedDataType::LONGITUDE, 0, -180, 180);
262            // The atmospheric pressure ranges from 0 to 999900. The default value is 101325.
263            SharedData<uint32_t>(SharedDataType::PRESSURE_VALUE, 101325, 0, 999900);
264            SharedData<bool>(SharedDataType::WEARING_STATE, true);
265            // The value ranges from -90 to 90. The default value is 0.
266            SharedData<double>(SharedDataType::LATITUDE, 0, -90, 90);
267        } else {
268            SharedData<std::string>(SharedDataType::LANGUAGE, "zh_CN");
269            SharedData<std::string>(SharedDataType::LAN, "zh");
270            SharedData<std::string>(SharedDataType::REGION, "CN");
271        }
272    }
273
274    TEST(CommandLineInterfaceTest, ReadAndApplyConfigTest)
275    {
276        std::string deviceType = "liteWearable";
277        CommandParser::GetInstance().deviceType = deviceType;
278        CommandLineInterface& instance = CommandLineInterface::GetInstance();
279        // path is empty
280        instance.ReadAndApplyConfig("");
281        EXPECT_FALSE(SharedData<bool>::GetData(SharedDataType::KEEP_SCREEN_ON));
282        // path not empty
283        instance.Init(deviceType);
284        InitSharedData(deviceType);
285        char buffer[FILENAME_MAX];
286        if (getcwd(buffer, FILENAME_MAX) != nullptr) {
287            std::string currDir = std::string(buffer);
288            std::string currFile = currDir + "/config.json";
289            // 创建文件流对象并打开文件
290            std::ofstream file(currFile);
291            // 检查文件是否成功打开
292            if (file.is_open()) {
293                file << g_configPath;
294                file.close();
295                instance.ReadAndApplyConfig(currFile);
296            } else {
297                printf("Error creating file!\n");\
298                EXPECT_TRUE(false);
299            }
300        } else {
301            printf("error: getcwd failed\n");
302            EXPECT_TRUE(false);
303        }
304        EXPECT_TRUE(SharedData<bool>::GetData(SharedDataType::KEEP_SCREEN_ON));
305        EXPECT_EQ(SharedData<uint8_t>::GetData(SharedDataType::BRIGHTNESS_VALUE), 170);
306        EXPECT_EQ(SharedData<uint8_t>::GetData(SharedDataType::HEARTBEAT_VALUE), 100);
307    }
308
309    TEST(CommandLineInterfaceTest, ApplyConfigCommandsTest_Err)
310    {
311        g_output = false;
312        CommandLineInterface::GetInstance().ApplyConfigCommands("MousePress", nullptr);
313        EXPECT_FALSE(g_output);
314    }
315
316    TEST(CommandLineInterfaceTest, CreatCommandToSendDataTest_Err)
317    {
318        g_output = false;
319        Json2::Value val;
320        CommandLineInterface::GetInstance().CreatCommandToSendData("aaaa", val, "set");
321        EXPECT_TRUE(g_output);
322    }
323
324    TEST(CommandLineInterfaceTest, SendJsonDataTest)
325    {
326        g_output = false;
327        std::string msg = R"({"type":"action","command":"MousePress"})";
328        Json2::Value jsonData = JsonReader::ParseJsonData2(msg);
329        CommandLineInterface::SendJsonData(jsonData);
330        EXPECT_TRUE(g_output);
331    }
332
333    TEST(CommandLineInterfaceTest, SendJSHeapMemoryTest)
334    {
335        g_output = false;
336        CommandLineInterface::GetInstance().SendJSHeapMemory(1, 1, 1);
337        EXPECT_TRUE(g_output);
338    }
339
340    TEST(CommandLineInterfaceTest, SendWebsocketStartupSignalTest)
341    {
342        g_output = false;
343        CommandLineInterface::GetInstance().SendWebsocketStartupSignal();
344        EXPECT_TRUE(g_output);
345    }
346
347    TEST(CommandLineInterfaceTest, CreatCommandToSendDataTest)
348    {
349        std::string deviceType = "phone";
350        CommandParser::GetInstance().deviceType = deviceType;
351        CommandLineInterface::GetInstance().Init(deviceType);
352        g_output = false;
353        EXPECT_FALSE(g_output);
354        Json2::Value val;
355        CommandLineInterface::GetInstance().CreatCommandToSendData("LoadContent", val, "get");
356        EXPECT_TRUE(g_output);
357    }
358
359    TEST(CommandLineInterfaceTest, ApplyConfigMembersTest_Err)
360    {
361        std::string deviceType = "liteWearable";
362        CommandParser::GetInstance().deviceType = deviceType;
363        CommandLineInterface::GetInstance().Init(deviceType);
364        std::string jsonStr = R"({ "Language" : { "args" : { "Language" : "zh-CN" }},
365                                    "Language2" : { "args1" : { "Language" : "zh-CN" }},
366                                    "Language3" : "",
367                                    "Language4" : { "args" : ""}})";
368        Json2::Value::Members members= { "Language", "Language2", "Language3", "Language4" };
369        Json2::Value commands = JsonReader::ParseJsonData2(jsonStr);
370        CommandLineInterface::GetInstance().ApplyConfigMembers(commands, members);
371        std::string language = SharedData<std::string>::GetData(SharedDataType::LANGUAGE);
372        EXPECT_EQ(language, "zh-CN");
373    }
374
375    TEST(CommandLineInterfaceTest, ApplyConfigTest_Err)
376    {
377        g_output = false;
378        std::string jsonStr1 = R"({ "setting" : { "1.0.1" : "aaa"}})";
379        Json2::Value json1 = JsonReader::ParseJsonData2(jsonStr1);
380        CommandLineInterface::GetInstance().ApplyConfig(json1);
381        EXPECT_FALSE(g_output);
382        g_output = false;
383        std::string jsonStr2 = R"({ "setting" : "aaa"})";
384        Json2::Value json2 = JsonReader::ParseJsonData2(jsonStr2);
385        CommandLineInterface::GetInstance().ApplyConfig(json2);
386        EXPECT_FALSE(g_output);
387    }
388
389    TEST(CommandLineInterfaceTest, SendJSHeapMemoryTest_Err)
390    {
391        g_output = false;
392        std::unique_ptr<LocalSocket> temp = std::move(CommandLineInterface::GetInstance().socket);
393        CommandLineInterface::GetInstance().socket = nullptr;
394        CommandLineInterface::GetInstance().SendJSHeapMemory(0, 0, 0);
395        EXPECT_FALSE(g_output);
396        CommandLineInterface::GetInstance().socket = std::move(temp);
397    }
398}
399