1 /*
2  * Copyright (c) 2023 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 <gmock/gmock.h>
17 #include <gtest/gtest.h>
18 
19 #include "nweb_log.h"
20 #include "ohos_adapter_helper.h"
21 
22 #define private public
23 #include "imf_adapter_impl.h"
24 
25 using namespace testing;
26 using namespace testing::ext;
27 
28 namespace OHOS::NWeb {
29 namespace {
30 std::shared_ptr<IMFAdapterImpl> g_imf = nullptr;
31 } // namespace
32 
33 class NWebIMFAdapterTest : public testing::Test {
34 public:
35     static void SetUpTestCase(void);
36     static void TearDownTestCase(void);
37     void SetUp();
38     void TearDown();
39 };
40 
41 class IMFCursorInfoAdapterMock : public IMFCursorInfoAdapter {
42 public:
43     IMFCursorInfoAdapterMock() = default;
44 
45     ~IMFCursorInfoAdapterMock() override = default;
46 
GetLeft()47     double GetLeft() override
48     {
49         return 0.0;
50     }
51 
GetTop()52     double GetTop() override
53     {
54         return 0.0;
55     }
56 
GetWidth()57     double GetWidth() override
58     {
59         return 0.0;
60     }
61 
GetHeight()62     double GetHeight() override
63     {
64         return 0.0;
65     }
66 };
67 
68 class IMFInputAttributeAdapterMock : public IMFInputAttributeAdapter {
69 public:
70     IMFInputAttributeAdapterMock() = default;
71 
72     ~IMFInputAttributeAdapterMock() override = default;
73 
GetInputPattern()74     int32_t GetInputPattern() override
75     {
76         return 0;
77     }
78 
GetEnterKeyType()79     int32_t GetEnterKeyType() override
80     {
81         return 0;
82     }
83 };
84 
85 class IMFSelectionRangeAdapterMock : public IMFSelectionRangeAdapter {
86 public:
87     IMFSelectionRangeAdapterMock() = default;
88 
89     ~IMFSelectionRangeAdapterMock() override = default;
90 
GetStart()91     int32_t GetStart() override
92     {
93         return 0;
94     }
95 
GetEnd()96     int32_t GetEnd() override
97     {
98         return 0;
99     }
100 };
101 
102 class IMFTextConfigTest : public IMFTextConfigAdapter {
103 public:
104     IMFTextConfigTest() = default;
105     ~IMFTextConfigTest() override = default;
106 
GetInputAttribute()107     std::shared_ptr<IMFInputAttributeAdapter> GetInputAttribute()
108     {
109         auto mock = std::make_shared<IMFInputAttributeAdapterMock>();
110         return mock;
111     }
112 
GetCursorInfo()113     std::shared_ptr<IMFCursorInfoAdapter> GetCursorInfo()
114     {
115         auto mock = std::make_shared<IMFCursorInfoAdapterMock>();
116         return mock;
117     }
118 
GetSelectionRange()119     std::shared_ptr<IMFSelectionRangeAdapter> GetSelectionRange()
120     {
121         auto mock = std::make_shared<IMFSelectionRangeAdapterMock>();
122         return mock;
123     }
124 
GetWindowId()125     uint32_t GetWindowId()
126     {
127         WVLOG_I("test GetWindowId");
128         return 0;
129     }
130 
GetPositionY()131     double GetPositionY()
132     {
133         WVLOG_I("test GetPositionY");
134         return 0.0;
135     }
136 
GetHeight()137     double GetHeight()
138     {
139         WVLOG_I("test GetHeight");
140         return 0.0;
141     }
142 };
143 
144 class IMFTextListenerTest : public IMFTextListenerAdapter {
145 public:
146     IMFTextListenerTest() = default;
147     ~IMFTextListenerTest() override = default;
InsertText(const std::u16string & text)148     void InsertText(const std::u16string& text) override
149     {
150         WVLOG_I("test InsertText");
151         isInsertText_ = true;
152     }
DeleteForward(int32_t length)153     void DeleteForward(int32_t length) override
154     {
155         WVLOG_I("test DeleteForward");
156         isDeleteForward_ = true;
157     }
DeleteBackward(int32_t length)158     void DeleteBackward(int32_t length) override
159     {
160         WVLOG_I("test DeleteBackward");
161         isDeleteBackward_ = true;
162     }
SendKeyEventFromInputMethod()163     void SendKeyEventFromInputMethod() override
164     {
165         WVLOG_I("test SendKeyEventFromInputMethod");
166         isSendKeyEventFromInputMethod_ = true;
167     }
SendKeyboardStatus(const IMFAdapterKeyboardStatus & adapterKeyboardStatus)168     void SendKeyboardStatus(const IMFAdapterKeyboardStatus& adapterKeyboardStatus) override
169     {
170         WVLOG_I("test SendKeyboardStatus");
171         isSendKeyboardStatus_ = true;
172     }
SendFunctionKey(std::shared_ptr<IMFAdapterFunctionKeyAdapter> functionKey)173     void SendFunctionKey(std::shared_ptr<IMFAdapterFunctionKeyAdapter> functionKey) override
174     {
175         WVLOG_I("test SendFunctionKey");
176         isSendFunctionKey_ = true;
177     }
SetKeyboardStatus(bool status)178     void SetKeyboardStatus(bool status) override
179     {
180         WVLOG_I("test SetKeyboardStatus");
181         isSetKeyboardStatus_ = true;
182     }
MoveCursor(const IMFAdapterDirection direction)183     void MoveCursor(const IMFAdapterDirection direction) override
184     {
185         WVLOG_I("test MoveCursor");
186         isMoveCursor_ = true;
187     }
HandleSetSelection(int32_t start,int32_t end)188     void HandleSetSelection(int32_t start, int32_t end) override
189     {
190         WVLOG_I("test HandleSetSelection");
191         isHandleSetSelection_ = true;
192     }
HandleExtendAction(int32_t action)193     void HandleExtendAction(int32_t action) override
194     {
195         WVLOG_I("test HandleExtendAction");
196         isHandleExtendAction_ = true;
197     }
HandleSelect(int32_t keyCode,int32_t cursorMoveSkip)198     void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override
199     {
200         WVLOG_I("test HandleSelect");
201         isHandleSelect_ = true;
202     }
GetTextIndexAtCursor()203     int32_t GetTextIndexAtCursor() override
204     {
205         WVLOG_I("test GetTextIndexAtCursor");
206         isGetTextIndexAtCursor_ = true;
207         return 0;
208     }
GetLeftTextOfCursor(int32_t number)209     std::u16string GetLeftTextOfCursor(int32_t number) override
210     {
211         WVLOG_I("test GetLeftTextOfCursor");
212         isGetLeftTextOfCursor_ = true;
213         return u"";
214     }
GetRightTextOfCursor(int32_t number)215     std::u16string GetRightTextOfCursor(int32_t number) override
216     {
217         WVLOG_I("test GetRightTextOfCursor");
218         isGetRightTextOfCursor_ = true;
219         return u"";
220     }
SetPreviewText(const std::u16string & text,int32_t start,int32_t end)221     int32_t SetPreviewText(const std::u16string& text, int32_t start, int32_t end) override
222     {
223         WVLOG_I("test SetPreviewText");
224         isSetPreviewText_ = true;
225         return 0;
226     }
FinishTextPreview()227     void FinishTextPreview() override
228     {
229         WVLOG_I("test FinishTextPreview");
230         isFinishTextPreview_ = true;
231     }
SetNeedUnderLine(bool isNeedUnderline)232     void SetNeedUnderLine(bool isNeedUnderline) override
233     {
234         WVLOG_I("test SetNeedUnderLine");
235         isSetNeedUnderLine_ = true;
236     }
KeyboardUpperRightCornerHide()237     void KeyboardUpperRightCornerHide() override
238     {
239         WVLOG_I("test KeyboardUpperRightCornerHide");
240         isKeyboardUpperRightCornerHide_ = true;
241     }
VerifyAllSuccess()242     bool VerifyAllSuccess()
243     {
244         return isInsertText_ && isDeleteForward_ && isDeleteBackward_ && isSendKeyEventFromInputMethod_ &&
245                isSendKeyboardStatus_ && isSendFunctionKey_ && isSetKeyboardStatus_ && isMoveCursor_ &&
246                isHandleSetSelection_ && isHandleExtendAction_ && isHandleSelect_ && isGetTextIndexAtCursor_ &&
247                isGetLeftTextOfCursor_ && isGetRightTextOfCursor_ && isSetPreviewText_ && isFinishTextPreview_ &&
248                isSetNeedUnderLine_ && isKeyboardUpperRightCornerHide_;
249     }
VerifyFunctionKeySuccess()250     bool VerifyFunctionKeySuccess()
251     {
252         return isSendFunctionKey_;
253     }
254 private:
255     bool isInsertText_ = false;
256     bool isDeleteForward_ = false;
257     bool isDeleteBackward_ = false;
258     bool isSendKeyEventFromInputMethod_ = false;
259     bool isSendKeyboardStatus_ = false;
260     bool isSendFunctionKey_ = false;
261     bool isSetKeyboardStatus_ = false;
262     bool isMoveCursor_ = false;
263     bool isHandleSetSelection_ = false;
264     bool isHandleExtendAction_ = false;
265     bool isHandleSelect_ = false;
266     bool isGetTextIndexAtCursor_ = false;
267     bool isGetLeftTextOfCursor_ = false;
268     bool isGetRightTextOfCursor_ = false;
269     bool isSetPreviewText_ = false;
270     bool isFinishTextPreview_ = false;
271     bool isSetNeedUnderLine_ = false;
272     bool isKeyboardUpperRightCornerHide_ = false;
273 };
274 
SetUpTestCase(void)275 void NWebIMFAdapterTest::SetUpTestCase(void)
276 {
277     g_imf = std::make_unique<IMFAdapterImpl>();
278     ASSERT_NE(g_imf, nullptr);
279 }
280 
TearDownTestCase(void)281 void NWebIMFAdapterTest::TearDownTestCase(void) {}
282 
SetUp(void)283 void NWebIMFAdapterTest::SetUp(void) {}
284 
TearDown(void)285 void NWebIMFAdapterTest::TearDown(void) {}
286 
287 /**
288  * @tc.name: NWebIMFAdapterTest_IMFAdapterImpl_001.
289  * @tc.desc: IMF adapter unittest.
290  * @tc.type: FUNC.
291  * @tc.require:
292  */
293 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_IMFAdapterImpl_001, TestSize.Level1)
294 {
295     bool res = g_imf->Attach(nullptr, false);
296     EXPECT_EQ(g_imf->textListener_, nullptr);
297     EXPECT_FALSE(res);
298 }
299 
300 /**
301  * @tc.name: NWebIMFAdapterTest_IMFAdapterImpl_002.
302  * @tc.desc: IMF adapter unittest.
303  * @tc.type: FUNC.
304  * @tc.require:
305  */
306 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_IMFAdapterImpl_002, TestSize.Level1)
307 {
308     auto listener = std::make_shared<IMFTextListenerTest>();
309     bool res = g_imf->Attach(listener, true);
310     EXPECT_FALSE(res);
311     EXPECT_NE(g_imf->textListener_, nullptr);
312     g_imf->HideTextInput();
313 }
314 
315 /**
316  * @tc.name: NWebIMFAdapterTest_IMFAdapterImpl_003.
317  * @tc.desc: IMF adapter unittest.
318  * @tc.type: FUNC.
319  * @tc.require:
320  */
321 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_IMFAdapterImpl_003, TestSize.Level1)
322 {
323     auto listener = std::make_shared<IMFTextListenerTest>();
324     bool res = g_imf->Attach(listener, false);
325     EXPECT_FALSE(res);
326     EXPECT_NE(g_imf->textListener_, nullptr);
327     g_imf->ShowCurrentInput(IMFAdapterTextInputType::TEXT);
328     g_imf->ShowCurrentInput(IMFAdapterTextInputType::NUMBER);
329     g_imf->HideTextInput();
330 }
331 
332 /**
333  * @tc.name: NWebIMFAdapterTest_IMFAdapterImpl_004.
334  * @tc.desc: IMF adapter unittest.
335  * @tc.type: FUNC.
336  * @tc.require:
337  */
338 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_IMFAdapterImpl_004, TestSize.Level1)
339 {
340     EXPECT_NE(g_imf, nullptr);
341     g_imf->OnCursorUpdate(nullptr);
342     std::u16string text;
343     g_imf->OnSelectionChange(text, 0, 0);
344     g_imf->Close();
345     auto mock = std::make_shared<IMFCursorInfoAdapterMock>();
346     g_imf->OnCursorUpdate(mock);
347 }
348 
349 /**
350  * @tc.name: NWebIMFAdapterTest_IMFAdapterImpl_005.
351  * @tc.desc: IMF adapter unittest.
352  * @tc.type: FUNC.
353  * @tc.require:
354  */
355 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_IMFAdapterImpl_005, TestSize.Level1)
356 {
357     auto imf_adapter = OhosAdapterHelper::GetInstance().CreateMMIAdapter();
358     EXPECT_NE(imf_adapter, nullptr);
359     auto listener = std::make_shared<IMFTextListenerTest>();
360     auto listenerTest = std::make_shared<IMFTextListenerAdapterImpl>(listener);
361     std::u16string text;
362     MiscServices::KeyEvent event;
363     MiscServices::FunctionKey functionKey;
364     listenerTest->InsertText(text);
365     listenerTest->DeleteForward(0);
366     listenerTest->DeleteBackward(0);
367     listenerTest->SendKeyEventFromInputMethod(event);
368     listenerTest->SendKeyboardStatus(MiscServices::KeyboardStatus::SHOW);
369     listenerTest->SendFunctionKey(functionKey);
370     listenerTest->SetKeyboardStatus(true);
371 
372     listenerTest->MoveCursor(MiscServices::Direction::NONE);
373     listenerTest->MoveCursor(MiscServices::Direction::UP);
374     listenerTest->MoveCursor(MiscServices::Direction::DOWN);
375     listenerTest->MoveCursor(MiscServices::Direction::LEFT);
376     listenerTest->MoveCursor(MiscServices::Direction::RIGHT);
377     listenerTest->HandleSetSelection(0, 0);
378     listenerTest->HandleExtendAction(0);
379     listenerTest->HandleSelect(0, 0);
380     listenerTest->GetTextIndexAtCursor();
381     listenerTest->GetLeftTextOfCursor(0);
382     listenerTest->GetRightTextOfCursor(0);
383     MiscServices::Range range { 0, 0 };
384     listenerTest->SetPreviewText(text, range);
385     listenerTest->FinishTextPreview();
386     const std::unordered_map<std::string, MiscServices::PrivateDataValue> privateCommand;
387     listenerTest->ReceivePrivateCommand(privateCommand);
388 }
389 
390 /**
391  * @tc.name: NWebIMFAdapterTest_IMFAdapterImpl_006.
392  * @tc.desc: IMF adapter unittest.
393  * @tc.type: FUNC.
394  * @tc.require:
395  */
396 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_IMFAdapterImpl_006, TestSize.Level1)
397 {
398     auto imf_adapter = OhosAdapterHelper::GetInstance().CreateMMIAdapter();
399     EXPECT_NE(imf_adapter, nullptr);
400     auto listener = std::make_shared<IMFTextListenerTest>();
401     auto listenerTest = std::make_shared<IMFTextListenerAdapterImpl>(listener);
402     MiscServices::FunctionKey functionKey;
403     listenerTest->SendFunctionKey(functionKey);
404     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::UNSPECIFIED);
405     listenerTest->SendFunctionKey(functionKey);
406     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::NONE);
407     listenerTest->SendFunctionKey(functionKey);
408     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::GO);
409     listenerTest->SendFunctionKey(functionKey);
410     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::SEARCH);
411     listenerTest->SendFunctionKey(functionKey);
412     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::SEND);
413     listenerTest->SendFunctionKey(functionKey);
414     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::NEXT);
415     listenerTest->SendFunctionKey(functionKey);
416     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::DONE);
417     listenerTest->SendFunctionKey(functionKey);
418     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::PREVIOUS);
419     listenerTest->SendFunctionKey(functionKey);
420     functionKey.SetEnterKeyType(MiscServices::EnterKeyType::NEW_LINE);
421     listenerTest->SendFunctionKey(functionKey);
422     EXPECT_EQ(listener->VerifyFunctionKeySuccess(), true);
423 }
424 
425 /**
426  * @tc.name: NWebIMFAdapterTest_InsertText_007.
427  * @tc.desc: IMF adapter unittest.
428  * @tc.type: FUNC.
429  * @tc.require:
430  */
431 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_InsertText_007, TestSize.Level1)
432 {
433     auto listenerTest = std::make_shared<IMFTextListenerAdapterImpl>(nullptr);
434     EXPECT_NE(listenerTest, nullptr);
435     std::u16string text;
436     MiscServices::KeyEvent event;
437     MiscServices::FunctionKey functionKey;
438     listenerTest->InsertText(text);
439     listenerTest->DeleteForward(0);
440     listenerTest->DeleteBackward(0);
441     listenerTest->SendKeyEventFromInputMethod(event);
442     listenerTest->SendKeyboardStatus(MiscServices::KeyboardStatus::SHOW);
443     listenerTest->SendFunctionKey(functionKey);
444     listenerTest->SetKeyboardStatus(true);
445     listenerTest->MoveCursor(MiscServices::Direction::NONE);
446     listenerTest->HandleSetSelection(0, 0);
447     listenerTest->HandleExtendAction(0);
448     listenerTest->HandleSelect(0, 0);
449     listenerTest->GetTextIndexAtCursor();
450     listenerTest->GetLeftTextOfCursor(0);
451     listenerTest->GetRightTextOfCursor(0);
452     MiscServices::Range range { 0, 0 };
453     listenerTest->SetPreviewText(text, range);
454     listenerTest->FinishTextPreview();
455     const std::unordered_map<std::string, MiscServices::PrivateDataValue> privateCommand;
456     listenerTest->ReceivePrivateCommand(privateCommand);
457 }
458 
459 /**
460  * @tc.name: NWebIMFAdapterTest_InsertText_008.
461  * @tc.desc: IMF adapter unittest.
462  * @tc.type: FUNC.
463  * @tc.require:
464  */
465 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_InsertText_008, TestSize.Level1)
466 {
467     bool result = g_imf->Attach(nullptr, true, nullptr, false);
468     EXPECT_FALSE(result);
469     auto listener = std::make_shared<IMFTextListenerTest>();
470     EXPECT_NE(listener, nullptr);
471     result = g_imf->Attach(nullptr, true, nullptr, false);
472     EXPECT_FALSE(result);
473     result = g_imf->Attach(nullptr, true, nullptr, false);
474     EXPECT_FALSE(result);
475 }
476 
477 /**
478  * @tc.name: NWebIMFAdapterTest_IMFAdapterImpl_009.
479  * @tc.desc: IMF adapter unittest.
480  * @tc.type: FUNC.
481  * @tc.require:
482  */
483 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_IMFAdapterImpl_009, TestSize.Level1)
484 {
485     auto imf_adapter = OhosAdapterHelper::GetInstance().CreateMMIAdapter();
486     EXPECT_NE(imf_adapter, nullptr);
487     auto listener = std::make_shared<IMFTextListenerTest>();
488     auto listenerTest = std::make_shared<IMFTextListenerAdapterImpl>(listener);
489     std::unordered_map<std::string, MiscServices::PrivateDataValue> privateCommand;
490     privateCommand = { { "test", "test" } };
491     listenerTest->ReceivePrivateCommand(privateCommand);
492     privateCommand = { { "previewTextStyle", "underline" } };
493     listenerTest->ReceivePrivateCommand(privateCommand);
494     privateCommand = { { "com.autofill.params.userName", "test" } };
495     listenerTest->ReceivePrivateCommand(privateCommand);
496     privateCommand = { { "com.autofill.params.otherAccount", true } };
497     listenerTest->ReceivePrivateCommand(privateCommand);
498 }
499 
500 /**
501  * @tc.name: NWebIMFAdapterTest_InsertText_010.
502  * @tc.desc: IMF adapter unittest.
503  * @tc.type: FUNC.
504  * @tc.require:
505  */
506 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_InsertText_010, TestSize.Level1)
507 {
508     auto listener = std::make_shared<IMFTextListenerTest>();
509     auto config = std::make_shared<IMFTextConfigTest>();
510     bool result = g_imf->Attach(listener, true, nullptr, false);
511     EXPECT_FALSE(result);
512 
513     result = g_imf->Attach(listener, true, config, false);
514     EXPECT_FALSE(result);
515     EXPECT_NE(g_imf->textListener_, nullptr);
516     g_imf->HideTextInput();
517 }
518 
519 /**
520  * @tc.name: NWebIMFAdapterTest_InsertText_011.
521  * @tc.desc: IMF adapter unittest.
522  * @tc.type: FUNC.
523  * @tc.require:
524  */
525 HWTEST_F(NWebIMFAdapterTest, NWebIMFAdapterTest_InsertText_011, TestSize.Level1)
526 {
527     EXPECT_NE(g_imf, nullptr);
528     std::string commandKey = "autofill.cancel";
529     std::string commandValue = "{\"userName\":\"test\",\"hasAccount\":\"test\"}";
530     g_imf->SendPrivateCommand(commandKey, commandValue);
531     commandKey = "test";
532     g_imf->SendPrivateCommand(commandKey, commandValue);
533 }
534 
535 } // namespace OHOS::NWeb
536