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 #include "test/unittest/core/pattern/rich_editor/rich_editor_common_test_ng.h"
16 #define private public
17 #define protected public
18 
19 using namespace testing;
20 using namespace testing::ext;
21 
22 namespace OHOS::Ace::NG {
23 namespace {
24 int32_t testOnReadyEvent = 0;
25 int32_t testAboutToIMEInput = 0;
26 int32_t testOnIMEInputComplete = 0;
27 int32_t testAboutToDelete = 0;
28 int32_t testOnDeleteComplete = 0;
29 } // namespace
30 
31 class RichEditorPatternTestOneNg : public RichEditorCommonTestNg {
32 public:
33     void SetUp() override;
34     void TearDown() override;
35     static void TearDownTestSuite();
36 };
37 
SetUp()38 void RichEditorPatternTestOneNg::SetUp()
39 {
40     MockPipelineContext::SetUp();
41     MockContainer::SetUp();
42     MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
43     auto* stack = ViewStackProcessor::GetInstance();
44     auto nodeId = stack->ClaimNodeId();
45     richEditorNode_ = FrameNode::GetOrCreateFrameNode(
46         V2::RICH_EDITOR_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<RichEditorPattern>(); });
47     ASSERT_NE(richEditorNode_, nullptr);
48     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
49     richEditorPattern->InitScrollablePattern();
50     richEditorPattern->SetRichEditorController(AceType::MakeRefPtr<RichEditorController>());
51     richEditorPattern->GetRichEditorController()->SetPattern(AceType::WeakClaim(AceType::RawPtr(richEditorPattern)));
52     richEditorPattern->CreateNodePaintMethod();
53     richEditorNode_->GetGeometryNode()->SetContentSize({});
54 }
55 
TearDown()56 void RichEditorPatternTestOneNg::TearDown()
57 {
58     richEditorNode_ = nullptr;
59     testOnReadyEvent = 0;
60     testAboutToIMEInput = 0;
61     testOnIMEInputComplete = 0;
62     testAboutToDelete = 0;
63     testOnDeleteComplete = 0;
64     MockParagraph::TearDown();
65 }
66 
TearDownTestSuite()67 void RichEditorPatternTestOneNg::TearDownTestSuite()
68 {
69     TestNG::TearDownTestSuite();
70 }
71 
72 /**
73  * @tc.name: RemoveEmptySpanNodes001
74  * @tc.desc: test RichEditorPattern RemoveEmptySpanNodes
75  * @tc.type: FUNC
76  */
77 HWTEST_F(RichEditorPatternTestOneNg, RemoveEmptySpanNodes001, TestSize.Level1)
78 {
79     ASSERT_NE(richEditorNode_, nullptr);
80     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
81     ASSERT_NE(richEditorPattern, nullptr);
82     richEditorPattern->RemoveEmptySpanNodes();
83     auto host = richEditorPattern->GetHost();
84     ASSERT_NE(host, nullptr);
85 }
86 
87 /**
88  * @tc.name: GetParagraphLength001
89  * @tc.desc: test RichEditorPattern GetParagraphLength
90  * @tc.type: FUNC
91  */
92 HWTEST_F(RichEditorPatternTestOneNg, GetParagraphLength001, TestSize.Level1)
93 {
94     ASSERT_NE(richEditorNode_, nullptr);
95     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
96     ASSERT_NE(richEditorPattern, nullptr);
97     std::list<RefPtr<UINode>> spans;
98     int32_t ret = richEditorPattern->GetParagraphLength(spans);
99     ASSERT_EQ(ret, 0);
100 }
101 
102 /**
103  * @tc.name: CalculateEmptyValueCaretRect001
104  * @tc.desc: test RichEditorPattern CalculateEmptyValueCaretRect
105  * @tc.type: FUNC
106  */
107 HWTEST_F(RichEditorPatternTestOneNg, CalculateEmptyValueCaretRect001, TestSize.Level1)
108 {
109     ASSERT_NE(richEditorNode_, nullptr);
110     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
111     ASSERT_NE(richEditorPattern, nullptr);
112     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
113     ASSERT_NE(paragraph, nullptr);
114     EXPECT_CALL(*paragraph, PushStyle(_)).Times(AnyNumber());
115     EXPECT_CALL(*paragraph, AddText(_)).Times(AnyNumber());
116     EXPECT_CALL(*paragraph, PopStyle()).Times(AnyNumber());
117     EXPECT_CALL(*paragraph, Build()).Times(AnyNumber());
118     EXPECT_CALL(*paragraph, Layout(_)).Times(AnyNumber());
119     TestParagraphItem testParagraphItem = {
120         .start = 0, .end = 6, .indexOffsetMap = { { 0, Offset(0, 5) }, { 6, Offset(50, 0) } }
121     };
122     richEditorPattern->paragraphs_.AddParagraph({ .paragraph = paragraph, .start = 0, .end = 6 });
123     CaretMetricsF metricsDown;
124     CaretMetricsF metricsUp;
125     for (const auto& [index, offset] : testParagraphItem.indexOffsetMap) {
126         metricsDown.offset.SetX(offset.GetX());
127         metricsDown.offset.SetY(offset.GetY());
128         metricsUp.offset.SetX(offset.GetX());
129         metricsUp.offset.SetY(offset.GetY());
130         EXPECT_CALL(*paragraph, GetGlyphIndexByCoordinate(_, _)).WillRepeatedly(Return(6));
131         EXPECT_CALL(*paragraph, GetMaxWidth).WillRepeatedly(Return(150));
132         EXPECT_CALL(*paragraph, GetHeight).WillRepeatedly(Return(50));
133         EXPECT_CALL(*paragraph, ComputeOffsetForCaretDownstream(index, _, _))
134             .WillRepeatedly(DoAll(SetArgReferee<1>(metricsDown), Return(true)));
135         EXPECT_CALL(*paragraph, ComputeOffsetForCaretUpstream(index, _, _))
136             .WillRepeatedly(DoAll(SetArgReferee<1>(metricsUp), Return(true)));
137     }
138 
139     TextStyle style;
140     style.SetLineHeight(LINE_HEIGHT_VALUE);
141     style.SetLetterSpacing(LETTER_SPACING);
142     style.SetFontFeatures(TEXT_FONTFEATURE);
143     auto layoutProperty = richEditorPattern->GetLayoutProperty<TextLayoutProperty>();
144     layoutProperty->UpdateLayoutDirection(TextDirection::RTL);
145     richEditorPattern->presetParagraph_ = paragraph;
146     richEditorPattern->CalculateEmptyValueCaretRect();
147     richEditorPattern->typingTextStyle_ = style;
148     richEditorPattern->PreferredParagraph();
149     EXPECT_NE(richEditorPattern->presetParagraph_, nullptr);
150 }
151 
152 /**
153  * @tc.name: HandleMenuCallbackOnSelectAll001
154  * @tc.desc: test RichEditorPattern HandleMenuCallbackOnSelectAll
155  * @tc.type: FUNC
156  */
157 HWTEST_F(RichEditorPatternTestOneNg, HandleMenuCallbackOnSelectAll001, TestSize.Level1)
158 {
159     ASSERT_NE(richEditorNode_, nullptr);
160     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
161     ASSERT_NE(richEditorPattern, nullptr);
162 
163     /**
164      * @tc.steps: step1. get richeditor pattern and add add text span
165      */
166     AddSpan("hello1");
167     EXPECT_EQ(richEditorPattern->GetTextContentLength(), 6);
168 
169     /**
170      * @tc.steps: step2. request focus
171      */
172     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
173     focusHub->RequestFocusImmediately();
174 
175     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
176     ASSERT_NE(eventHub, nullptr);
177 
178     bool enabledCache = eventHub->IsEnabled();
179     EXPECT_EQ(enabledCache, true);
180 
181     /**
182      * @tc.step: step3. create a scene where the text menu has popped up
183      */
184     richEditorPattern->textDetectEnable_ = true;
185     richEditorPattern->enabled_ = true;
186     richEditorPattern->OnModifyDone();
187 
188     richEditorPattern->textDetectEnable_ = true;
189     richEditorPattern->enabled_ = false;
190     richEditorPattern->OnModifyDone();
191 
192     richEditorPattern->textDetectEnable_ = false;
193     richEditorPattern->enabled_ = true;
194     richEditorPattern->OnModifyDone();
195 
196     richEditorPattern->textDetectEnable_ = false;
197     richEditorPattern->enabled_ = false;
198     richEditorPattern->OnModifyDone();
199 
200     richEditorPattern->textSelector_.Update(1, 2);
201     richEditorPattern->CalculateHandleOffsetAndShowOverlay();
202     richEditorPattern->ShowSelectOverlay(
203         richEditorPattern->textSelector_.firstHandle, richEditorPattern->textSelector_.secondHandle, false);
204     EXPECT_TRUE(richEditorPattern->SelectOverlayIsOn());
205 
206     /**
207      * @tc.step: step4. test OnMenuItemAction
208      */
209     richEditorPattern->selectOverlay_->OnMenuItemAction(OptionMenuActionId::COPY, OptionMenuType::TOUCH_MENU);
210     EXPECT_EQ(richEditorPattern->textSelector_.GetTextStart(), 1);
211     EXPECT_EQ(richEditorPattern->textSelector_.GetTextEnd(), 2);
212 
213     richEditorPattern->selectOverlay_->OnMenuItemAction(OptionMenuActionId::PASTE, OptionMenuType::NO_MENU);
214     EXPECT_EQ(richEditorPattern->GetTextContentLength(), 6);
215 
216     richEditorPattern->selectOverlay_->isUsingMouse_ = true;
217     richEditorPattern->HandleMenuCallbackOnSelectAll();
218     ASSERT_EQ(richEditorPattern->IsUsingMouse(), false);
219 }
220 
221 /**
222  * @tc.name: InsertStyledStringByPaste001
223  * @tc.desc: test RichEditorPattern InsertStyledStringByPaste
224  * @tc.type: FUNC
225  */
226 HWTEST_F(RichEditorPatternTestOneNg, InsertStyledStringByPaste001, TestSize.Level1)
227 {
228     /**
229      * @tc.steps: step1. get richEditor pattern and controller
230      */
231     ASSERT_NE(richEditorNode_, nullptr);
232     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
233     ASSERT_NE(richEditorPattern, nullptr);
234 
235     auto richEditorController = richEditorPattern->GetRichEditorController();
236     ASSERT_NE(richEditorController, nullptr);
237 
238     /**
239      * @tc.steps: step2. add span and select text
240      */
241     AddSpan("test");
242     EXPECT_EQ(richEditorPattern->GetTextContentLength(), 4);
243     richEditorPattern->textSelector_.Update(3, 4);
244     richEditorPattern->styledString_ = AceType::MakeRefPtr<MutableSpanString>("abc");
245     std::string data = "abc";
246     RefPtr<SpanString> spanString = AceType::MakeRefPtr<SpanString>(data);
247     richEditorPattern->InsertStyledStringByPaste(spanString);
248 
249     ASSERT_EQ(richEditorPattern->textSelector_.IsValid(), false);
250 }
251 
252 /**
253  * @tc.name: AddSpansByPaste001
254  * @tc.desc: test RichEditorPattern AddSpansByPaste
255  * @tc.type: FUNC
256  */
257 HWTEST_F(RichEditorPatternTestOneNg, AddSpansByPaste001, TestSize.Level1)
258 {
259     /**
260      * @tc.steps: step1. get richEditor pattern and controller
261      */
262     ASSERT_NE(richEditorNode_, nullptr);
263     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
264     ASSERT_NE(richEditorPattern, nullptr);
265 
266     auto richEditorController = richEditorPattern->GetRichEditorController();
267     ASSERT_NE(richEditorController, nullptr);
268 
269     /**
270      * @tc.steps: step2. add span and select text
271      */
272     AddSpan("test");
273     EXPECT_EQ(richEditorPattern->GetTextContentLength(), 4);
274     richEditorPattern->textSelector_.Update(3, 4);
275     std::list<RefPtr<NG::SpanItem>> spans;
276     OHOS::Ace::RefPtr<OHOS::Ace::NG::SpanItem> spanItem1 = AceType::MakeRefPtr<ImageSpanItem>();
277     spans.push_back(spanItem1);
278     richEditorPattern->AddSpansByPaste(spans);
279     ASSERT_EQ(richEditorPattern->textSelector_.IsValid(), false);
280 }
281 
282 /**
283  * @tc.name: UnableStandardInput001
284  * @tc.desc: test RichEditorPattern UnableStandardInput
285  * @tc.type: FUNC
286  */
287 HWTEST_F(RichEditorPatternTestOneNg, UnableStandardInput001, TestSize.Level1)
288 {
289     ASSERT_NE(richEditorNode_, nullptr);
290     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
291     ASSERT_NE(richEditorPattern, nullptr);
292     richEditorPattern->UnableStandardInput(true);
293     bool res = richEditorPattern->UnableStandardInput(false);
294     ASSERT_EQ(res, false);
295 }
296 
297 /**
298  * @tc.name: HandleOnDelete001
299  * @tc.desc: test RichEditorPattern HandleOnDelete
300  * @tc.type: FUNC
301  */
302 HWTEST_F(RichEditorPatternTestOneNg, HandleOnDelete001, TestSize.Level1)
303 {
304     ASSERT_NE(richEditorNode_, nullptr);
305     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
306     ASSERT_NE(richEditorPattern, nullptr);
307     richEditorPattern->HandleOnDelete(true);
308     richEditorPattern->HandleOnDelete(false);
309 }
310 
311 /**
312  * @tc.name: CursorMoveUp001
313  * @tc.desc: test RichEditorPattern CursorMoveUp
314  * @tc.type: FUNC
315  */
316 HWTEST_F(RichEditorPatternTestOneNg, CursorMoveUp001, TestSize.Level1)
317 {
318     ASSERT_NE(richEditorNode_, nullptr);
319     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
320     ASSERT_NE(richEditorPattern, nullptr);
321 
322     /**
323      * @tc.steps: step1. get richeditor pattern and add add text span
324      */
325     AddSpan("");
326     richEditorPattern->CursorMoveUp();
327     AddSpan("hello1");
328     bool res = richEditorPattern->CursorMoveUp();
329     res = richEditorPattern->CursorMoveDown();
330     ASSERT_EQ(res, true);
331 }
332 
333 /**
334  * @tc.name: CursorMoveHome001
335  * @tc.desc: test RichEditorPattern CursorMoveHome
336  * @tc.type: FUNC
337  */
338 HWTEST_F(RichEditorPatternTestOneNg, CursorMoveHome001, TestSize.Level1)
339 {
340     ASSERT_NE(richEditorNode_, nullptr);
341     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
342     ASSERT_NE(richEditorPattern, nullptr);
343     richEditorPattern->caretPosition_ = 0;
344     bool res = richEditorPattern->CursorMoveHome();
345     ASSERT_EQ(res, false);
346 }
347 
348 /**
349  * @tc.name: ClearOperationRecords001
350  * @tc.desc: test RichEditorPattern ClearOperationRecords
351  * @tc.type: FUNC
352  */
353 HWTEST_F(RichEditorPatternTestOneNg, ClearOperationRecords001, TestSize.Level1)
354 {
355     ASSERT_NE(richEditorNode_, nullptr);
356     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
357     ASSERT_NE(richEditorPattern, nullptr);
358     RichEditorPattern::OperationRecord record;
359     richEditorPattern->redoOperationRecords_.push_back(record);
360     richEditorPattern->ClearRedoOperationRecords();
361     richEditorPattern->redoOperationRecords_.clear();
362     richEditorPattern->HandleOnRedoAction();
363     ASSERT_EQ(richEditorPattern->redoOperationRecords_.empty(), true);
364     richEditorPattern->operationRecords_.push_back(record);
365     richEditorPattern->ClearOperationRecords();
366     richEditorPattern->operationRecords_.clear();
367     richEditorPattern->HandleOnUndoAction();
368     ASSERT_EQ(richEditorPattern->operationRecords_.empty(), true);
369 }
370 
371 /**
372  * @tc.name: ResetAfterPaste001
373  * @tc.desc: test RichEditorPattern ResetAfterPaste
374  * @tc.type: FUNC
375  */
376 HWTEST_F(RichEditorPatternTestOneNg, ResetAfterPaste001, TestSize.Level1)
377 {
378     ASSERT_NE(richEditorNode_, nullptr);
379     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
380     ASSERT_NE(richEditorPattern, nullptr);
381     richEditorPattern->previewLongPress_ = true;
382     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
383     ASSERT_NE(focusHub, nullptr);
384     focusHub->RequestFocusImmediately();
385     richEditorPattern->isEditing_ = false;
386     richEditorPattern->ResetAfterPaste();
387     ASSERT_NE(richEditorPattern->previewLongPress_, true);
388 }
389 
390 /**
391  * @tc.name: ShowHandles001
392  * @tc.desc: test RichEditorPattern ShowHandles
393  * @tc.type: FUNC
394  */
395 HWTEST_F(RichEditorPatternTestOneNg, ShowHandles001, TestSize.Level1)
396 {
397     ASSERT_NE(richEditorNode_, nullptr);
398     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
399     ASSERT_NE(richEditorPattern, nullptr);
400     auto richEditorController = richEditorPattern->GetRichEditorController();
401     ASSERT_NE(richEditorController, nullptr);
402     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
403     ASSERT_NE(focusHub, nullptr);
404     /**
405      * @tc.steps: step2. initalize span properties
406      */
407     TextSpanOptions options2;
408     options2.value = INIT_VALUE_1;
409 
410     /**
411      * @tc.steps: step3. test add span
412      */
413     richEditorController->AddTextSpan(options2);
414     focusHub->RequestFocusImmediately();
415     richEditorPattern->ShowHandles(true);
416     richEditorPattern->ShowHandles(false);
417     ASSERT_EQ(richEditorPattern->HasFocus(), true);
418 }
419 
420 /**
421  * @tc.name: UpdateTextFieldManager001
422  * @tc.desc: test RichEditorPattern UpdateTextFieldManager
423  * @tc.type: FUNC
424  */
425 HWTEST_F(RichEditorPatternTestOneNg, UpdateTextFieldManager001, TestSize.Level1)
426 {
427     MockPipelineContext::GetCurrent()->SetMinPlatformVersion(static_cast<int32_t>(PlatformVersion::VERSION_ELEVEN));
428 
429     ASSERT_NE(richEditorNode_, nullptr);
430     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
431     ASSERT_NE(richEditorPattern, nullptr);
432     auto richEditorController = richEditorPattern->GetRichEditorController();
433     ASSERT_NE(richEditorController, nullptr);
434     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
435     ASSERT_NE(focusHub, nullptr);
436     /**
437      * @tc.steps: step2. initalize span properties
438      */
439     TextSpanOptions options2;
440     options2.value = INIT_VALUE_1;
441 
442     /**
443      * @tc.steps: step3. test add span
444      */
445     richEditorController->AddTextSpan(options2);
446     focusHub->RequestFocusImmediately();
447     richEditorPattern->ShowHandles(true);
448     richEditorPattern->ShowHandles(false);
449 
450     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
451     ASSERT_NE(themeManager, nullptr);
452     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<RichEditorTheme>()));
453 
454     auto oldThemeManager = PipelineBase::GetCurrentContext()->themeManager_;
455     PipelineBase::GetCurrentContext()->themeManager_ = themeManager;
456 
457     RichEditorTheme richEditorTheme;
458     EXPECT_EQ(richEditorPattern->GetPreviewTextDecorationColor(), richEditorTheme.GetPreviewUnderLineColor());
459 
460     auto safeAreaManager = AceType::MakeRefPtr<SafeAreaManager>();
461     MockPipelineContext::GetCurrent()->safeAreaManager_ = safeAreaManager;
462     MockPipelineContext::GetCurrent()->SetRootSize(800, 2000);
463     auto textFieldManager = AceType::MakeRefPtr<TextFieldManagerNG>();
464     textFieldManager->SetHeight(20);
465     MockPipelineContext::GetCurrent()->SetTextFieldManager(textFieldManager);
466 
467     Offset Offset = { 1, 4 };
468     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
469 
470     richEditorPattern->isTextChange_ = true;
471     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
472     EXPECT_EQ(richEditorPattern->HasFocus(), true);
473 }
474 
475 /**
476  * @tc.name: JudgeSelectType001
477  * @tc.desc: test RichEditorPattern JudgeSelectType
478  * @tc.type: FUNC
479  */
480 HWTEST_F(RichEditorPatternTestOneNg, JudgeSelectType001, TestSize.Level1)
481 {
482     ASSERT_NE(richEditorNode_, nullptr);
483     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
484     ASSERT_NE(richEditorPattern, nullptr);
485     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
486     ASSERT_NE(paragraph, nullptr);
487 
488     richEditorPattern->previewLongPress_ = true;
489     auto offset = Offset(50.0, -80.0);
490     AddSpan("hello1");
491     auto selectType = richEditorPattern->JudgeSelectType(offset).second;
492     EXPECT_NE(selectType, SelectType::SELECT_FORWARD);
493     richEditorPattern->previewLongPress_ = false;
494     richEditorPattern->editingLongPress_ = true;
495     selectType = richEditorPattern->JudgeSelectType(offset).second;
496     EXPECT_NE(selectType, SelectType::SELECT_FORWARD);
497 }
498 
499 /**
500  * @tc.name: HandleSelectOverlayWithOptions001
501  * @tc.desc: test RichEditorPattern HandleSelectOverlayWithOptions
502  * @tc.type: FUNC
503  */
504 HWTEST_F(RichEditorPatternTestOneNg, HandleSelectOverlayWithOptions001, TestSize.Level1)
505 {
506     ASSERT_NE(richEditorNode_, nullptr);
507     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
508     ASSERT_NE(richEditorPattern, nullptr);
509 
510     SelectionOptions options;
511     options.menuPolicy = MenuPolicy::SHOW;
512     richEditorPattern->isMousePressed_ = true;
513     richEditorPattern->sourceType_ = SourceType::MOUSE;
514     richEditorPattern->HandleSelectOverlayWithOptions(options);
515     richEditorPattern->isMousePressed_ = false;
516     richEditorPattern->sourceType_ = SourceType::MOUSE;
517     richEditorPattern->HandleSelectOverlayWithOptions(options);
518     richEditorPattern->isMousePressed_ = true;
519     richEditorPattern->sourceType_ = SourceType::TOUCH;
520     richEditorPattern->HandleSelectOverlayWithOptions(options);
521     richEditorPattern->isMousePressed_ = false;
522     richEditorPattern->sourceType_ = SourceType::TOUCH;
523     richEditorPattern->HandleSelectOverlayWithOptions(options);
524     options.menuPolicy = MenuPolicy::DEFAULT;
525     richEditorPattern->HandleSelectOverlayWithOptions(options);
526     options.menuPolicy = MenuPolicy::HIDE;
527     richEditorPattern->HandleSelectOverlayWithOptions(options);
528     ClearSpan();
529     richEditorPattern->HandleSelectOverlayWithOptions(options);
530     ASSERT_EQ(richEditorPattern->SelectOverlayIsOn(), false);
531 }
532 
533 /**
534  * @tc.name: InsertValueInStyledString001
535  * @tc.desc: test RichEditorPattern InsertValueInStyledString
536  * @tc.type: FUNC
537  */
538 HWTEST_F(RichEditorPatternTestOneNg, InsertValueInStyledString001, TestSize.Level1)
539 {
540     ASSERT_NE(richEditorNode_, nullptr);
541     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
542     ASSERT_NE(richEditorPattern, nullptr);
543 
544     TextStyle style;
545     style.SetLineHeight(LINE_HEIGHT_VALUE);
546     style.SetLetterSpacing(LETTER_SPACING);
547     style.SetFontFeatures(TEXT_FONTFEATURE);
548 
549     UpdateSpanStyle updateSpanStyle;
550 
551     std::string content = "TEST123";
552     richEditorPattern->isSpanStringMode_ = true;
553     richEditorPattern->styledString_ = AceType::MakeRefPtr<MutableSpanString>(content);
554 
555     richEditorPattern->typingStyle_ = std::nullopt;
556     richEditorPattern->typingTextStyle_ = std::nullopt;
557     richEditorPattern->InsertValueInStyledString("abc");
558 
559     richEditorPattern->typingStyle_ = std::nullopt;
560     richEditorPattern->typingTextStyle_ = style;
561     richEditorPattern->InsertValueInStyledString("abc");
562 
563     richEditorPattern->typingStyle_ = updateSpanStyle;
564     richEditorPattern->typingTextStyle_ = std::nullopt;
565     richEditorPattern->InsertValueInStyledString("abc");
566 
567     richEditorPattern->typingStyle_ = updateSpanStyle;
568     richEditorPattern->typingTextStyle_ = style;
569     richEditorPattern->InsertValueInStyledString("abc");
570 
571     ASSERT_EQ(richEditorPattern->typingTextStyle_.has_value(), true);
572 }
573 
574 /**
575  * @tc.name: InsertValueInStyledString002
576  * @tc.desc: test RichEditorPattern InsertValueInStyledString
577  * @tc.type: FUNC
578  */
579 HWTEST_F(RichEditorPatternTestOneNg, InsertValueInStyledString002, TestSize.Level1)
580 {
581     ASSERT_NE(richEditorNode_, nullptr);
582     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
583     ASSERT_NE(richEditorPattern, nullptr);
584     auto richEditorController = richEditorPattern->GetRichEditorController();
585     ASSERT_NE(richEditorController, nullptr);
586     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
587     ASSERT_NE(focusHub, nullptr);
588     auto host = richEditorPattern->GetHost();
589     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
590     ASSERT_NE(eventHub, nullptr);
591     TextSpanOptions options2;
592     options2.value = INIT_VALUE_1;
593     richEditorController->AddTextSpan(options2);
594     focusHub->RequestFocusImmediately();
595     richEditorPattern->FireOnSelectionChange(-1, 0);
596     richEditorPattern->FireOnSelectionChange(0, -1);
597     richEditorPattern->FireOnSelectionChange(-1, -1);
598     ASSERT_EQ(richEditorPattern->HasFocus(), true);
599 }
600 
601 /**
602  * @tc.name: CreateDecorationSpanByTextStyle001
603  * @tc.desc: test RichEditorPattern CreateDecorationSpanByTextStyle
604  * @tc.type: FUNC
605  */
606 HWTEST_F(RichEditorPatternTestOneNg, CreateDecorationSpanByTextStyle001, TestSize.Level1)
607 {
608     ASSERT_NE(richEditorNode_, nullptr);
609     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
610     ASSERT_NE(richEditorPattern, nullptr);
611     UpdateSpanStyle updateSpanStyle;
612     updateSpanStyle.updateTextDecorationStyle = TextDecorationStyle::DASHED;
613     TextStyle style;
614     style.SetLineHeight(LINE_HEIGHT_VALUE);
615     style.SetLetterSpacing(LETTER_SPACING);
616     style.SetFontFeatures(TEXT_FONTFEATURE);
617     RefPtr<DecorationSpan> span = richEditorPattern->CreateDecorationSpanByTextStyle(updateSpanStyle, style, 0);
618     ASSERT_NE(span, nullptr);
619 }
620 
621 /**
622  * @tc.name: DeleteValueInStyledString001
623  * @tc.desc: test RichEditorPattern DeleteValueInStyledString
624  * @tc.type: FUNC
625  */
626 HWTEST_F(RichEditorPatternTestOneNg, DeleteValueInStyledString001, TestSize.Level1)
627 {
628     ASSERT_NE(richEditorNode_, nullptr);
629     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
630     ASSERT_NE(richEditorPattern, nullptr);
631     richEditorPattern->styledString_ = AceType::MakeRefPtr<MutableSpanString>("abc");
632     richEditorPattern->caretVisible_ = false;
633     richEditorPattern->previewLongPress_ = true;
634     richEditorPattern->DeleteValueInStyledString(0, 10, true);
635     richEditorPattern->previewLongPress_ = false;
636     richEditorPattern->DeleteValueInStyledString(0, 10, true);
637     richEditorPattern->previewLongPress_ = true;
638     richEditorPattern->DeleteValueInStyledString(0, 10, false);
639     richEditorPattern->previewLongPress_ = false;
640     richEditorPattern->DeleteValueInStyledString(0, 10, false);
641     ASSERT_EQ(!richEditorPattern->BeforeStyledStringChange(0, 10, ""), false);
642 }
643 
644 /**
645  * @tc.name: MouseDoubleClickParagraphEnd001
646  * @tc.desc: test RichEditorPattern MouseDoubleClickParagraphEnd
647  * @tc.type: FUNC
648  */
649 HWTEST_F(RichEditorPatternTestOneNg, MouseDoubleClickParagraphEnd001, TestSize.Level1)
650 {
651     ASSERT_NE(richEditorNode_, nullptr);
652     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
653     ASSERT_NE(richEditorPattern, nullptr);
654 
655     AddSpan("TEST123");
656     std::string content = "TEST123";
657     richEditorPattern->isSpanStringMode_ = true;
658     richEditorPattern->styledString_ = AceType::MakeRefPtr<MutableSpanString>(content);
659 
660     richEditorPattern->typingStyle_ = std::nullopt;
661     richEditorPattern->typingTextStyle_ = std::nullopt;
662     richEditorPattern->InsertValueInStyledString("TEST123");
663 
664     richEditorPattern->caretUpdateType_ = CaretUpdateType::DOUBLE_CLICK;
665     richEditorPattern->sourceType_ = SourceType::MOUSE;
666     int32_t index = 7;
667     int32_t index2 = 2;
668     richEditorPattern->MouseDoubleClickParagraphEnd(index2);
669     richEditorPattern->MouseDoubleClickParagraphEnd(index);
670     EXPECT_EQ(richEditorPattern->GetParagraphEndPosition(index), 7);
671 }
672 
673 /**
674  * @tc.name: CreateImageSourceInfo002
675  * @tc.desc: test CreateImageSourceInfo
676  * @tc.type: FUNC
677  */
678 HWTEST_F(RichEditorPatternTestOneNg, CreateImageSourceInfo002, TestSize.Level1)
679 {
680     ASSERT_NE(richEditorNode_, nullptr);
681     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
682     ASSERT_NE(richEditorPattern, nullptr);
683     richEditorPattern->CreateEventHub();
684     ImageSpanOptions options;
685     void* voidPtr = static_cast<void*>(new char[0]);
686     RefPtr<PixelMap> pixelMap = PixelMap::CreatePixelMap(voidPtr);
687     ASSERT_NE(pixelMap, nullptr);
688     options.imagePixelMap = pixelMap;
689     richEditorPattern->CreateImageSourceInfo(options);
690     EXPECT_EQ(options.imagePixelMap.has_value(), true);
691 }
692 
693 /**
694  * @tc.name: GetTextContentLength001
695  * @tc.desc: test GetTextContentLength
696  * @tc.type: FUNC
697  */
698 HWTEST_F(RichEditorPatternTestOneNg, GetTextContentLength001, TestSize.Level1)
699 {
700     ASSERT_NE(richEditorNode_, nullptr);
701     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
702     ASSERT_NE(richEditorPattern, nullptr);
703     richEditorPattern->styledString_ = nullptr;
704     richEditorPattern->isSpanStringMode_ = true;
705     richEditorPattern->GetTextContentLength();
706 
707     richEditorPattern->styledString_ = nullptr;
708     richEditorPattern->isSpanStringMode_ = false;
709     richEditorPattern->GetTextContentLength();
710 
711     richEditorPattern->styledString_ = AceType::MakeRefPtr<MutableSpanString>("abc");
712     richEditorPattern->isSpanStringMode_ = true;
713     richEditorPattern->GetTextContentLength();
714 
715     richEditorPattern->styledString_ = AceType::MakeRefPtr<MutableSpanString>("abc");
716     richEditorPattern->isSpanStringMode_ = false;
717     int32_t res = richEditorPattern->GetTextContentLength();
718     EXPECT_EQ(res, 0);
719 }
720 
721 /**
722  * @tc.name: SetGestureOptions001
723  * @tc.desc: test SetGestureOptions
724  * @tc.type: FUNC
725  */
726 HWTEST_F(RichEditorPatternTestOneNg, SetGestureOptions001, TestSize.Level1)
727 {
728     ASSERT_NE(richEditorNode_, nullptr);
729     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
730     ASSERT_NE(richEditorPattern, nullptr);
731 
732     OHOS::Ace::UserGestureOptions userGestureOptions;
__anon5aaa9b0c0302(GestureEvent& info) 733     userGestureOptions.onLongPress = [](GestureEvent& info) {};
734     auto spanItem = AceType::MakeRefPtr<SpanItem>();
735 
736     richEditorPattern->SetGestureOptions(userGestureOptions, spanItem);
737 
738     EXPECT_NE(userGestureOptions.onLongPress, nullptr);
739 }
740 
741 /**
742  * @tc.name: AddTextSpan001
743  * @tc.desc: test AddTextSpan
744  * @tc.type: FUNC
745  */
746 HWTEST_F(RichEditorPatternTestOneNg, AddTextSpan001, TestSize.Level1)
747 {
748     ASSERT_NE(richEditorNode_, nullptr);
749     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
750     ASSERT_NE(richEditorPattern, nullptr);
751     TextSpanOptions options;
752     richEditorPattern->previewTextRecord_.previewContent = "123";
753     richEditorPattern->previewTextRecord_.isPreviewTextInputting = true;
754     richEditorPattern->previewTextRecord_.startOffset = 0;
755     richEditorPattern->previewTextRecord_.endOffset = 0;
756     EXPECT_EQ(richEditorPattern->previewTextRecord_.IsValid(), true);
757     int32_t res = richEditorPattern->AddTextSpan(options, true, 0);
758     EXPECT_EQ(res, 0);
759 }
760 
761 /**
762  * @tc.name: DeleteSpansOperation001
763  * @tc.desc: test DeleteSpansOperation
764  * @tc.type: FUNC
765  */
766 HWTEST_F(RichEditorPatternTestOneNg, DeleteSpansOperation001, TestSize.Level1)
767 {
768     /**
769      * @tc.steps: step1. get richEditor pattern and controller
770      */
771     ASSERT_NE(richEditorNode_, nullptr);
772     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
773     ASSERT_NE(richEditorPattern, nullptr);
774 
775     auto richEditorController = richEditorPattern->GetRichEditorController();
776     ASSERT_NE(richEditorController, nullptr);
777 
778     AddSpan("test");
779     richEditorPattern->textSelector_.Update(3, 4);
780     richEditorPattern->DeleteSpansOperation(0, 0);
781     EXPECT_FALSE(richEditorPattern->textSelector_.IsValid());
782 }
783 
784 /**
785  * @tc.name: DeleteSpansByRange001
786  * @tc.desc: test DeleteSpansByRange
787  * @tc.type: FUNC
788  */
789 HWTEST_F(RichEditorPatternTestOneNg, DeleteSpansByRange001, TestSize.Level1)
790 {
791     ASSERT_NE(richEditorNode_, nullptr);
792     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
793     ASSERT_NE(richEditorPattern, nullptr);
794     SpanPositionInfo startInfo;
795     SpanPositionInfo endInfo;
796     startInfo.spanIndex_ = -1;
797     richEditorPattern->DeleteSpansByRange(0, 0, startInfo, endInfo);
798     EXPECT_EQ(richEditorPattern->GetHost()->GetChildren().size(), 0);
799 }
800 
801 /**
802  * @tc.name: CopyGestureOption001
803  * @tc.desc: test CopyGestureOption
804  * @tc.type: FUNC
805  */
806 HWTEST_F(RichEditorPatternTestOneNg, CopyGestureOption001, TestSize.Level1)
807 {
808     ASSERT_NE(richEditorNode_, nullptr);
809     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
810     ASSERT_NE(richEditorPattern, nullptr);
811 
812     RefPtr<SpanNode> source = OHOS::Ace::NG::SpanNode::CreateSpanNode(1);
813     RefPtr<SpanNode> target = OHOS::Ace::NG::SpanNode::CreateSpanNode(2);
__anon5aaa9b0c0402(GestureEvent& info) 814     GestureEventFunc func = [](GestureEvent& info) {};
815     source->GetSpanItem()->SetOnClickEvent(std::move(func));
816     source->GetSpanItem()->SetLongPressEvent(std::move(func));
817     richEditorPattern->CopyGestureOption(source, target);
818     ASSERT_NE(source->GetSpanItem(), nullptr);
819     ASSERT_NE(target->GetSpanItem(), nullptr);
820 }
821 
822 /**
823  * @tc.name: SetCaretOffset001
824  * @tc.desc: test SetCaretOffset
825  * @tc.type: FUNC
826  */
827 HWTEST_F(RichEditorPatternTestOneNg, SetCaretOffset001, TestSize.Level1)
828 {
829     ASSERT_NE(richEditorNode_, nullptr);
830     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
831     ASSERT_NE(richEditorPattern, nullptr);
832 
833     richEditorPattern->previewTextRecord_.previewContent = "abc";
834     richEditorPattern->previewTextRecord_.isPreviewTextInputting = true;
835     richEditorPattern->previewTextRecord_.startOffset = 0;
836     richEditorPattern->previewTextRecord_.endOffset = 0;
837 
838     bool res = richEditorPattern->SetCaretOffset(0);
839     ASSERT_EQ(res, false);
840 }
841 
842 /**
843  * @tc.name: CalcCursorOffsetByPosition001
844  * @tc.desc: test CalcCursorOffsetByPosition
845  * @tc.type: FUNC
846  */
847 HWTEST_F(RichEditorPatternTestOneNg, CalcCursorOffsetByPosition001, TestSize.Level1)
848 {
849     ASSERT_NE(richEditorNode_, nullptr);
850     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
851     ASSERT_NE(richEditorPattern, nullptr);
852     float selectLineHeight = 0;
853     richEditorPattern->CalcCursorOffsetByPosition(0, selectLineHeight, true, true);
854     ASSERT_EQ(richEditorPattern->GetTextContentLength(), 0);
855     AddSpan("hello1");
856     ASSERT_NE(richEditorPattern->GetTextContentLength(), 0);
857     richEditorPattern->CalcCursorOffsetByPosition(0, selectLineHeight, true, true);
858     ASSERT_EQ(richEditorPattern->GetHost()->GetChildren().empty(), false);
859 }
860 
861 /**
862  * @tc.name: UpdateDecoration001
863  * @tc.desc: test UpdateDecoration
864  * @tc.type: FUNC
865  */
866 HWTEST_F(RichEditorPatternTestOneNg, UpdateDecoration001, TestSize.Level1)
867 {
868     ASSERT_NE(richEditorNode_, nullptr);
869     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
870     ASSERT_NE(richEditorPattern, nullptr);
871     RefPtr<SpanNode> spanNode = OHOS::Ace::NG::SpanNode::CreateSpanNode(1);
872     UpdateSpanStyle updateSpanStyle;
873     updateSpanStyle.updateTextDecorationStyle = TextDecorationStyle::DASHED;
874     TextStyle textStyle;
875     richEditorPattern->UpdateDecoration(spanNode, updateSpanStyle, textStyle);
876     ASSERT_EQ(updateSpanStyle.updateTextDecoration.has_value(), false);
877 }
878 
879 /**
880  * @tc.name: UpdateImageStyle001
881  * @tc.desc: test UpdateImageStyle
882  * @tc.type: FUNC
883  */
884 HWTEST_F(RichEditorPatternTestOneNg, UpdateImageStyle001, TestSize.Level1)
885 {
886     ASSERT_NE(richEditorNode_, nullptr);
887     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
888     ASSERT_NE(richEditorPattern, nullptr);
889 
890     Dimension width = 50.0_vp;
891     Dimension height = 50.0_vp;
892     RefPtr<FrameNode> imageNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, 0, AceType::MakeRefPtr<ImagePattern>());
893     ImageSpanAttribute imageStyle;
894     richEditorPattern->updateSpanStyle_.updateImageWidth = std::nullopt;
895     richEditorPattern->updateSpanStyle_.updateImageHeight = std::nullopt;
896     richEditorPattern->UpdateImageStyle(imageNode, imageStyle);
897 
898     richEditorPattern->updateSpanStyle_.updateImageWidth = width;
899     richEditorPattern->updateSpanStyle_.updateImageHeight = height;
900     richEditorPattern->UpdateImageStyle(imageNode, imageStyle);
901 
902     richEditorPattern->updateSpanStyle_.updateImageWidth = width;
903     richEditorPattern->updateSpanStyle_.updateImageHeight = std::nullopt;
904     richEditorPattern->UpdateImageStyle(imageNode, imageStyle);
905 
906     richEditorPattern->updateSpanStyle_.updateImageWidth = std::nullopt;
907     richEditorPattern->updateSpanStyle_.updateImageHeight = height;
908     richEditorPattern->UpdateImageStyle(imageNode, imageStyle);
909     ASSERT_EQ(richEditorPattern->updateSpanStyle_.updateImageHeight.has_value(), true);
910 }
911 
912 /**
913  * @tc.name: SymbolSpanUpdateStyle001
914  * @tc.desc: test SymbolSpanUpdateStyle
915  * @tc.type: FUNC
916  */
917 HWTEST_F(RichEditorPatternTestOneNg, SymbolSpanUpdateStyle001, TestSize.Level1)
918 {
919     ASSERT_NE(richEditorNode_, nullptr);
920     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
921     ASSERT_NE(richEditorPattern, nullptr);
922 
923     auto spanNode = SpanNode::GetOrCreateSpanNode(V2::SYMBOL_SPAN_ETS_TAG, 0);
924     UpdateSpanStyle updateSpanStyle;
925     updateSpanStyle.updateTextDecorationStyle = TextDecorationStyle::DASHED;
926     TextStyle textStyle;
927 
928     bool res = richEditorPattern->SymbolSpanUpdateStyle(spanNode, updateSpanStyle, textStyle);
929     ASSERT_EQ(res, true);
930 }
931 
932 /**
933  * @tc.name: CloseSystemMenu001
934  * @tc.desc: test CloseSystemMenu
935  * @tc.type: FUNC
936  */
937 HWTEST_F(RichEditorPatternTestOneNg, CloseSystemMenu001, TestSize.Level1)
938 {
939     ASSERT_NE(richEditorNode_, nullptr);
940     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
941     ASSERT_NE(richEditorPattern, nullptr);
942 
943     /**
944      * @tc.steps: step1. get richeditor pattern and add add text span
945      */
946     AddSpan("hello1");
947     EXPECT_EQ(richEditorPattern->GetTextContentLength(), 6);
948 
949     /**
950      * @tc.steps: step2. request focus
951      */
952     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
953     focusHub->RequestFocusImmediately();
954 
955     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
956     ASSERT_NE(eventHub, nullptr);
957 
958     bool enabledCache = eventHub->IsEnabled();
959     EXPECT_EQ(enabledCache, true);
960 
961     /**
962      * @tc.step: step3. create a scene where the text menu has popped up
963      */
964     richEditorPattern->textDetectEnable_ = true;
965     richEditorPattern->enabled_ = true;
966     richEditorPattern->OnModifyDone();
967 
968     richEditorPattern->textDetectEnable_ = true;
969     richEditorPattern->enabled_ = false;
970     richEditorPattern->OnModifyDone();
971 
972     richEditorPattern->textDetectEnable_ = false;
973     richEditorPattern->enabled_ = true;
974     richEditorPattern->OnModifyDone();
975 
976     richEditorPattern->textDetectEnable_ = false;
977     richEditorPattern->enabled_ = false;
978     richEditorPattern->OnModifyDone();
979 
980     richEditorPattern->textSelector_.Update(1, 2);
981     richEditorPattern->CalculateHandleOffsetAndShowOverlay();
982     richEditorPattern->ShowSelectOverlay(
983         richEditorPattern->textSelector_.firstHandle, richEditorPattern->textSelector_.secondHandle, false);
984 
985     richEditorPattern->CloseSystemMenu();
986 
987     EXPECT_EQ(richEditorPattern->SelectOverlayIsOn(), false);
988 }
989 
990 /**
991  * @tc.name: CreateAndShowSingleHandle001
992  * @tc.desc: test CreateAndShowSingleHandle
993  * @tc.type: FUNC
994  */
995 HWTEST_F(RichEditorPatternTestOneNg, CreateAndShowSingleHandle001, TestSize.Level1)
996 {
997     /**
998      * @tc.steps: step1. create richEditorPattern
999      */
1000     ASSERT_NE(richEditorNode_, nullptr);
1001     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1002     ASSERT_NE(richEditorPattern, nullptr);
1003     richEditorPattern->caretPosition_ = -1;
1004 
1005     /**
1006      * @tc.steps: step2. Construct GestureEvent data and call CreatAndShowSingleHandle
1007      */
1008     ASSERT_NE(richEditorPattern->selectOverlay_, nullptr);
1009     richEditorPattern->previewTextRecord_.previewContent = "abc";
1010     richEditorPattern->previewTextRecord_.isPreviewTextInputting = true;
1011     richEditorPattern->previewTextRecord_.startOffset = 0;
1012     richEditorPattern->previewTextRecord_.endOffset = 0;
1013     richEditorPattern->CreateAndShowSingleHandle();
1014     EXPECT_FALSE(richEditorPattern->selectOverlay_->IsSingleHandle());
1015 }
1016 
1017 /**
1018  * @tc.name: MoveCaretAndStartFocus001
1019  * @tc.desc: test MoveCaretAndStartFocus
1020  * @tc.type: FUNC
1021  */
1022 HWTEST_F(RichEditorPatternTestOneNg, MoveCaretAndStartFocus001, TestSize.Level1)
1023 {
1024     ASSERT_NE(richEditorNode_, nullptr);
1025     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1026     ASSERT_NE(richEditorPattern, nullptr);
1027 
1028     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
1029     ASSERT_NE(focusHub, nullptr);
1030 
1031     Offset textOffset;
1032     richEditorPattern->overlayMod_ = nullptr;
1033     richEditorPattern->MoveCaretAndStartFocus(textOffset);
1034     EXPECT_TRUE(focusHub->RequestFocusImmediately());
1035 }
1036 
1037 /**
1038  * @tc.name: HandleOnlyImageSelected001
1039  * @tc.desc: test HandleOnlyImageSelected
1040  * @tc.type: FUNC
1041  */
1042 HWTEST_F(RichEditorPatternTestOneNg, HandleOnlyImageSelected001, TestSize.Level1)
1043 {
1044     /**
1045      * @tc.steps: step1. get richeditor pattern and add add text span
1046      */
1047     ASSERT_NE(richEditorNode_, nullptr);
1048     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1049     ASSERT_NE(richEditorPattern, nullptr);
1050     AddSpan(INIT_VALUE_1);
1051     EXPECT_EQ(richEditorPattern->GetTextContentLength(), 6);
1052 
1053     /**
1054      * @tc.steps: step2. request focus
1055      */
1056     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
1057     focusHub->RequestFocusImmediately();
1058 
1059     /**
1060      * @tc.step: step3. create a scene where the text menu has popped up
1061      */
1062     richEditorPattern->OnModifyDone();
1063     richEditorPattern->textSelector_.Update(1, 2);
1064     richEditorPattern->CalculateHandleOffsetAndShowOverlay();
1065     richEditorPattern->ShowSelectOverlay(
1066         richEditorPattern->textSelector_.firstHandle, richEditorPattern->textSelector_.secondHandle, false);
1067     EXPECT_TRUE(richEditorPattern->SelectOverlayIsOn());
1068 
1069     /**
1070      * @tc.step: step4. test OnMenuItemAction
1071      */
1072     richEditorPattern->selectOverlay_->OnMenuItemAction(OptionMenuActionId::COPY, OptionMenuType::TOUCH_MENU);
1073     EXPECT_EQ(richEditorPattern->textSelector_.GetTextStart(), 1);
1074     EXPECT_EQ(richEditorPattern->textSelector_.GetTextEnd(), 2);
1075 
1076     richEditorPattern->selectOverlay_->OnMenuItemAction(OptionMenuActionId::PASTE, OptionMenuType::NO_MENU);
1077     EXPECT_EQ(richEditorPattern->GetTextContentLength(), 6);
1078 
1079     Offset globalOffset;
1080     auto selectOverlayInfo = richEditorPattern->selectOverlay_->GetSelectOverlayInfo();
1081     auto selectInfoFirstHandle = selectOverlayInfo->firstHandle;
1082     auto selectInfoSecHandle = selectOverlayInfo->secondHandle;
1083     selectInfoFirstHandle.isShow = true;
1084     selectInfoSecHandle.isShow = true;
1085     richEditorPattern->HandleOnlyImageSelected(globalOffset, SourceTool::FINGER);
1086 
1087     selectInfoFirstHandle.isShow = false;
1088     selectInfoSecHandle.isShow = true;
1089     richEditorPattern->HandleOnlyImageSelected(globalOffset, SourceTool::FINGER);
1090 
1091     selectInfoFirstHandle.isShow = true;
1092     selectInfoSecHandle.isShow = true;
1093     richEditorPattern->HandleOnlyImageSelected(globalOffset, SourceTool::MOUSE);
1094 
1095     selectInfoFirstHandle.isShow = false;
1096     selectInfoSecHandle.isShow = true;
1097     richEditorPattern->HandleOnlyImageSelected(globalOffset, SourceTool::MOUSE);
1098 
1099     EXPECT_EQ(richEditorPattern->selectOverlay_->IsBothHandlesShow(), false);
1100 }
1101 
1102 /**
1103  * @tc.name: HandleBlurEvent001
1104  * @tc.desc: test HandleBlurEvent
1105  * @tc.type: FUNC
1106  */
1107 HWTEST_F(RichEditorPatternTestOneNg, HandleBlurEvent001, TestSize.Level1)
1108 {
1109     ASSERT_NE(richEditorNode_, nullptr);
1110     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1111     ASSERT_NE(richEditorPattern, nullptr);
1112     auto focusHub = richEditorNode_->GetOrCreateFocusHub();
1113     ASSERT_NE(focusHub, nullptr);
1114 
__anon5aaa9b0c0502() 1115     auto func = []() {};
1116 
1117     richEditorPattern->customKeyboardBuilder_ = func;
1118     richEditorPattern->isCustomKeyboardAttached_ = true;
1119     focusHub->blurReason_ = BlurReason::FRAME_DESTROY;
1120     richEditorPattern->HandleBlurEvent();
1121 
1122     richEditorPattern->customKeyboardBuilder_ = nullptr;
1123     richEditorPattern->isCustomKeyboardAttached_ = true;
1124     focusHub->blurReason_ = BlurReason::FRAME_DESTROY;
1125     richEditorPattern->HandleBlurEvent();
1126 
1127     richEditorPattern->customKeyboardBuilder_ = func;
1128     richEditorPattern->isCustomKeyboardAttached_ = true;
1129     focusHub->blurReason_ = BlurReason::WINDOW_BLUR;
1130     richEditorPattern->HandleBlurEvent();
1131 
1132     richEditorPattern->customKeyboardBuilder_ = nullptr;
1133     richEditorPattern->isCustomKeyboardAttached_ = true;
1134     focusHub->blurReason_ = BlurReason::WINDOW_BLUR;
1135     richEditorPattern->HandleBlurEvent();
1136     EXPECT_EQ(richEditorPattern->isMoveCaretAnywhere_, false);
1137 }
1138 
1139 /**
1140  * @tc.name: HandleFocusEvent001
1141  * @tc.desc: test HandleFocusEvent
1142  * @tc.type: FUNC
1143  */
1144 HWTEST_F(RichEditorPatternTestOneNg, HandleFocusEvent001, TestSize.Level1)
1145 {
1146     ASSERT_NE(richEditorNode_, nullptr);
1147     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1148     ASSERT_NE(richEditorPattern, nullptr);
1149 
1150     richEditorPattern->previewLongPress_ = true;
1151     richEditorPattern->HandleFocusEvent();
1152 
1153     richEditorPattern->previewLongPress_ = false;
1154     richEditorPattern->isCaretInContentArea_ = true;
1155 
1156     richEditorPattern->usingMouseRightButton_ = true;
1157     richEditorPattern->isLongPress_ = true;
1158     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = true;
1159     richEditorPattern->HandleFocusEvent();
1160 
1161     richEditorPattern->usingMouseRightButton_ = false;
1162     richEditorPattern->isLongPress_ = true;
1163     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = true;
1164     richEditorPattern->HandleFocusEvent();
1165 
1166     richEditorPattern->usingMouseRightButton_ = true;
1167     richEditorPattern->isLongPress_ = false;
1168     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = true;
1169     richEditorPattern->HandleFocusEvent();
1170 
1171     richEditorPattern->usingMouseRightButton_ = true;
1172     richEditorPattern->isLongPress_ = true;
1173     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = true;
1174     richEditorPattern->HandleFocusEvent();
1175 
1176     richEditorPattern->usingMouseRightButton_ = true;
1177     richEditorPattern->isLongPress_ = true;
1178     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = false;
1179     richEditorPattern->HandleFocusEvent();
1180 
1181     richEditorPattern->usingMouseRightButton_ = false;
1182     richEditorPattern->isLongPress_ = false;
1183     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = true;
1184     richEditorPattern->HandleFocusEvent();
1185 
1186     richEditorPattern->usingMouseRightButton_ = false;
1187     richEditorPattern->isLongPress_ = false;
1188     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = true;
1189     richEditorPattern->HandleFocusEvent();
1190 
1191     richEditorPattern->usingMouseRightButton_ = false;
1192     richEditorPattern->isLongPress_ = false;
1193     richEditorPattern->dataDetectorAdapter_->hasClickedMenuOption_ = false;
1194     richEditorPattern->HandleFocusEvent();
1195 
1196     EXPECT_EQ(richEditorPattern->textSelector_.SelectNothing(), true);
1197 }
1198 
1199 /**
1200  * @tc.name: CloseKeyboard001
1201  * @tc.desc: test CloseKeyboard
1202  * @tc.type: FUNC
1203  */
1204 HWTEST_F(RichEditorPatternTestOneNg, CloseKeyboard001, TestSize.Level1)
1205 {
1206     ASSERT_NE(richEditorNode_, nullptr);
1207     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1208     ASSERT_NE(richEditorPattern, nullptr);
1209 
1210     richEditorPattern->CloseKeyboard(false);
1211     EXPECT_EQ(richEditorPattern->HasConnection(), false);
1212 }
1213 
1214 /**
1215  * @tc.name: CalculateEmptyValueCaretRect002
1216  * @tc.desc: test CalculateEmptyValueCaretRect
1217  * @tc.type: FUNC
1218  */
1219 HWTEST_F(RichEditorPatternTestOneNg, CalculateEmptyValueCaretRect002, TestSize.Level1)
1220 {
1221     ASSERT_NE(richEditorNode_, nullptr);
1222     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1223     ASSERT_NE(richEditorPattern, nullptr);
1224 
1225     auto layoutProperty = richEditorPattern->GetLayoutProperty<TextLayoutProperty>();
1226 
1227     layoutProperty->UpdateLayoutDirection(TextDirection::RTL);
1228     layoutProperty->UpdateTextAlign(TextAlign::LEFT);
1229     richEditorPattern->CalculateEmptyValueCaretRect();
1230 
1231     layoutProperty->UpdateLayoutDirection(TextDirection::INHERIT);
1232     layoutProperty->UpdateTextAlign(TextAlign::CENTER);
1233     richEditorPattern->CalculateEmptyValueCaretRect();
1234 
1235     layoutProperty->UpdateLayoutDirection(TextDirection::INHERIT);
1236     layoutProperty->UpdateTextAlign(TextAlign::LEFT);
1237     richEditorPattern->CalculateEmptyValueCaretRect();
1238 
1239     EXPECT_EQ(richEditorPattern->presetParagraph_, false);
1240 }
1241 
1242 /**
1243  * @tc.name: HandleDoubleClickOrLongPress001
1244  * @tc.desc: test HandleDoubleClickOrLongPress
1245  * @tc.type: FUNC
1246  */
1247 HWTEST_F(RichEditorPatternTestOneNg, HandleDoubleClickOrLongPress001, TestSize.Level1)
1248 {
1249     ASSERT_NE(richEditorNode_, nullptr);
1250     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1251     ASSERT_NE(richEditorPattern, nullptr);
1252 
1253     GestureEvent info;
1254     info.SetSourceTool(SourceTool::FINGER);
1255     richEditorPattern->caretUpdateType_ = CaretUpdateType::DOUBLE_CLICK;
1256 
1257     richEditorPattern->previewTextRecord_.previewContent = "123";
1258     richEditorPattern->previewTextRecord_.isPreviewTextInputting = true;
1259     richEditorPattern->previewTextRecord_.startOffset = 0;
1260     richEditorPattern->previewTextRecord_.endOffset = 0;
1261     richEditorPattern->HandleDoubleClickOrLongPress(info);
1262 
1263     richEditorPattern->previewTextRecord_.previewContent = "123";
1264     richEditorPattern->previewTextRecord_.isPreviewTextInputting = false;
1265     richEditorPattern->previewTextRecord_.startOffset = 0;
1266     richEditorPattern->previewTextRecord_.endOffset = 0;
1267     richEditorPattern->status_ = Status::DRAGGING;
1268     richEditorPattern->HandleDoubleClickOrLongPress(info);
1269 
1270     richEditorPattern->status_ = Status::NONE;
1271     richEditorPattern->HandleDoubleClickOrLongPress(info);
1272 
1273     AddSpan("test");
1274     richEditorPattern->textSelector_.Update(3, 4);
1275     EXPECT_EQ(richEditorPattern->IsSelected(), true);
1276     richEditorPattern->HandleDoubleClickOrLongPress(info);
1277     EXPECT_EQ(richEditorPattern->IsSelected(), false);
1278 }
1279 
1280 /**
1281  * @tc.name: AdjustPlaceholderSelection001
1282  * @tc.desc: test AdjustPlaceholderSelection
1283  * @tc.type: FUNC
1284  */
1285 HWTEST_F(RichEditorPatternTestOneNg, AdjustPlaceholderSelection001, TestSize.Level1)
1286 {
1287     /**
1288      * @tc.steps: step1. init and call function.
1289      */
1290     ASSERT_NE(richEditorNode_, nullptr);
1291     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1292     ASSERT_NE(richEditorPattern, nullptr);
1293     richEditorPattern->CreateNodePaintMethod();
1294     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
1295     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
1296     AddSpan(INIT_VALUE_1);
1297     OHOS::Ace::RefPtr<OHOS::Ace::NG::SpanItem> spanItem1 = AceType::MakeRefPtr<ImageSpanItem>();
1298     richEditorPattern->spans_.emplace_back(spanItem1);
1299     OHOS::Ace::RefPtr<OHOS::Ace::NG::SpanItem> spanItem2 = AceType::MakeRefPtr<PlaceholderSpanItem>();
1300     richEditorPattern->spans_.emplace_back(spanItem2);
1301     OHOS::Ace::RefPtr<OHOS::Ace::NG::SpanItem> spanItem3 = AceType::MakeRefPtr<PlaceholderSpanItem>();
1302     richEditorPattern->spans_.emplace_back(spanItem3);
1303     auto paragraph = MockParagraph::GetOrCreateMockParagraph();
1304     ASSERT_NE(paragraph, nullptr);
1305     EXPECT_CALL(*paragraph, GetHeight()).WillRepeatedly(Return(300.0f));
1306     EXPECT_CALL(*paragraph, GetGlyphIndexByCoordinate(_, _)).WillRepeatedly(Return(6));
1307     TestParagraphRect paragraphRect = { .start = 0, .end = 6, .rects = { { 10.0, 20.0, 30.0, 40.0 } } };
1308     TestParagraphItem paragraphItem = { .start = 0, .end = 6, .testParagraphRects = { paragraphRect } };
1309     AddParagraph(paragraphItem);
1310     CaretMetricsF metrics = { { 10.0f, 50.0f }, 20.0f };
1311     EXPECT_CALL(*paragraph, ComputeOffsetForCaretUpstream(_, _, _))
1312         .WillRepeatedly(DoAll(SetArgReferee<1>(metrics), Return(true)));
1313     EXPECT_CALL(*paragraph, ComputeOffsetForCaretDownstream(_, _, _))
1314         .WillRepeatedly(DoAll(SetArgReferee<1>(metrics), Return(true)));
1315     TestParagraphRect paragraphRectSec = { .start = 7, .end = 12, .rects = { { 40.0, 50.0, 60.0, 70.0 } } };
1316     TestParagraphItem paragraphItemSec = { .start = 7, .end = 12, .testParagraphRects = { paragraphRectSec } };
1317     AddParagraph(paragraphItemSec);
1318     TestParagraphRect paragraphRectThi = { .start = 13, .end = 18, .rects = { { 80.0, 90.0, 100.0, 110.0 } } };
1319     TestParagraphItem paragraphItemThi = { .start = 13, .end = 18, .testParagraphRects = { paragraphRectThi } };
1320     AddParagraph(paragraphItemThi);
1321     /**
1322      * @tc.steps: step2. change parameter and call function.
1323      */
1324     int32_t start = 8;
1325     int32_t end = 10;
1326     Offset touchPos(8.0f, 350.0f);
1327     richEditorPattern->AdjustPlaceholderSelection(start, end, touchPos);
1328 
1329     for (auto iter : richEditorPattern->spans_) {
1330         iter->position = start;
1331     }
1332     richEditorPattern->AdjustPlaceholderSelection(start, end, touchPos);
1333     EXPECT_NE(start, end);
1334 }
1335 } // namespace OHOS::Ace::NG