• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 "input_method_ability.h"
17 
18 #include <gtest/gtest.h>
19 #include <string_ex.h>
20 #include <unistd.h>
21 
22 #include <cstdint>
23 #include <functional>
24 #include <string>
25 #include <thread>
26 #include <vector>
27 
28 #include "accesstoken_kit.h"
29 #include "global.h"
30 #include "i_input_data_channel.h"
31 #include "input_attribute.h"
32 #include "input_control_channel_stub.h"
33 #include "input_data_channel_proxy.h"
34 #include "input_data_channel_stub.h"
35 #include "input_method_agent_stub.h"
36 #include "input_method_controller.h"
37 #include "input_method_core_proxy.h"
38 #include "input_method_core_stub.h"
39 #include "input_method_property.h"
40 #include "message_handler.h"
41 #include "nativetoken_kit.h"
42 #include "os_account_manager.h"
43 #include "token_setproc.h"
44 
45 using namespace testing::ext;
46 using namespace OHOS::Security::AccessToken;
47 using namespace OHOS::AccountSA;
48 namespace OHOS {
49 namespace MiscServices {
50 constexpr uint32_t DEALY_TIME = 1;
51 constexpr int32_t MAIN_USER_ID = 100;
52 std::u16string g_textTemp = u"我們我們ddddd";
53 class InputMethodAbilityTest : public testing::Test {
54 public:
55     static std::string imeIdStopped_;
56     static std::mutex imeListenerCallbackLock_;
57     static std::condition_variable imeListenerCv_;
58     static bool showKeyboard_;
59     static std::mutex textListenerCallbackLock_;
60     static std::condition_variable textListenerCv_;
61     static int direction_;
62     static int deleteForwardLength_;
63     static int deleteBackwardLength_;
64     static std::u16string insertText_;
65     static int key_;
66     static int keyboardStatus_;
67     static bool status_;
68     static sptr<InputMethodController> imc_;
69     static sptr<InputMethodAbility> inputMethodAbility_;
70 
71     class InputMethodEngineListenerImpl : public InputMethodEngineListener {
72     public:
73         InputMethodEngineListenerImpl() = default;
74         ~InputMethodEngineListenerImpl() = default;
75 
OnKeyboardStatus(bool isShow)76         void OnKeyboardStatus(bool isShow)
77         {
78             showKeyboard_ = isShow;
79             InputMethodAbilityTest::imeListenerCv_.notify_one();
80             IMSA_HILOGI("InputMethodEngineListenerImpl OnKeyboardStatus");
81         }
82 
OnInputStart()83         void OnInputStart()
84         {
85             IMSA_HILOGI("InputMethodEngineListenerImpl OnInputStart");
86         }
87 
OnInputStop(const std::string & imeId)88         void OnInputStop(const std::string &imeId)
89         {
90             imeIdStopped_ = imeId;
91             IMSA_HILOGI("InputMethodEngineListenerImpl OnInputStop");
92         }
93 
OnSetCallingWindow(uint32_t windowId)94         void OnSetCallingWindow(uint32_t windowId)
95         {
96             IMSA_HILOGI("InputMethodEngineListenerImpl OnSetCallingWindow");
97         }
98 
OnSetSubtype(const SubProperty & property)99         void OnSetSubtype(const SubProperty &property)
100         {
101             IMSA_HILOGI("InputMethodEngineListenerImpl OnSetSubtype");
102         }
103     };
104     class TextChangeListener : public OnTextChangedListener {
105     public:
InsertText(const std::u16string & text)106         void InsertText(const std::u16string &text) override
107         {
108             insertText_ = text;
109             InputMethodAbilityTest::textListenerCv_.notify_one();
110         }
111 
DeleteForward(int32_t length)112         void DeleteForward(int32_t length) override
113         {
114             deleteForwardLength_ = length;
115             InputMethodAbilityTest::textListenerCv_.notify_one();
116             IMSA_HILOGI("TextChangeListener: DeleteForward, length is: %{public}d", length);
117         }
118 
DeleteBackward(int32_t length)119         void DeleteBackward(int32_t length) override
120         {
121             deleteBackwardLength_ = length;
122             InputMethodAbilityTest::textListenerCv_.notify_one();
123             IMSA_HILOGI("TextChangeListener: DeleteBackward, direction is: %{public}d", length);
124         }
125 
SendKeyEventFromInputMethod(const KeyEvent & event)126         void SendKeyEventFromInputMethod(const KeyEvent &event) override
127         {
128         }
129 
SendKeyboardInfo(const KeyboardInfo & info)130         void SendKeyboardInfo(const KeyboardInfo &info) override
131         {
132             FunctionKey functionKey = info.GetFunctionKey();
133             KeyboardStatus keyboardStatus = info.GetKeyboardStatus();
134             key_ = (int)functionKey;
135             keyboardStatus_ = (int)keyboardStatus;
136             InputMethodAbilityTest::textListenerCv_.notify_one();
137         }
138 
SetKeyboardStatus(bool status)139         void SetKeyboardStatus(bool status) override
140         {
141             status_ = status;
142         }
143 
MoveCursor(const Direction direction)144         void MoveCursor(const Direction direction) override
145         {
146             direction_ = (int)direction;
147             InputMethodAbilityTest::textListenerCv_.notify_one();
148             IMSA_HILOGI("TextChangeListener: MoveCursor, direction is: %{public}d", direction);
149         }
HandleSetSelection(int32_t start,int32_t end)150         void HandleSetSelection(int32_t start, int32_t end) override
151         {
152         }
HandleExtendAction(int32_t action)153         void HandleExtendAction(int32_t action) override
154         {
155         }
HandleSelect(int32_t keyCode,int32_t cursorMoveSkip)156         void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override
157         {
158         }
159     };
InitTestConfiguration(const std::string & bundleName)160     static void InitTestConfiguration(const std::string &bundleName)
161     {
162         IMSA_HILOGI("bundleName: %{public}s", bundleName.c_str());
163         std::vector<int32_t> userIds;
164         auto ret = OsAccountManager::QueryActiveOsAccountIds(userIds);
165         if (ret != ErrorCode::NO_ERROR || userIds.empty()) {
166             IMSA_HILOGE("query active os account id failed");
167             userIds[0] = MAIN_USER_ID;
168         }
169         HapInfoParams infoParams = {
170             .userID = userIds[0],
171             .bundleName = bundleName,
172             .instIndex = 0,
173             .appIDDesc = "ohos.inputmethod_test.demo"
174         };
175         HapPolicyParams policyParams = {
176             .apl = APL_NORMAL,
177             .domain = "test.domain.inputmethod",
178             .permList = {},
179             .permStateList = {}
180         };
181         AccessTokenKit::AllocHapToken(infoParams, policyParams);
182         auto tokenID = AccessTokenKit::GetHapTokenID(infoParams.userID, infoParams.bundleName, infoParams.instIndex);
183         int res = SetSelfTokenID(tokenID);
184         if (res == ErrorCode::NO_ERROR) {
185             IMSA_HILOGI("SetSelfTokenID success!");
186         } else {
187             IMSA_HILOGE("SetSelfTokenID fail!");
188         }
189     }
SetUpTestCase(void)190     static void SetUpTestCase(void)
191     {
192         IMSA_HILOGI("InputMethodAbilityTest::SetUpTestCase");
193         std::shared_ptr<Property> property = InputMethodController::GetInstance()->GetCurrentInputMethod();
194         std::string currImeBundleName = property != nullptr ? property->name : "default.inputmethod.unittest";
195         InitTestConfiguration(currImeBundleName);
196         inputMethodAbility_ = InputMethodAbility::GetInstance();
197         inputMethodAbility_->OnImeReady();
198         inputMethodAbility_->SetCoreAndAgent();
199         sptr<OnTextChangedListener> textListener = new TextChangeListener();
200         imc_ = InputMethodController::GetInstance();
201         imc_->Attach(textListener);
202     }
TearDownTestCase(void)203     static void TearDownTestCase(void)
204     {
205         IMSA_HILOGI("InputMethodAbilityTest::TearDownTestCase");
206         imc_->Close();
207     }
SetUp()208     void SetUp()
209     {
210         IMSA_HILOGI("InputMethodAbilityTest::SetUp");
211     }
TearDown()212     void TearDown()
213     {
214         IMSA_HILOGI("InputMethodAbilityTest::TearDown");
215     }
216 };
217 
218 std::string InputMethodAbilityTest::imeIdStopped_;
219 std::mutex InputMethodAbilityTest::imeListenerCallbackLock_;
220 std::condition_variable InputMethodAbilityTest::imeListenerCv_;
221 bool InputMethodAbilityTest::showKeyboard_ = true;
222 std::mutex InputMethodAbilityTest::textListenerCallbackLock_;
223 std::condition_variable InputMethodAbilityTest::textListenerCv_;
224 int InputMethodAbilityTest::direction_;
225 int InputMethodAbilityTest::deleteForwardLength_ = 0;
226 int InputMethodAbilityTest::deleteBackwardLength_ = 0;
227 std::u16string InputMethodAbilityTest::insertText_;
228 int InputMethodAbilityTest::key_ = 0;
229 int InputMethodAbilityTest::keyboardStatus_;
230 bool InputMethodAbilityTest::status_;
231 sptr<InputMethodController> InputMethodAbilityTest::imc_;
232 sptr<InputMethodAbility> InputMethodAbilityTest::inputMethodAbility_;
233 
234 /**
235 * @tc.name: testSerializedInputAttribute
236 * @tc.desc: Checkout the serialization of InputAttribute.
237 * @tc.type: FUNC
238 */
239 HWTEST_F(InputMethodAbilityTest, testSerializedInputAttribute, TestSize.Level0)
240 {
241     InputAttribute inAttribute;
242     inAttribute.inputPattern = InputAttribute::PATTERN_PASSWORD;
243     MessageParcel data;
244     EXPECT_TRUE(InputAttribute::Marshalling(inAttribute, data));
245     InputAttribute outAttribute;
246     EXPECT_TRUE(InputAttribute::Unmarshalling(outAttribute, data));
247     EXPECT_TRUE(outAttribute.GetSecurityFlag());
248 }
249 
250 /**
251 * @tc.name: testShowKeyboardInputMethodCoreProxy
252 * @tc.desc: Test InputMethodCoreProxy ShowKeyboard
253 * @tc.type: FUNC
254 * @tc.require: issueI5NXHK
255 */
256 HWTEST_F(InputMethodAbilityTest, testShowKeyboardInputMethodCoreProxy, TestSize.Level0)
257 {
258     sptr<InputMethodCoreStub> coreStub = new InputMethodCoreStub(0);
259     sptr<IInputMethodCore> core = coreStub;
260     auto msgHandler = new (std::nothrow) MessageHandler();
261     coreStub->SetMessageHandler(msgHandler);
262     sptr<InputDataChannelStub> channelStub = new InputDataChannelStub();
263 
264     MessageParcel data;
265     data.WriteRemoteObject(core->AsObject());
266     data.WriteRemoteObject(channelStub->AsObject());
267     sptr<IRemoteObject> coreObject = data.ReadRemoteObject();
268     sptr<IRemoteObject> channelObject = data.ReadRemoteObject();
269 
270     sptr<InputMethodCoreProxy> coreProxy = new InputMethodCoreProxy(coreObject);
271     sptr<InputDataChannelProxy> channelProxy = new InputDataChannelProxy(channelObject);
272     SubProperty subProperty;
273     auto ret = coreProxy->showKeyboard(channelProxy, false, subProperty);
274     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::imeListenerCallbackLock_);
275     auto cvStatus = InputMethodAbilityTest::imeListenerCv_.wait_for(lock, std::chrono::seconds(DEALY_TIME));
276     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
277     EXPECT_EQ(cvStatus, std::cv_status::timeout);
278     EXPECT_TRUE(InputMethodAbilityTest::showKeyboard_);
279     delete msgHandler;
280 }
281 
282 /**
283 * @tc.name: testHideKeyboardSelfWithoutImeListener
284 * @tc.desc: InputMethodAbility HideKeyboardSelf Without ImeListener
285 * @tc.type: FUNC
286 * @tc.require:
287 * @tc.author: Hollokin
288 */
289 HWTEST_F(InputMethodAbilityTest, testHideKeyboardSelfWithoutImeListener, TestSize.Level0)
290 {
291     IMSA_HILOGI("InputMethodAbility testHideKeyboardSelfWithoutImeListener START");
292     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::imeListenerCallbackLock_);
293     InputMethodAbilityTest::showKeyboard_ = true;
294     auto ret = inputMethodAbility_->HideKeyboardSelf();
295     auto cvStatus = imeListenerCv_.wait_for(lock, std::chrono::seconds(DEALY_TIME));
296     EXPECT_EQ(cvStatus, std::cv_status::timeout);
297     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
298     EXPECT_TRUE(InputMethodAbilityTest::showKeyboard_);
299 }
300 
301 /**
302 * @tc.name: testHideKeyboardSelf
303 * @tc.desc: InputMethodAbility HideKeyboardSelf
304 * @tc.type: FUNC
305 * @tc.require:
306 * @tc.author: Hollokin
307 */
308 HWTEST_F(InputMethodAbilityTest, testHideKeyboardSelf, TestSize.Level0)
309 {
310     IMSA_HILOGI("InputMethodAbility testHideKeyboardSelf START");
311     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::imeListenerCallbackLock_);
312     InputMethodAbilityTest::showKeyboard_ = true;
313     inputMethodAbility_->setImeListener(std::make_shared<InputMethodEngineListenerImpl>());
314     auto ret = inputMethodAbility_->HideKeyboardSelf();
315     InputMethodAbilityTest::imeListenerCv_.wait_for(
__anon1252d5fd0102null316         lock, std::chrono::seconds(DEALY_TIME), [] { return InputMethodAbilityTest::showKeyboard_ == false; });
317     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
318     EXPECT_FALSE(InputMethodAbilityTest::showKeyboard_);
319 }
320 
321 /**
322 * @tc.name: testMoveCursor
323 * @tc.desc: InputMethodAbility MoveCursor
324 * @tc.type: FUNC
325 * @tc.require:
326 * @tc.author: Hollokin
327 */
328 HWTEST_F(InputMethodAbilityTest, testMoveCursor, TestSize.Level0)
329 {
330     IMSA_HILOGI("InputMethodAbility MoveCursor Test START");
331     constexpr int32_t keyCode = 4;
332     auto ret = inputMethodAbility_->MoveCursor(keyCode); // move cursor right
333     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::textListenerCallbackLock_);
334     InputMethodAbilityTest::textListenerCv_.wait_for(
__anon1252d5fd0202null335         lock, std::chrono::seconds(DEALY_TIME), [] { return InputMethodAbilityTest::direction_ == keyCode; });
336     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
337     EXPECT_EQ(InputMethodAbilityTest::direction_, keyCode);
338 }
339 
340 /**
341 * @tc.name: testInsertText
342 * @tc.desc: InputMethodAbility InsertText
343 * @tc.type: FUNC
344 * @tc.require:
345 * @tc.author: Hollokin
346 */
347 HWTEST_F(InputMethodAbilityTest, testInsertText, TestSize.Level0)
348 {
349     IMSA_HILOGI("InputMethodAbility InsertText Test START");
350     std::string text = "text";
351     std::u16string u16Text = Str8ToStr16(text);
352     auto ret = inputMethodAbility_->InsertText(text);
353     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::textListenerCallbackLock_);
354     InputMethodAbilityTest::textListenerCv_.wait_for(
__anon1252d5fd0302null355         lock, std::chrono::seconds(DEALY_TIME), [u16Text] { return InputMethodAbilityTest::insertText_ == u16Text; });
356     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
357     EXPECT_EQ(InputMethodAbilityTest::insertText_, u16Text);
358 }
359 
360 /**
361 * @tc.name: testSendFunctionKey
362 * @tc.desc: InputMethodAbility SendFunctionKey
363 * @tc.type: FUNC
364 * @tc.require:
365 * @tc.author: Hollokin
366 */
367 HWTEST_F(InputMethodAbilityTest, testSendFunctionKey, TestSize.Level0)
368 {
369     IMSA_HILOGI("InputMethodAbility SendFunctionKey Test START");
370     constexpr int32_t funcKey = 1;
371     auto ret = inputMethodAbility_->SendFunctionKey(funcKey);
372     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::textListenerCallbackLock_);
373     InputMethodAbilityTest::textListenerCv_.wait_for(
__anon1252d5fd0402null374         lock, std::chrono::seconds(DEALY_TIME), [] { return InputMethodAbilityTest::key_ == funcKey; });
375     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
376     EXPECT_EQ(InputMethodAbilityTest::key_, funcKey);
377 }
378 
379 /**
380 * @tc.name: testDeleteText
381 * @tc.desc: InputMethodAbility DeleteForward & DeleteBackward
382 * @tc.type: FUNC
383 * @tc.require:
384 * @tc.author: Hollokin
385 */
386 HWTEST_F(InputMethodAbilityTest, testDeleteText, TestSize.Level0)
387 {
388     IMSA_HILOGI("InputMethodAbility testDelete Test START");
389     int32_t deleteForwardLenth = 1;
390     auto ret = inputMethodAbility_->DeleteForward(deleteForwardLenth);
391     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::textListenerCallbackLock_);
392     InputMethodAbilityTest::textListenerCv_.wait_for(lock, std::chrono::seconds(DEALY_TIME),
__anon1252d5fd0502null393         [deleteForwardLenth] { return InputMethodAbilityTest::deleteForwardLength_ == deleteForwardLenth; });
394     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
395     EXPECT_EQ(InputMethodAbilityTest::deleteForwardLength_, deleteForwardLenth);
396 
397     int32_t deleteBackwardLenth = 2;
398     ret = inputMethodAbility_->DeleteBackward(deleteBackwardLenth);
399     InputMethodAbilityTest::textListenerCv_.wait_for(lock, std::chrono::seconds(DEALY_TIME),
__anon1252d5fd0602null400         [deleteBackwardLenth] { return InputMethodAbilityTest::deleteBackwardLength_ == deleteBackwardLenth; });
401     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
402     EXPECT_EQ(InputMethodAbilityTest::deleteBackwardLength_, deleteBackwardLenth);
403 }
404 
405 /**
406 * @tc.name: testGetEnterKeyType
407 * @tc.desc: InputMethodAbility GetEnterKeyType & GetInputPattern
408 * @tc.type: FUNC
409 * @tc.require:
410 * @tc.author: Hollokin
411 */
412 HWTEST_F(InputMethodAbilityTest, testGetEnterKeyType, TestSize.Level0)
413 {
414     IMSA_HILOGI("InputMethodAbility testGetEnterKeyType START");
415     Configuration config;
416     EnterKeyType keyType = EnterKeyType::NEXT;
417     config.SetEnterKeyType(keyType);
418     TextInputType textInputType = TextInputType::DATETIME;
419     config.SetTextInputType(textInputType);
420     imc_->OnConfigurationChange(config);
421     int32_t keyType2;
422     auto ret = inputMethodAbility_->GetEnterKeyType(keyType2);
423     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
424     EXPECT_EQ(keyType2, (int)keyType);
425     int32_t inputPattern;
426     ret = inputMethodAbility_->GetInputPattern(inputPattern);
427     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
428     EXPECT_EQ(inputPattern, (int)textInputType);
429 }
430 
431 /**
432 * @tc.name: testGetTextParamExceptionValidation_001
433 * @tc.desc: mSelectNewBegin = mSelectNewEnd> size()
434 * @tc.type: FUNC
435 * @tc.require: issuesI6PPJM
436 */
437 HWTEST_F(InputMethodAbilityTest, testGetTextParamExceptionValidation_001, TestSize.Level0)
438 {
439     IMSA_HILOGI("InputMethodAbility testGetTextParamExceptionValidation_001 START");
440     int32_t start = 10;
441     int32_t end = 10;
442     imc_->OnSelectionChange(g_textTemp, start, end);
443     int32_t number = 3;
444     std::u16string text;
445     auto ret = inputMethodAbility_->GetTextAfterCursor(number, text);
446     EXPECT_EQ(ret, ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED);
447     EXPECT_EQ(text, u"");
448     ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
449     EXPECT_EQ(ret, ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED);
450     EXPECT_EQ(text, u"");
451 }
452 
453 /**
454 * @tc.name: testGetTextParamExceptionValidation_002
455 * @tc.desc: mSelectNewBegin > mSelectNewEnd, mSelectNewBegin > size()
456 * @tc.type: FUNC
457 * @tc.require: issuesI6PPJM
458 */
459 HWTEST_F(InputMethodAbilityTest, testGetTextParamExceptionValidation_002, TestSize.Level0)
460 {
461     IMSA_HILOGI("InputMethodAbility testGetTextParamExceptionValidation_002 START");
462     int32_t start = 11;
463     int32_t end = 9;
464     imc_->OnSelectionChange(g_textTemp, start, end);
465     int32_t number = 3;
466     std::u16string text;
467     auto ret = inputMethodAbility_->GetTextAfterCursor(number, text);
468     EXPECT_EQ(ret, ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED);
469     EXPECT_EQ(text, u"");
470     ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
471     EXPECT_EQ(ret, ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED);
472     EXPECT_EQ(text, u"");
473 }
474 
475 /**
476 * @tc.name: testGetTextParamExceptionValidation_003
477 * @tc.desc: mSelectNewBegin < mSelectNewEnd, mSelectNewEnd > size()
478 * @tc.type: FUNC
479 * @tc.require: issuesI6PPJM
480 */
481 HWTEST_F(InputMethodAbilityTest, testGetTextParamExceptionValidation_003, TestSize.Level0)
482 {
483     IMSA_HILOGI("InputMethodAbility testGetTextParamExceptionValidation_003 START");
484     int32_t start = 9;
485     int32_t end = 11;
486     imc_->OnSelectionChange(g_textTemp, start, end);
487     int32_t number = 3;
488     std::u16string text;
489     auto ret = inputMethodAbility_->GetTextAfterCursor(number, text);
490     EXPECT_EQ(ret, ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED);
491     EXPECT_EQ(text, u"");
492     ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
493     EXPECT_EQ(ret, ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED);
494     EXPECT_EQ(text, u"");
495 }
496 
497 /**
498 * @tc.name: testGetTextAfterCursor_001
499 * @tc.desc: click textfield, mSelectNewEnd + number > size()
500 * @tc.type: FUNC
501 * @tc.require: issuesI6PPJM
502 */
503 HWTEST_F(InputMethodAbilityTest, testGetTextAfterCursor_001, TestSize.Level0)
504 {
505     IMSA_HILOGI("InputMethodAbility testGetTextAfterCursor_001 START");
506     int32_t start = 8;
507     int32_t end = 8;
508     imc_->OnSelectionChange(g_textTemp, start, end);
509     int32_t number = 3;
510     std::u16string text;
511     auto ret = inputMethodAbility_->GetTextAfterCursor(number, text);
512     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
513     EXPECT_EQ(text, u"d");
514 }
515 
516 /**
517 * @tc.name: testGetTextAfterCursor_002
518 * @tc.desc: Select forward, mSelectNewBegin/mSelectNewEnd + number == size()
519 * @tc.type: FUNC
520 * @tc.require: issuesI6PPJM
521 */
522 HWTEST_F(InputMethodAbilityTest, testGetTextAfterCursor_002, TestSize.Level0)
523 {
524     IMSA_HILOGI("InputMethodAbility testGetTextAfterCursor_002 START");
525     // implemented correctly: mSelectNewBegin > mSelectNewEnd
526     int32_t start = 7;
527     int32_t end = 4;
528     imc_->OnSelectionChange(g_textTemp, start, end);
529     int32_t number = 2;
530     std::u16string text;
531     auto ret = inputMethodAbility_->GetTextAfterCursor(number, text);
532     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
533     EXPECT_EQ(text, u"dd");
534 
535     // implemented Currently: mSelectNewBegin < mSelectNewEnd
536     start = 4;
537     end = 7;
538     imc_->OnSelectionChange(g_textTemp, start, end);
539     number = 2;
540     ret = inputMethodAbility_->GetTextAfterCursor(number, text);
541     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
542     EXPECT_EQ(text, u"dd");
543 }
544 
545 /**
546 * @tc.name: testGetTextAfterCursor_003
547 * @tc.desc: Select backward, mSelectNewEnd + number < size()
548 * @tc.type: FUNC
549 * @tc.require: issuesI6PPJM
550 */
551 HWTEST_F(InputMethodAbilityTest, testGetTextAfterCursor_003, TestSize.Level0)
552 {
553     IMSA_HILOGI("InputMethodAbility testGetTextAfterCursor_003 START");
554     int32_t start = 4;
555     int32_t end = 5;
556     imc_->OnSelectionChange(g_textTemp, start, end);
557     int32_t number = 3;
558     std::u16string text;
559     auto ret = inputMethodAbility_->GetTextAfterCursor(number, text);
560     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
561     EXPECT_EQ(text, u"ddd");
562 }
563 
564 /**
565 * @tc.name: testGetTextBeforeCursor_001
566 * @tc.desc: click textfield, mSelectNewBegin > number
567 * @tc.type: FUNC
568 * @tc.require: issuesI6PPJM
569 */
570 HWTEST_F(InputMethodAbilityTest, testGetTextBeforeCursor_001, TestSize.Level0)
571 {
572     IMSA_HILOGI("InputMethodAbility testGetTextBeforeCursor_001 START");
573     int32_t start = 6;
574     int32_t end = 6;
575     imc_->OnSelectionChange(g_textTemp, start, end);
576     int32_t number = 3;
577     std::u16string text;
578     auto ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
579     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
580     EXPECT_EQ(text, u"們dd");
581 }
582 
583 /**
584 * @tc.name: testGetTextBeforeCursor_002
585 * @tc.desc: Select forward, mSelectNewBegin/mSelectNewEnd == number
586 * @tc.type: FUNC
587 * @tc.require: issuesI6PPJM
588 */
589 HWTEST_F(InputMethodAbilityTest, testGetTextBeforeCursor_002, TestSize.Level0)
590 {
591     IMSA_HILOGI("InputMethodAbility testGetTextBeforeCursor_002 START");
592     // implemented correctly: mSelectNewBegin > mSelectNewEnd
593     int32_t start = 7;
594     int32_t end = 4;
595     imc_->OnSelectionChange(g_textTemp, start, end);
596     int32_t number = 4;
597     std::u16string text;
598     auto ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
599     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
600     EXPECT_EQ(text, u"我們我們");
601 
602     // implemented Currently: mSelectNewBegin < mSelectNewEnd
603     start = 4;
604     end = 7;
605     imc_->OnSelectionChange(g_textTemp, start, end);
606     number = 4;
607     ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
608     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
609     EXPECT_EQ(text, u"我們我們");
610 }
611 
612 /**
613 * @tc.name: testGetTextBeforeCursor_003
614 * @tc.desc: Select backward, mSelectNewBegin < number
615 * @tc.type: FUNC
616 * @tc.require: issuesI6PPJM
617 */
618 HWTEST_F(InputMethodAbilityTest, testGetTextBeforeCursor_003, TestSize.Level0)
619 {
620     IMSA_HILOGI("InputMethodAbility testGetTextBeforeCursor_003 START");
621     int32_t start = 4;
622     int32_t end = 5;
623     imc_->OnSelectionChange(g_textTemp, start, end);
624     int32_t number = 5;
625     std::u16string text;
626     auto ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
627     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
628     EXPECT_EQ(text, u"我們我們");
629 }
630 } // namespace MiscServices
631 } // namespace OHOS
632