• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <utility>
17 
18 #include "gtest/gtest.h"
19 // For testing private method
20 #define private public
21 #include "frontend_api_handler.h"
22 #include "dummy_controller.h"
23 #include "widget_selector.h"
24 
25 using namespace OHOS::uitest;
26 using namespace std;
27 using namespace nlohmann;
28 
29 // test fixture
30 class FrontendApiHandlerTest : public testing::Test {
31 public:
32     ~FrontendApiHandlerTest() override = default;
33 protected:
SetUp()34     void SetUp() override
35     {
36         auto dummyController = make_unique<DummyController>("dummyController");
37         dummyController->SetWorkable(true);
38         UiController::RegisterController(move(dummyController), HIGH);
39     }
40 
TearDown()41     void TearDown() override
42     {
43         // common-preprocessors works on all apiCall, delete after testing
44         FrontendApiServer::Get().RemoveCommonPreprocessor("dummyProcessor");
45         UiController::RemoveController("dummyController");
46     }
47 };
48 
TEST_F(FrontendApiHandlerTest,basicJsonReadWrite)49 TEST_F(FrontendApiHandlerTest, basicJsonReadWrite)
50 {
51     auto container = json::array();
52     // write
53     container.emplace_back("wyz");
54     container.emplace_back(1);
55     container.emplace_back(0.1);
56     container.emplace_back(true);
57     container.emplace_back(nullptr);
58     // read
59     ASSERT_EQ(5, container.size());
60     ASSERT_EQ("wyz", container.at(INDEX_ZERO).get<string>());
61     ASSERT_EQ(1, container.at(INDEX_ONE).get<uint8_t>());
62     ASSERT_NEAR(0.1, container.at(INDEX_TWO).get<float>(), 1E-6);
63     ASSERT_EQ(true, container.at(INDEX_THREE).get<bool>());
64     ASSERT_EQ(nlohmann::detail::value_t::null, container.at(INDEX_FOUR).type());
65 }
66 
GenerateUniqueId()67 static string GenerateUniqueId()
68 {
69     return to_string(GetCurrentMicroseconds());
70 }
71 
TEST_F(FrontendApiHandlerTest,noInvocationHandler)72 TEST_F(FrontendApiHandlerTest, noInvocationHandler)
73 {
74     static auto apiId = GenerateUniqueId();
75     auto call = ApiCallInfo {.apiId_ = "wyz"};
76     auto reply = ApiReplyInfo();
77     FrontendApiServer::Get().Call(call, reply);
78     ASSERT_EQ(ERR_INTERNAL, reply.exception_.code_);
79     ASSERT_TRUE(reply.exception_.message_.find("No handler found") != string::npos);
80 }
81 
TEST_F(FrontendApiHandlerTest,addRemoveHandler)82 TEST_F(FrontendApiHandlerTest, addRemoveHandler)
83 {
84     static auto apiId = GenerateUniqueId();
85     auto &server = FrontendApiServer::Get();
86     ASSERT_FALSE(server.HasHandlerFor(apiId));
87     auto handler = [](const ApiCallInfo &in, ApiReplyInfo &out) {
88         // nop
89     };
90     server.AddHandler(apiId, handler);
91     ASSERT_TRUE(server.HasHandlerFor(apiId));
92 
93     json caller;
94     auto call = ApiCallInfo {.apiId_ = apiId};
95     auto reply = ApiReplyInfo();
96     server.Call(call, reply);
97     ASSERT_EQ(NO_ERROR, reply.exception_.code_);
98 
99     server.RemoveHandler(apiId);
100     ASSERT_FALSE(server.HasHandlerFor(apiId));
101     server.Call(call, reply);
102     ASSERT_EQ(ERR_INTERNAL, reply.exception_.code_) << "The handler should be unavailable after been removed";
103 }
104 
TEST_F(FrontendApiHandlerTest,inOutDataTransfer)105 TEST_F(FrontendApiHandlerTest, inOutDataTransfer)
106 {
107     static auto apiId = GenerateUniqueId();
108     auto &server = FrontendApiServer::Get();
109     auto handler = [](const ApiCallInfo &in, ApiReplyInfo &out) {
110         out.resultValue_ = in.paramList_.at(0).get<string>().length() + in.paramList_.at(1).get<uint8_t>();
111     };
112     server.AddHandler(apiId, handler);
113 
114     auto call = ApiCallInfo {.apiId_ = apiId};
115     auto reply = ApiReplyInfo();
116     call.paramList_.emplace_back("wyz");
117     call.paramList_.emplace_back(10);
118     server.Call(call, reply);
119     ASSERT_EQ(NO_ERROR, reply.exception_.code_);
120     ASSERT_EQ(string("wyz").length() + 10, reply.resultValue_.get<uint8_t>());
121 }
122 
TEST_F(FrontendApiHandlerTest,jsonExceptionDefance)123 TEST_F(FrontendApiHandlerTest, jsonExceptionDefance)
124 {
125     static auto apiId = GenerateUniqueId();
126     auto &server = FrontendApiServer::Get();
127     auto handler = [](const ApiCallInfo &in, ApiReplyInfo &out) {
128         out.resultValue_ = in.paramList_.at(100).get<uint8_t>();
129     };
130     server.AddHandler(apiId, handler);
131 
132     auto call = ApiCallInfo {.apiId_ = apiId};
133     auto reply = ApiReplyInfo();
134     server.Call(call, reply);
135     // json exception should be caught and reported properly
136     ASSERT_EQ(ERR_INTERNAL, reply.exception_.code_);
137     ASSERT_TRUE(reply.exception_.message_.find("json.exception.out_of_range") != string::npos);
138 }
139 
TEST_F(FrontendApiHandlerTest,apiErrorDeliver)140 TEST_F(FrontendApiHandlerTest, apiErrorDeliver)
141 {
142     static auto apiId = GenerateUniqueId();
143     auto &server = FrontendApiServer::Get();
144     auto handler = [](const ApiCallInfo &in, ApiReplyInfo &out) { out.exception_.code_ = USAGE_ERROR; };
145     server.AddHandler(apiId, handler);
146 
147     auto call = ApiCallInfo {.apiId_ = apiId};
148     auto reply = ApiReplyInfo();
149     server.Call(call, reply);
150     // api error should be delivered out to caller
151     ASSERT_EQ(USAGE_ERROR, reply.exception_.code_);
152 }
153 
TEST_F(FrontendApiHandlerTest,commonPreprocessor)154 TEST_F(FrontendApiHandlerTest, commonPreprocessor)
155 {
156     static auto apiId = GenerateUniqueId();
157     auto &server = FrontendApiServer::Get();
158     auto handlerCalled = false;
159     auto handler = [&handlerCalled](const ApiCallInfo &in, ApiReplyInfo &out) { handlerCalled = true; };
160     server.AddHandler(apiId, handler);
161 
162     auto processor = [](const ApiCallInfo &in, ApiReplyInfo &out) {
163         if (in.paramList_.at(0).get<string>() == "oops") {
164             out.exception_.code_ = ERR_OPERATION_UNSUPPORTED;
165         }
166     };
167     server.AddCommonPreprocessor("dummyProcessor", processor);
168 
169     auto call = ApiCallInfo {.apiId_ = apiId};
170     auto reply = ApiReplyInfo();
171     // handler should be called if preprocessing passed
172     call.paramList_.emplace_back("nice");
173     server.Call(call, reply);
174     ASSERT_EQ(NO_ERROR, reply.exception_.code_);
175     ASSERT_TRUE(handlerCalled);
176     // preprocessing failed, handler should not be called
177     call.paramList_.clear();
178     call.paramList_.emplace_back("oops");
179     handlerCalled = false;
180     server.Call(call, reply);
181     ASSERT_EQ(ERR_OPERATION_UNSUPPORTED, reply.exception_.code_);
182     ASSERT_FALSE(handlerCalled);
183 }
184 
TEST_F(FrontendApiHandlerTest,checkAllHandlersRegisted)185 TEST_F(FrontendApiHandlerTest, checkAllHandlersRegisted)
186 {
187     auto &server = FrontendApiServer::Get();
188     // each frontend-api should have handler
189     for (const auto &classDef : FRONTEND_CLASS_DEFS) {
190         for (size_t idx = 0; idx < classDef->methodCount_; idx++) {
191             const auto &methodDef = classDef->methods_[idx];
192             const auto message = "No handler registered for '" + string(methodDef.name_) + "'";
193             ASSERT_TRUE(server.HasHandlerFor(methodDef.name_)) << message;
194         }
195     }
196 }
197 
198 // API8 end to end call test
TEST_F(FrontendApiHandlerTest,callApiE2EOldAPi)199 TEST_F(FrontendApiHandlerTest, callApiE2EOldAPi)
200 {
201     const auto& server =  FrontendApiServer::Get();
202     // create by1 with seed
203     auto call0 = ApiCallInfo {.apiId_ = "By.text", .callerObjRef_ = string(REF_SEED_BY)};
204     call0.paramList_.emplace_back("wyz");
205     auto reply0 = ApiReplyInfo();
206     server.Call(call0, reply0);
207     // check result
208     ASSERT_EQ(NO_ERROR, reply0.exception_.code_);
209     ASSERT_EQ(nlohmann::detail::value_t::string, reply0.resultValue_.type()); // should return backend-by-ref
210     const auto ref0 = reply0.resultValue_.get<string>();
211     ASSERT_TRUE(ref0.find("By#") != string::npos);
212 
213     // go on creating combine by: isAfter (after ref0)
214     auto call1 = ApiCallInfo {.apiId_ = "By.isAfter", .callerObjRef_ = string(REF_SEED_BY)};
215     call1.paramList_.emplace_back(ref0);
216     auto reply1 = ApiReplyInfo();
217     server.Call(call1, reply1);
218     ASSERT_EQ(NO_ERROR, reply1.exception_.code_);
219     ASSERT_EQ(nlohmann::detail::value_t::string, reply1.resultValue_.type()); // should return backend-by-ref
220     const auto ref1 = reply1.resultValue_.get<string>();
221     ASSERT_TRUE(ref1.find("By#") != string::npos);
222     // should always return a new By
223     ASSERT_NE(ref0, ref1);
224 
225     auto call2 = ApiCallInfo {.apiId_ = "UiDriver.create", .callerObjRef_ = string()};
226     auto reply2 = ApiReplyInfo();
227     server.Call(call2, reply2);
228     ASSERT_EQ(NO_ERROR, reply2.exception_.code_);
229     ASSERT_EQ(nlohmann::detail::value_t::string, reply2.resultValue_.type()); // should return backend-On-ref
230     const auto ref2 = reply2.resultValue_.get<string>();
231     ASSERT_TRUE(ref2.find("UiDriver#") != string::npos);
232 
233     auto call3 = ApiCallInfo {.apiId_ = "By.id", .callerObjRef_ = string(REF_SEED_BY)};
234     call3.paramList_.emplace_back(1);
235     auto reply3 = ApiReplyInfo();
236     server.Call(call3, reply3);
237     // check result
238     ASSERT_EQ(NO_ERROR, reply3.exception_.code_);
239     ASSERT_EQ(nlohmann::detail::value_t::string, reply3.resultValue_.type()); // should return backend-by-ref
240     const auto ref3 = reply3.resultValue_.get<string>();
241     ASSERT_TRUE(ref3.find("By#") != string::npos);
242 
243     auto call4 = ApiCallInfo {.apiId_ = "By.key", .callerObjRef_ = string(REF_SEED_BY)};
244     call4.paramList_.emplace_back("1");
245     auto reply4 = ApiReplyInfo();
246     server.Call(call4, reply4);
247     // check result
248     ASSERT_EQ(NO_ERROR, reply4.exception_.code_);
249     ASSERT_EQ(nlohmann::detail::value_t::string, reply4.resultValue_.type()); // should return backend-by-ref
250     const auto ref4 = reply4.resultValue_.get<string>();
251     ASSERT_TRUE(ref4.find("By#") != string::npos);
252 }
253 
254 // API9+ end to end call test
TEST_F(FrontendApiHandlerTest,callApiE2E)255 TEST_F(FrontendApiHandlerTest, callApiE2E)
256 {
257     const auto& server =  FrontendApiServer::Get();
258 
259     // create by1 with seed
260     auto call0 = ApiCallInfo {.apiId_ = "On.text", .callerObjRef_ = string(REF_SEED_BY)};
261     call0.paramList_.emplace_back("wyz");
262     auto reply0 = ApiReplyInfo();
263     server.Call(call0, reply0);
264     // check result
265     ASSERT_EQ(NO_ERROR, reply0.exception_.code_);
266     ASSERT_EQ(nlohmann::detail::value_t::string, reply0.resultValue_.type()); // should return backend-On-ref
267     const auto ref0 = reply0.resultValue_.get<string>();
268     ASSERT_TRUE(ref0.find("On#") != string::npos);
269 
270     // go on creating combine by: isAfter (after ref0)
271     auto call1 = ApiCallInfo {.apiId_ = "On.isAfter", .callerObjRef_ = string(REF_SEED_BY)};
272     call1.paramList_.emplace_back(ref0);
273     auto reply1 = ApiReplyInfo();
274     server.Call(call1, reply1);
275     // check result
276     ASSERT_EQ(NO_ERROR, reply1.exception_.code_);
277     ASSERT_EQ(nlohmann::detail::value_t::string, reply1.resultValue_.type()); // should return backend-On-ref
278     const auto ref1 = reply1.resultValue_.get<string>();
279     ASSERT_TRUE(ref1.find("On#") != string::npos);
280     ASSERT_NE(ref0, ref1);
281 
282     // should always return a new By
283     auto call2 = ApiCallInfo {.apiId_ = "Driver.create", .callerObjRef_ = string()};
284     auto reply2 = ApiReplyInfo();
285     server.Call(call2, reply2);
286     ASSERT_EQ(NO_ERROR, reply2.exception_.code_);
287     ASSERT_EQ(nlohmann::detail::value_t::string, reply2.resultValue_.type()); // should return backend-On-ref
288     const auto ref2 = reply2.resultValue_.get<string>();
289     ASSERT_TRUE(ref2.find("Driver#") != string::npos);
290 
291     auto call3 = ApiCallInfo {.apiId_ = "On.id", .callerObjRef_ = string(REF_SEED_BY)};
292     call3.paramList_.emplace_back("1");
293     auto reply3 = ApiReplyInfo();
294     server.Call(call3, reply3);
295     // check result
296     ASSERT_EQ(NO_ERROR, reply3.exception_.code_);
297     ASSERT_EQ(nlohmann::detail::value_t::string, reply3.resultValue_.type()); // should return backend-by-ref
298     const auto ref3 = reply3.resultValue_.get<string>();
299     ASSERT_TRUE(ref3.find("On#") != string::npos);
300 }
301 
302 // FrontendAPiServer::ApiMapPre and ApiMapPost Test (Used for old api adaptation)
TEST_F(FrontendApiHandlerTest,apiMapTest)303 TEST_F(FrontendApiHandlerTest, apiMapTest) {
304     const auto& server =  FrontendApiServer::Get();
305     auto call0 = ApiCallInfo {.apiId_ = "UiDriver.findComponent", .callerObjRef_ = "UiDriver#0"};
306     call0.paramList_.emplace_back("By#1");
307     string oldApiName = server.ApiMapPre(call0);
308     // Call_id and callerObjRef should be converted correctly.
309     // Object parameters and object return value should be converted.
310     ASSERT_EQ(call0.paramList_.at(0).get<string>(), "On#1");
311     ASSERT_EQ(call0.apiId_, "Driver.findComponent");
312     ASSERT_EQ(call0.callerObjRef_, "Driver#0");
313     ASSERT_EQ(oldApiName, "UiDriver.findComponent");
314     auto reply0 = ApiReplyInfo();
315     reply0.resultValue_ = "Component#1";
316     server.ApiMapPost(oldApiName, reply0);
317     ASSERT_EQ(reply0.resultValue_.get<string>(), "UiComponent#1");
318 
319     oldApiName = "UiDriver.findComponents";
320     auto reply1 = ApiReplyInfo();
321     reply1.resultValue_ = nlohmann::json::array();
322     reply1.resultValue_.emplace_back("Component#0");
323     reply1.resultValue_.emplace_back("Component#1");
324     server.ApiMapPost(oldApiName, reply1);
325     // Object array return value should be converted;
326     ASSERT_EQ(reply1.resultValue_.at(0).get<string>(), "UiComponent#0");
327     ASSERT_EQ(reply1.resultValue_.at(1).get<string>(), "UiComponent#1");
328 
329     auto call1 = ApiCallInfo {.apiId_ = "By.text", .callerObjRef_ = "By#seed"};
330     call1.paramList_.emplace_back("By#0");
331     oldApiName = server.ApiMapPre(call1);
332     // String parameters should NOT be converted;
333     ASSERT_EQ(call1.apiId_, "On.text");
334     ASSERT_EQ(call1.callerObjRef_, "On#seed");
335     ASSERT_EQ(call1.paramList_.at(0).get<string>(), "By#0");
336     ASSERT_EQ(oldApiName, "By.text");
337 
338     auto call2 = ApiCallInfo {.apiId_ = "UiComponent.getText", .callerObjRef_ = "UiComponent#0"};
339     oldApiName = server.ApiMapPre(call2);
340     // String return value should NOT be converted.
341     ASSERT_EQ(call2.apiId_, "Component.getText");
342     ASSERT_EQ(call2.callerObjRef_, "Component#0");
343     ASSERT_EQ(oldApiName, "UiComponent.getText");
344     auto reply2 = ApiReplyInfo();
345     reply2.resultValue_ = "Component#0";
346     server.ApiMapPost(oldApiName, reply2);
347     ASSERT_EQ(reply2.resultValue_.get<string>(), "Component#0");
348 
349     auto call3 = ApiCallInfo {.apiId_ = "Component.getText", .callerObjRef_ = "Component#0"};
350     oldApiName = server.ApiMapPre(call3);
351     // New API should NOT be converted.
352     ASSERT_EQ(call3.apiId_, "Component.getText");
353     ASSERT_EQ(call3.callerObjRef_, "Component#0");
354     ASSERT_EQ(oldApiName, "");
355 
356     // Test special apiId_ mapping
357     ApiCallInfo calls[] = {
358         {.apiId_ = "By.id", .callerObjRef_ = "By#0"},
359         {.apiId_ = "By.key", .callerObjRef_ = "By#0"},
360         {.apiId_ = "UiComponent.getId", .callerObjRef_ = "UiComponent#0"},
361         {.apiId_ = "UiComponent.getKey", .callerObjRef_ = "UiComponent#0"}
362     };
363     string expectedResults[] = {
364         "On.accessibilityId",
365         "On.id",
366         "Component.getAccessibilityId",
367         "Component.getId"
368     };
369     for (size_t i = 0; i < sizeof(calls) / sizeof(ApiCallInfo); i++) {
370         server.ApiMapPre(calls[i]);
371         ASSERT_EQ(calls[i].apiId_, expectedResults[i]);
372     }
373 }
374 
TEST_F(FrontendApiHandlerTest,parameterPreChecks)375 TEST_F(FrontendApiHandlerTest, parameterPreChecks)
376 {
377     const auto& server =  FrontendApiServer::Get();
378     // call with argument missing
379     auto call0 = ApiCallInfo {.apiId_ = "By.type", .callerObjRef_ = string(REF_SEED_BY)};
380     auto reply0 = ApiReplyInfo();
381     server.Call(call0, reply0);
382     ASSERT_EQ(USAGE_ERROR, reply0.exception_.code_);
383     ASSERT_TRUE(reply0.exception_.message_.find("Illegal argument count") != string::npos);
384     // call with argument redundant
385     auto call1 = ApiCallInfo {.apiId_ = "By.type", .callerObjRef_ = string(REF_SEED_BY)};
386     auto reply1 = ApiReplyInfo();
387     call1.paramList_.emplace_back("wyz");
388     call1.paramList_.emplace_back("zl");
389     server.Call(call1, reply1);
390     ASSERT_EQ(USAGE_ERROR, reply1.exception_.code_);
391     ASSERT_TRUE(reply1.exception_.message_.find("Illegal argument count") != string::npos);
392     // call with argument of wrong type
393     auto call2 = ApiCallInfo {.apiId_ = "By.type", .callerObjRef_ = string(REF_SEED_BY)};
394     auto reply2 = ApiReplyInfo();
395     call2.paramList_.emplace_back(1);
396     server.Call(call2, reply2);
397     ASSERT_EQ(USAGE_ERROR, reply2.exception_.code_);
398     ASSERT_TRUE(reply2.exception_.message_.find("Expect string") != string::npos);
399     // call with argument defaulted (bool=true)
400     auto call3 = ApiCallInfo {.apiId_ = "By.enabled", .callerObjRef_ = string(REF_SEED_BY)};
401     auto reply3 = ApiReplyInfo();
402     call3.paramList_.emplace_back(true); // no defaulted
403     server.Call(call3, reply3);
404     ASSERT_EQ(NO_ERROR, reply3.exception_.code_);
405 
406     auto call4 = ApiCallInfo {.apiId_ = "By.enabled", .callerObjRef_ = string(REF_SEED_BY)};
407     auto reply4 = ApiReplyInfo(); // defaulted
408     server.Call(call4, reply4);
409     ASSERT_EQ(NO_ERROR, reply4.exception_.code_);
410     // call with bad object ref
411     auto call5 = ApiCallInfo {.apiId_ = "By.isAfter", .callerObjRef_ = string(REF_SEED_BY)};
412     call5.paramList_.emplace_back("By#100");
413     auto reply5 = ApiReplyInfo();
414     server.Call(call5, reply5);
415     ASSERT_EQ(INTERNAL_ERROR, reply5.exception_.code_); // bad-object is internal_error
416     ASSERT_TRUE(reply5.exception_.message_.find("Bad object ref") != string::npos);
417     // call with json param with wrong property
418     auto call6 = ApiCallInfo {.apiId_ = "UiDriver.create"};
419     auto reply6 = ApiReplyInfo();
420     server.Call(call6, reply6);
421     auto call7 = ApiCallInfo {.apiId_ = "UiDriver.findWindow", .callerObjRef_ = reply6.resultValue_.get<string>()};
422     auto arg = json();
423     arg["badProp"] = "wyz";
424     call7.paramList_.emplace_back(arg);
425     auto reply7 = ApiReplyInfo();
426     server.Call(call7, reply7);
427     ASSERT_EQ(USAGE_ERROR, reply7.exception_.code_);
428     ASSERT_TRUE(reply7.exception_.message_.find("Illegal property") != string::npos);
429 }
430 
TEST_F(FrontendApiHandlerTest,pointerMatrixparameterPreChecks)431 TEST_F(FrontendApiHandlerTest, pointerMatrixparameterPreChecks)
432 {
433     const auto& server =  FrontendApiServer::Get();
434     // call with argument llegal fingers
435     auto call0 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
436     auto reply0 = ApiReplyInfo();
437     call0.paramList_.emplace_back(11);
438     call0.paramList_.emplace_back(3);
439     server.Call(call0, reply0);
440     ASSERT_EQ(ERR_INVALID_INPUT, reply0.exception_.code_);
441     ASSERT_TRUE(reply0.exception_.message_.find("Number of illegal fingers") != string::npos);
442     // call with argument illegal steps
443     auto call2 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
444     auto reply2 = ApiReplyInfo();
445     call2.paramList_.emplace_back(2);
446     call2.paramList_.emplace_back(1001);
447     server.Call(call2, reply2);
448     ASSERT_EQ(ERR_INVALID_INPUT, reply2.exception_.code_);
449     ASSERT_TRUE(reply2.exception_.message_.find("Number of illegal steps") != string::npos);
450     // call with argument illegal steps
451     auto call4 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
452     auto reply4 = ApiReplyInfo();
453     call4.paramList_.emplace_back(5);
454     call4.paramList_.emplace_back(0);
455     server.Call(call4, reply4);
456     ASSERT_EQ(ERR_INVALID_INPUT, reply4.exception_.code_);
457     ASSERT_TRUE(reply4.exception_.message_.find("Number of illegal steps") != string::npos);
458     // call with argument illegal fingers
459     auto call5 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
460     auto reply5 = ApiReplyInfo();
461     call5.paramList_.emplace_back(-1);
462     call5.paramList_.emplace_back(5);
463     server.Call(call5, reply5);
464     ASSERT_EQ(ERR_INVALID_INPUT, reply5.exception_.code_);
465     ASSERT_TRUE(reply5.exception_.message_.find("Number of illegal fingers") != string::npos);
466     // call with argument illegal fingers
467     auto call6 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
468     auto reply6 = ApiReplyInfo();
469     call6.paramList_.emplace_back(0);
470     call6.paramList_.emplace_back(5);
471     server.Call(call6, reply6);
472     ASSERT_EQ(ERR_INVALID_INPUT, reply6.exception_.code_);
473     ASSERT_TRUE(reply6.exception_.message_.find("Number of illegal fingers") != string::npos);
474 }
475 
TEST_F(FrontendApiHandlerTest,pointerMatrixparameterPreChecksOne)476 TEST_F(FrontendApiHandlerTest, pointerMatrixparameterPreChecksOne)
477 {
478     const auto& server =  FrontendApiServer::Get();
479     // call with argument illegal steps
480     auto call7 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
481     auto reply7 = ApiReplyInfo();
482     call7.paramList_.emplace_back(5);
483     call7.paramList_.emplace_back(-5);
484     server.Call(call7, reply7);
485     ASSERT_EQ(ERR_INVALID_INPUT, reply7.exception_.code_);
486     ASSERT_TRUE(reply7.exception_.message_.find("Number of illegal steps") != string::npos);
487     // call with argument illegal fingers
488     auto call10 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
489     auto reply10 = ApiReplyInfo();
490     call10.paramList_.emplace_back(6);
491     call10.paramList_.emplace_back(10);
492     server.Call(call10, reply10);
493     ASSERT_EQ(NO_ERROR, reply10.exception_.code_);
494     auto call11 = ApiCallInfo {.apiId_ = "PointerMatrix.setPoint", .callerObjRef_ = reply10.resultValue_.get<string>()};
495     call11.paramList_.emplace_back(6);
496     call11.paramList_.emplace_back(1);
497     auto arg1 = json();
498     arg1["x"] = 9;
499     arg1["y"] = 10;
500     call11.paramList_.emplace_back(arg1);
501     auto reply11 = ApiReplyInfo();
502     server.Call(call11, reply11);
503     ASSERT_EQ(ERR_INVALID_INPUT, reply11.exception_.code_);
504     ASSERT_TRUE(reply11.exception_.message_.find("Number of illegal fingers") != string::npos);
505     // call with argument illegal steps
506     auto call12 = ApiCallInfo {.apiId_ = "PointerMatrix.create"};
507     auto reply12 = ApiReplyInfo();
508     call12.paramList_.emplace_back(6);
509     call12.paramList_.emplace_back(10);
510     server.Call(call12, reply12);
511     ASSERT_EQ(NO_ERROR, reply12.exception_.code_);
512     auto call13 = ApiCallInfo {.apiId_ = "PointerMatrix.setPoint", .callerObjRef_ = reply12.resultValue_.get<string>()};
513     call13.paramList_.emplace_back(5);
514     call13.paramList_.emplace_back(11);
515     auto arg2 = json();
516     arg2["x"] = 9;
517     arg2["y"] = 10;
518     call13.paramList_.emplace_back(arg2);
519     auto reply13 = ApiReplyInfo();
520     server.Call(call13, reply13);
521     ASSERT_EQ(ERR_INVALID_INPUT, reply13.exception_.code_);
522     ASSERT_TRUE(reply13.exception_.message_.find("Number of illegal steps") != string::npos);
523 }
524 
TEST_F(FrontendApiHandlerTest,injectMultiPointerActionparameterPreChecks)525 TEST_F(FrontendApiHandlerTest, injectMultiPointerActionparameterPreChecks)
526 {
527     const auto& server =  FrontendApiServer::Get();
528     auto call2 = ApiCallInfo {.apiId_ = "UiDriver.create"};
529     auto reply2 = ApiReplyInfo();
530     server.Call(call2, reply2);
531     auto call3 = ApiCallInfo {.apiId_ = "UiDriver.fling", .callerObjRef_ = reply2.resultValue_.get<string>()};
532     auto from = json();
533     from["x"] = 30;
534     from["y"] = 40;
535     auto to = json();
536     to["x"] = 300;
537     to["y"] = 400;
538     call3.paramList_.emplace_back(from);
539     call3.paramList_.emplace_back(to);
540     call3.paramList_.emplace_back(0);
541     call3.paramList_.emplace_back(4000);
542     auto reply3 = ApiReplyInfo();
543     server.Call(call3, reply3);
544     ASSERT_EQ(USAGE_ERROR, reply3.exception_.code_);
545     ASSERT_TRUE(reply3.exception_.message_.find("The stepLen is out of range") != string::npos);
546 
547     auto call4 = ApiCallInfo {.apiId_ = "UiDriver.create"};
548     auto reply4 = ApiReplyInfo();
549     server.Call(call4, reply4);
550     auto call5 = ApiCallInfo {.apiId_ = "UiDriver.fling", .callerObjRef_ = reply4.resultValue_.get<string>()};
551     call5.paramList_.emplace_back(from);
552     call5.paramList_.emplace_back(to);
553     call5.paramList_.emplace_back(451);
554     call5.paramList_.emplace_back(4000);
555     auto reply5 = ApiReplyInfo();
556     server.Call(call5, reply5);
557     ASSERT_EQ(USAGE_ERROR, reply5.exception_.code_);
558     ASSERT_TRUE(reply5.exception_.message_.find("The stepLen is out of range") != string::npos);
559 
560     auto call6 = ApiCallInfo {.apiId_ = "UiDriver.create"};
561     auto reply6 = ApiReplyInfo();
562     server.Call(call6, reply6);
563     auto call7 = ApiCallInfo {.apiId_ = "UiDriver.fling", .callerObjRef_ = reply6.resultValue_.get<string>()};
564     auto from3 = json();
565     from3["x"] = "";
566     from3["y"] = "";
567     call7.paramList_.emplace_back(from3);
568     call7.paramList_.emplace_back(to);
569     call7.paramList_.emplace_back(500);
570     call7.paramList_.emplace_back(4000);
571     auto reply7 = ApiReplyInfo();
572     server.Call(call7, reply7);
573     ASSERT_EQ(USAGE_ERROR, reply7.exception_.code_);
574 }