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 
17 using namespace testing;
18 using namespace testing::ext;
19 
20 namespace OHOS::Ace::NG {
21 
22 class RichEditorEditTestOneNg : public RichEditorCommonTestNg {
23 public:
24     void SetUp() override;
25     void TearDown() override;
26     static void TearDownTestSuite();
27 };
28 
SetUp()29 void RichEditorEditTestOneNg::SetUp()
30 {
31     MockPipelineContext::SetUp();
32     MockContainer::SetUp();
33     MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
34     auto* stack = ViewStackProcessor::GetInstance();
35     auto nodeId = stack->ClaimNodeId();
36     richEditorNode_ = FrameNode::GetOrCreateFrameNode(
37         V2::RICH_EDITOR_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<RichEditorPattern>(); });
38     ASSERT_NE(richEditorNode_, nullptr);
39     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
40     richEditorPattern->InitScrollablePattern();
41     richEditorPattern->SetRichEditorController(AceType::MakeRefPtr<RichEditorController>());
42     richEditorPattern->GetRichEditorController()->SetPattern(AceType::WeakClaim(AceType::RawPtr(richEditorPattern)));
43     richEditorPattern->CreateNodePaintMethod();
44     richEditorNode_->GetGeometryNode()->SetContentSize({});
45 }
46 
TearDown()47 void RichEditorEditTestOneNg::TearDown()
48 {
49     richEditorNode_ = nullptr;
50     MockParagraph::TearDown();
51 }
52 
TearDownTestSuite()53 void RichEditorEditTestOneNg::TearDownTestSuite()
54 {
55     TestNG::TearDownTestSuite();
56 }
57 
58 /**
59  * @tc.name: GetRightTextOfCursor001
60  * @tc.desc: test GetRightTextOfCursor
61  * @tc.type: FUNC
62  */
63 HWTEST_F(RichEditorEditTestOneNg, GetRightTextOfCursor001, TestSize.Level1)
64 {
65     ASSERT_NE(richEditorNode_, nullptr);
66     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
67     richEditorPattern->textForDisplay_ = "tesol";
68     ASSERT_NE(richEditorPattern, nullptr);
69     richEditorPattern->caretPosition_ = 1;
70     richEditorPattern->textSelector_.baseOffset = 2;
71     richEditorPattern->textSelector_.destinationOffset = 3;
72     auto ret = StringUtils::Str16ToStr8(richEditorPattern->GetRightTextOfCursor(2));
73     EXPECT_EQ(ret, "ol");
74 
75     richEditorPattern->textSelector_.baseOffset = 2;
76     richEditorPattern->textSelector_.destinationOffset = 2;
77     ret = StringUtils::Str16ToStr8(richEditorPattern->GetRightTextOfCursor(2));
78     EXPECT_EQ(ret, "es");
79 }
80 
81 /**
82  * @tc.name: GetRightTextOfCursor002
83  * @tc.desc: test get right text of cursor
84  * @tc.type: FUNC
85  */
86 HWTEST_F(RichEditorEditTestOneNg, GetRightTextOfCursor002, TestSize.Level1)
87 {
88     ASSERT_NE(richEditorNode_, nullptr);
89     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
90     ASSERT_NE(richEditorPattern, nullptr);
91     AddSpan(INIT_VALUE_1);
92     auto ret = StringUtils::Str16ToStr8(richEditorPattern->GetRightTextOfCursor(3));
93     EXPECT_EQ(ret, "hel");
94 }
95 
96 /**
97  * @tc.name: GetTextIndexAtCursor001
98  * @tc.desc: test get text index at cursor
99  * @tc.type: FUNC
100  */
101 HWTEST_F(RichEditorEditTestOneNg, GetTextIndexAtCursor001, TestSize.Level1)
102 {
103     ASSERT_NE(richEditorNode_, nullptr);
104     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
105     ASSERT_NE(richEditorPattern, nullptr);
106     AddSpan(INIT_VALUE_1);
107     richEditorPattern->caretPosition_ = 3;
108     EXPECT_EQ(richEditorPattern->GetTextIndexAtCursor(), 3);
109 }
110 
111 /**
112  * @tc.name: GetSelectedSpanText002
113  * @tc.desc: test get select span text
114  * @tc.type: FUNC
115  */
116 HWTEST_F(RichEditorEditTestOneNg, GetSelectedSpanText002, TestSize.Level1)
117 {
118     ASSERT_NE(richEditorNode_, nullptr);
119     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
120     ASSERT_NE(richEditorPattern, nullptr);
121 
122     auto ret = richEditorPattern->GetSelectedSpanText(StringUtils::ToWstring(INIT_VALUE_1), -1, 1);
123     ret = richEditorPattern->GetSelectedSpanText(StringUtils::ToWstring(INIT_VALUE_1), -1, 10);
124     ret = richEditorPattern->GetSelectedSpanText(StringUtils::ToWstring(INIT_VALUE_1), 0, 1);
125     EXPECT_EQ(ret, "h");
126 }
127 
128 /**
129  * @tc.name: GetChildByIndex002
130  * @tc.desc: test get child by index
131  * @tc.type: FUNC
132  */
133 HWTEST_F(RichEditorEditTestOneNg, GetChildByIndex002, TestSize.Level1)
134 {
135     ASSERT_NE(richEditorNode_, nullptr);
136     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
137     ASSERT_NE(richEditorPattern, nullptr);
138     richEditorPattern->GetChildByIndex(-1);
139     AddSpan(INIT_VALUE_1);
140     auto ret = richEditorPattern->GetChildByIndex(0);
141     EXPECT_EQ(*(richEditorNode_->GetChildren().begin()), ret);
142 }
143 
144 /**
145  * @tc.name: GetChildByIndex001
146  * @tc.desc: test GetChildByIndex
147  * @tc.type: FUNC
148  */
149 HWTEST_F(RichEditorEditTestOneNg, GetChildByIndex001, TestSize.Level1)
150 {
151     ASSERT_NE(richEditorNode_, nullptr);
152     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
153     ASSERT_NE(richEditorPattern, nullptr);
154     richEditorPattern->caretPosition_ = 0;
155     AddSpan(INIT_VALUE_1);
156     auto ret1 = richEditorPattern->GetChildByIndex(1);
157     EXPECT_EQ(ret1, nullptr);
158     auto ret2 = richEditorPattern->GetChildByIndex(-1);
159     EXPECT_EQ(ret2, nullptr);
160     auto ret3 = richEditorPattern->GetChildByIndex(0);
161     EXPECT_NE(ret3, nullptr);
162 }
163 
164 /**
165  * @tc.name: GetSelectedSpanText001
166  * @tc.desc: test GetSelectedSpanText
167  * @tc.type: FUNC
168  */
169 HWTEST_F(RichEditorEditTestOneNg, GetSelectedSpanText001, TestSize.Level1)
170 {
171     ASSERT_NE(richEditorNode_, nullptr);
172     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
173     ASSERT_NE(richEditorPattern, nullptr);
174     std::string ori = "12345";
175     std::wstring value = StringUtils::ToWstring(ori);
176 
177     std::vector<int> start = { -1, 0, 15 };
178     std::vector<int> end = { 10, -3 };
179 
180     for (int i = 0; i < 3; ++i) {
181         for (int j = 0; j < 2; ++j) {
182             auto ret = richEditorPattern->GetSelectedSpanText(value, start[i], end[j]);
183             EXPECT_EQ(ret, "");
184         }
185     }
186 
187     auto ret = richEditorPattern->GetSelectedSpanText(value, 0, 1);
188     EXPECT_EQ(ret, "1");
189 }
190 
191 /**
192  * @tc.name: CreateNodePaintMethod001
193  * @tc.desc: test CreateNodePaintMethod
194  * @tc.type: FUNC
195  */
196 HWTEST_F(RichEditorEditTestOneNg, CreateNodePaintMethod001, TestSize.Level1)
197 {
198     ASSERT_NE(richEditorNode_, nullptr);
199     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
200     ASSERT_NE(richEditorPattern, nullptr);
201     richEditorPattern->CreateNodePaintMethod();
202     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
203     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
204 }
205 
206 /**
207  * @tc.name: CreateNodePaintMethod002
208  * @tc.desc: test CreateNodePaintMethod
209  * @tc.type: FUNC
210  */
211 HWTEST_F(RichEditorEditTestOneNg, CreateNodePaintMethod002, TestSize.Level1)
212 {
213     ASSERT_NE(richEditorNode_, nullptr);
214     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
215     ASSERT_NE(richEditorPattern, nullptr);
216     richEditorPattern->contentMod_ = AceType::MakeRefPtr<RichEditorContentModifier>(
217         richEditorPattern->textStyle_, &richEditorPattern->paragraphs_, richEditorPattern);
218     richEditorPattern->isCustomFont_ = true;
219     richEditorPattern->CreateNodePaintMethod();
220     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
221     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
222 }
223 
224 /**
225  * @tc.name: GetSpanItemByIndex001
226  * @tc.desc: test GetSpanItemByIndex
227  * @tc.type: FUNC
228  */
229 HWTEST_F(RichEditorEditTestOneNg, GetSpanItemByIndex001, TestSize.Level1)
230 {
231     ASSERT_NE(richEditorNode_, nullptr);
232     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
233     ASSERT_NE(richEditorPattern, nullptr);
234     richEditorPattern->spans_.push_front(AceType::MakeRefPtr<SpanItem>());
235     auto ret = richEditorPattern->GetSpanItemByIndex(-1);
236     EXPECT_EQ(ret, nullptr);
237     ret = richEditorPattern->GetSpanItemByIndex(1);
238     EXPECT_EQ(ret, nullptr);
239     ret = richEditorPattern->GetSpanItemByIndex(0);
240     EXPECT_EQ(ret, richEditorPattern->spans_.front());
241 }
242 
243 /**
244  * @tc.name: DeleteValueSetTextSpan
245  * @tc.desc: test add delete text span
246  * @tc.type: FUNC
247  */
248 HWTEST_F(RichEditorEditTestOneNg, DeleteValueSetTextSpan, TestSize.Level1)
249 {
250     /**
251      * @tc.steps: step1. get richEditor controller
252      */
253     ASSERT_NE(richEditorNode_, nullptr);
254     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
255     ASSERT_NE(richEditorPattern, nullptr);
256     auto richEditorController = richEditorPattern->GetRichEditorController();
257     ASSERT_NE(richEditorController, nullptr);
258 
259     /**
260      * @tc.steps: step2. test add span
261      */
262     AddSpan(INIT_VALUE_1);
263     struct UpdateParagraphStyle style1;
264     style1.textAlign = TextAlign::END;
265     style1.leadingMargin = std::make_optional<NG::LeadingMargin>();
266     style1.leadingMargin->size = LeadingMarginSize(Dimension(5.0), Dimension(10.0));
267     richEditorPattern->UpdateParagraphStyle(0, 6, style1);
268     auto info = richEditorController->GetSpansInfo(0, 6);
269     EXPECT_EQ(info.selection_.resultObjects.size(), 1);
270 
271     auto it = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
272     auto spanItem = it->GetSpanItem();
273     spanItem->position = 0;
274     spanItem->textStyle_ = TextStyle();
275     spanItem->textStyle_.value().fontFamilies_.push_back("test1");
276     RichEditorAbstractSpanResult spanResult;
277     spanResult.SetSpanIndex(0);
278     richEditorPattern->DeleteValueSetTextSpan(spanItem, 0, 1, spanResult);
279 
280     EXPECT_EQ(spanResult.GetTextStyle().textAlign, int(TextAlign::END));
281     EXPECT_EQ(spanResult.GetTextStyle().leadingMarginSize[0], "5.00px");
282     EXPECT_EQ(spanResult.GetTextStyle().leadingMarginSize[1], "10.00px");
283 
284     ClearSpan();
285 }
286 
287 /**
288  * @tc.name: DeleteValueSetImageSpan
289  * @tc.desc: test delete imagespan
290  * @tc.type: FUNC
291  */
292 HWTEST_F(RichEditorEditTestOneNg, DeleteValueSetImageSpan, TestSize.Level1)
293 {
294     /**
295      * @tc.steps: step1. get richEditor controller
296      */
297     ASSERT_NE(richEditorNode_, nullptr);
298     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
299     ASSERT_NE(richEditorPattern, nullptr);
300     auto richEditorController = richEditorPattern->GetRichEditorController();
301     ASSERT_NE(richEditorController, nullptr);
302 
303     /**
304      * @tc.steps: step2. initalize span properties
305      */
306     ImageSpanOptions options;
307     options.image = IMAGE_VALUE;
308     std::optional<Ace::NG::MarginProperty> marginProp = std::nullopt;
309     std::optional<Ace::NG::BorderRadiusProperty> borderRadius = std::nullopt;
310     marginProp = { CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC, CALC_LENGTH_CALC };
311     borderRadius = { CALC_TEST, CALC_TEST, CALC_TEST, CALC_TEST };
312     ImageSpanAttribute imageStyle;
313     imageStyle.marginProp = marginProp;
314     imageStyle.borderRadius = borderRadius;
315     options.imageAttribute = imageStyle;
316 
317     /**
318      * @tc.steps: step3. test delete image span
319      */
320     richEditorController->AddImageSpan(options);
321     RichEditorAbstractSpanResult spanResult;
322     spanResult.SetSpanIndex(0);
323     auto spanItem = richEditorPattern->spans_.front();
324     richEditorPattern->DeleteValueSetImageSpan(spanItem, spanResult);
325     EXPECT_EQ(spanResult.GetMargin(), marginProp->ToString());
326     EXPECT_EQ(spanResult.GetBorderRadius(),
327         "{\"topLeft\":\"10.00px\",\"topRight\":\"10.00px\",\"bottomLeft\":\"10.00px\",\"bottomRight\":\"10.00px\"}");
328 
329     ClearSpan();
330 }
331 
332 /**
333  * @tc.name: CheckEditorTypeChange001
334  * @tc.desc: test CheckEditorTypeChange
335  * @tc.type: FUNC
336  */
337 HWTEST_F(RichEditorEditTestOneNg, CheckEditorTypeChange001, TestSize.Level1)
338 {
339     ASSERT_NE(richEditorNode_, nullptr);
340     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
341     auto pipeline = PipelineContext::GetCurrentContextSafely();
342     SelectOverlayInfo selectOverlayInfo;
343     int32_t singleLineHeight = 143;
344     selectOverlayInfo.singleLineHeight = singleLineHeight;
345     CHECK_NULL_VOID(pipeline);
346     auto host = richEditorPattern->GetHost();
347     CHECK_NULL_VOID(host);
348     pipeline->AddOnAreaChangeNode(host->GetId());
349 
350     richEditorPattern->selectOverlayProxy_ =
351         pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay(selectOverlayInfo, nullptr);
352     EXPECT_EQ(richEditorPattern->GetEditorType(), TextSpanType::NONE);
353 }
354 
355 /**
356  * @tc.name: InsertValueByPaste001
357  * @tc.desc: test InsertValueByPaste
358  * @tc.type: FUNC
359  */
360 HWTEST_F(RichEditorEditTestOneNg, InsertValueByPaste001, TestSize.Level1)
361 {
362     /**
363      * @tc.steps: step1. create textFrameNode.
364      */
365     ASSERT_NE(richEditorNode_, nullptr);
366     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
367     auto textFrameNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, 0, AceType::MakeRefPtr<TextPattern>());
368     ASSERT_NE(textFrameNode, nullptr);
369     RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
370     ASSERT_NE(geometryNode, nullptr);
371     RefPtr<LayoutWrapperNode> layoutWrapper =
372         AceType::MakeRefPtr<LayoutWrapperNode>(textFrameNode, geometryNode, textFrameNode->GetLayoutProperty());
373     auto textPattern = textFrameNode->GetPattern<TextPattern>();
374     ASSERT_NE(textPattern, nullptr);
375 
376     /**
377      * @tc.steps: step2. construct spanItem_.
378      */
379     textPattern->isSpanStringMode_ = true;
380 
381     auto pasteStr = richEditorPattern->GetPasteStr();
382     richEditorPattern->InsertValueByPaste(pasteStr);
383 
384     richEditorPattern->OnAreaChangedInner();
385     OffsetF Offset = {1, 2};
386     EXPECT_NE(richEditorPattern->GetPaintRectGlobalOffset(), Offset);
387 }
388 
389 /**
390  * @tc.name: GetThumbnailCallback001
391  * @tc.desc: test GetThumbnailCallback
392  * @tc.type: FUNC
393  */
394 HWTEST_F(RichEditorEditTestOneNg, GetThumbnailCallback001, TestSize.Level1)
395 {
396     ASSERT_NE(richEditorNode_, nullptr);
397     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
398     auto host = richEditorPattern->GetHost();
399     CHECK_NULL_VOID(host);
400     auto gestureHub = host->GetOrCreateGestureEventHub();
401     CHECK_NULL_VOID(gestureHub);
402 
403     gestureHub->InitDragDropEvent();
404     gestureHub->SetThumbnailCallback(richEditorPattern->GetThumbnailCallback());
405     EXPECT_EQ(richEditorPattern->dragNode_, nullptr);
406 }
407 
408 /**
409  * @tc.name: SetSelection001
410  * @tc.desc: test SetSelection
411  * @tc.type: FUNC
412  */
413 HWTEST_F(RichEditorEditTestOneNg, SetSelection001, TestSize.Level1)
414 {
415     ASSERT_NE(richEditorNode_, nullptr);
416     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
417     ASSERT_NE(richEditorPattern, nullptr);
418     richEditorPattern->DumpInfo();
419 
420     auto pipeline = PipelineContext::GetCurrentContext();
421     auto theme = AceType::MakeRefPtr<MockThemeManager>();
422     pipeline->SetThemeManager(theme);
423 
424     richEditorPattern->isTextChange_ = false;
425     EXPECT_EQ(richEditorPattern->IsShowHandle(), false);
426 
427     auto manager = AceType::MakeRefPtr<TextFieldManagerNG>();
428     richEditorPattern->ScrollToSafeArea();
429     EXPECT_EQ(LessNotEqual(manager->GetHeight(), 800.0f), true);
430 
431     richEditorPattern->InitScrollablePattern();
432     EXPECT_EQ(richEditorPattern->GetScrollBar(), true);
433 
434     richEditorPattern->overlayMod_ = AceType::MakeRefPtr<TextOverlayModifier>();
435     richEditorPattern->InitScrollablePattern();
436     EXPECT_EQ(richEditorPattern->GetScrollBar(), true);
437 
438     Offset Offset = {1, 4};
439     richEditorPattern->isTextChange_ = true;
440     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
441     EXPECT_EQ(richEditorPattern->HasFocus(), false);
442 
443     richEditorPattern->isTextChange_ = false;
444     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
445     EXPECT_EQ(richEditorPattern->HasFocus(), false);
446 
447     richEditorPattern->caretUpdateType_ = CaretUpdateType::DOUBLE_CLICK;
448     richEditorPattern->sourceType_ = SourceType::MOUSE;
449     int32_t index = 1;
450     richEditorPattern->MouseDoubleClickParagraphEnd(index);
451     EXPECT_NE(richEditorPattern->GetParagraphEndPosition(index), index);
452 
453     SelectionOptions options;
454     options.menuPolicy = MenuPolicy::SHOW;
455     richEditorPattern->HandleSelectOverlayWithOptions(options);
456     EXPECT_EQ(richEditorPattern->selectionMenuOffsetByMouse_.GetX(),
457         richEditorPattern->selectionMenuOffsetByMouse_.GetX());
458 
459     int32_t start = 1;
460     int32_t end = 3;
461     richEditorPattern->SetSelection(start, end, options);
462     EXPECT_NE(richEditorPattern->textSelector_.GetStart(), start);
463 
464     options.menuPolicy = MenuPolicy::HIDE;
465     richEditorPattern->HandleSelectOverlayWithOptions(options);
466     EXPECT_EQ(richEditorPattern->selectionMenuOffsetByMouse_.GetX(),
467         richEditorPattern->selectionMenuOffsetByMouse_.GetX());
468 
469     richEditorPattern->SetSelection(start, end, options);
470     EXPECT_NE(richEditorPattern->textSelector_.GetEnd(), end);
471 
472     options.menuPolicy = MenuPolicy::DEFAULT;
473     richEditorPattern->SetSelection(start, end, options);
474     EXPECT_NE(richEditorPattern->textSelector_.GetEnd(), end);
475 }
476 
477 /**
478  * @tc.name: CreateHandles001
479  * @tc.desc: test CreateHandles
480  * @tc.type: FUNC
481  */
482 HWTEST_F(RichEditorEditTestOneNg, CreateHandles001, TestSize.Level1)
483 {
484     ASSERT_NE(richEditorNode_, nullptr);
485     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
486     richEditorPattern->textForDisplay_ = "testShowHandles";
487     ASSERT_NE(richEditorPattern, nullptr);
488     richEditorPattern->caretPosition_ = 1;
489     richEditorPattern->textSelector_.baseOffset = 1;
490     richEditorPattern->textSelector_.destinationOffset = 3;
491 
492     richEditorPattern->CreateHandles();
493     auto offsetF = OffsetF(0.0f, 0.0f);
494     EXPECT_EQ(richEditorPattern->textSelector_.selectionBaseOffset, offsetF);
495 
496     richEditorPattern->ShowHandles(false);
497     EXPECT_NE(richEditorPattern->showSelect_, false);
498 
499     richEditorPattern->ShowHandles(true);
500     EXPECT_EQ(richEditorPattern->showSelect_, true);
501 
502     Offset textOffset = {1, 3};
503     EXPECT_NE(richEditorPattern->BetweenSelection(textOffset), true);
504 
505     richEditorPattern->CloseHandleAndSelect();
506     EXPECT_EQ(richEditorPattern->showSelect_, false);
507 }
508 
509 /**
510  * @tc.name: RefreshSelectOverlay001
511  * @tc.desc: test RefreshSelectOverlay and more.
512  * @tc.type: FUNC
513  */
514 HWTEST_F(RichEditorEditTestOneNg, RefreshSelectOverlay001, TestSize.Level1)
515 {
516     ASSERT_NE(richEditorNode_, nullptr);
517     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
518     ASSERT_NE(richEditorPattern, nullptr);
519 
520     int32_t posx = 1;
521     int32_t posy = 3;
522     richEditorPattern->HandleSurfacePositionChanged(posx, posy);
523     EXPECT_EQ(richEditorPattern->HasFocus(), false);
524 
525     richEditorPattern->RefreshSelectOverlay(true, false);
526     EXPECT_EQ(richEditorPattern->textSelector_.firstHandle, RectF(0, 0, 0, 0));
527 
528     EXPECT_EQ(richEditorPattern->IsHandlesShow(), false);
529 
530     auto pipeline = PipelineContext::GetCurrentContext();
531     auto theme = AceType::MakeRefPtr<MockThemeManager>();
532     EXPECT_CALL(*theme, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<RichEditorTheme>()));
533     pipeline->themeManager_ = theme;
534 
__anon93c694140202() 535     richEditorPattern->customKeyboardBuilder_ = []() {};
536     richEditorPattern->DumpInfo();
537     richEditorPattern->isTextChange_ = false;
538     EXPECT_EQ(richEditorPattern->IsShowHandle(), true);
539 
540     richEditorPattern->selectOverlay_->SetUsingMouse(false);
541     richEditorPattern->UpdateSelectionInfo(posx, posy);
542     EXPECT_EQ(richEditorPattern->sourceType_, SourceType::TOUCH);
543 
544     richEditorPattern->InitScrollablePattern();
545     EXPECT_EQ(richEditorPattern->GetScrollBar(), true);
546 
547     richEditorPattern->overlayMod_ = AceType::MakeRefPtr<TextOverlayModifier>();
548     richEditorPattern->InitScrollablePattern();
549     EXPECT_EQ(richEditorPattern->GetScrollBar(), true);
550 
551     Offset Offset = {1, 4};
552     richEditorPattern->isTextChange_ = true;
553     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
554     EXPECT_EQ(richEditorPattern->HasFocus(), false);
555 
556     richEditorPattern->isTextChange_ = false;
557     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
558     EXPECT_EQ(richEditorPattern->HasFocus(), false);
559 }
560 
561 /**
562  * @tc.name: ShowHandles001
563  * @tc.desc: test ShowHandles
564  * @tc.type: FUNC
565  */
566 HWTEST_F(RichEditorEditTestOneNg, ShowHandles001, TestSize.Level1)
567 {
568     ASSERT_NE(richEditorNode_, nullptr);
569     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
570     ASSERT_NE(richEditorPattern, nullptr);
571 
572     richEditorPattern->status_ = Status::DRAGGING;
573     richEditorPattern->CreateHandles();
574     auto offsetF = OffsetF(0.0f, 0.0f);
575     EXPECT_EQ(richEditorPattern->textSelector_.selectionBaseOffset, offsetF);
576 
577     richEditorPattern->contentChange_ = true;
578     richEditorPattern->keyboardAvoidance_ = true;
579     EXPECT_EQ(richEditorPattern->GetCrossOverHeight(), 0.0f);
580 
581     AddImageSpan();
582     richEditorPattern->textSelector_.baseOffset = 0;
583     richEditorPattern->textSelector_.destinationOffset = 1;
584     richEditorPattern->ShowHandles(false);
585     EXPECT_EQ(richEditorPattern->showSelect_, true);
586 
587     richEditorPattern->isSpanStringMode_ = true;
588     auto pasteStr = richEditorPattern->GetPasteStr();
589     richEditorPattern->InsertValueByPaste(pasteStr);
590     EXPECT_EQ(richEditorPattern->caretVisible_, true);
591 
592     richEditorPattern->GetThumbnailCallback();
593     EXPECT_EQ(richEditorPattern->dragNode_, nullptr);
594 }
595 
596 /**
597  * @tc.name: HandleOnPaste001
598  * @tc.desc: test HandleOnPaste
599  * @tc.type: FUNC
600  */
601 HWTEST_F(RichEditorEditTestOneNg, HandleOnPaste001, TestSize.Level1)
602 {
603     ASSERT_NE(richEditorNode_, nullptr);
604     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
605     ASSERT_NE(richEditorPattern, nullptr);
606     auto pipeline = MockPipelineContext::GetCurrent();
607     auto clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
608     richEditorPattern->clipboard_ = clipboard;
609     AddSpan("testHandleOnPaste1");
610     richEditorPattern->HandleOnPaste();
611     richEditorPattern->textSelector_.baseOffset = 0;
612     richEditorPattern->textSelector_.destinationOffset = 8;
613     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
614 
615     ClearSpan();
616     AddImageSpan();
617     richEditorPattern->textSelector_.baseOffset = 0;
618     richEditorPattern->textSelector_.destinationOffset = 1;
619     richEditorPattern->OnCopyOperation(true);
620     EXPECT_EQ(richEditorPattern->textSelector_.baseOffset, 0);
621 }
622 
623 /**
624  * @tc.name: HandleAIWrite001
625  * @tc.desc: test GetAIWriteInfo
626  * @tc.type: FUNC
627  */
628 HWTEST_F(RichEditorEditTestOneNg, HandleAIWrite001, TestSize.Level1)
629 {
630     ASSERT_NE(richEditorNode_, nullptr);
631     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
632     ASSERT_NE(richEditorPattern, nullptr);
633     auto richEditorController = richEditorPattern->GetRichEditorController();
634     ASSERT_NE(richEditorController, nullptr);
635 
636     TextSpanOptions options;
637     options.value = INIT_VALUE_3;
638     richEditorController->AddTextSpan(options);
639 
640     richEditorPattern->textSelector_.Update(0, 5);
641     AIWriteInfo info;
642     richEditorPattern->GetAIWriteInfo(info);
643     EXPECT_EQ(info.selectStart, 0);
644     EXPECT_EQ(info.selectEnd, 5);
645     EXPECT_EQ(info.selectLength, 5);
646     EXPECT_EQ(info.firstHandle, richEditorPattern->textSelector_.firstHandle.ToString());
647     EXPECT_EQ(info.secondHandle, richEditorPattern->textSelector_.secondHandle.ToString());
648     RefPtr<SpanString> spanString = SpanString::DecodeTlv(info.selectBuffer);
649     ASSERT_NE(spanString, nullptr);
650     auto textContent = spanString->GetString();
651     EXPECT_EQ(textContent.empty(), false);
652 }
653 
654 /**
655  * @tc.name: HandleAIWrite001
656  * @tc.desc: test HandleOnAIWrite
657  * @tc.type: FUNC
658  */
659 HWTEST_F(RichEditorEditTestOneNg, HandleAIWrite002, TestSize.Level1)
660 {
661     ASSERT_NE(richEditorNode_, nullptr);
662     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
663     ASSERT_NE(richEditorPattern, nullptr);
664     auto richEditorController = richEditorPattern->GetRichEditorController();
665     ASSERT_NE(richEditorController, nullptr);
666 
667     TextSpanOptions options;
668     options.value = INIT_VALUE_3;
669     richEditorController->AddTextSpan(options);
670     richEditorPattern->textSelector_.Update(0, 5);
671     richEditorPattern->HandleOnAIWrite();
672     auto start = richEditorPattern->operationRecords_.size();
673 
674     std::vector<uint8_t> buff;
675     auto spanStr = AceType::MakeRefPtr<SpanString>("dddd结果回填123456");
676     spanStr->EncodeTlv(buff);
677     richEditorPattern->HandleAIWriteResult(0, 5, buff);
678     EXPECT_EQ(richEditorPattern->operationRecords_.size(), start + 3);
679 }
680 
681 /**
682  * @tc.name: HandleAIWrite001
683  * @tc.desc: test AddSpansAndReplacePlaceholder&SetSubSpansWithAIWrite
684  * @tc.type: FUNC
685  */
686 HWTEST_F(RichEditorEditTestOneNg, HandleAIWrite003, TestSize.Level1)
687 {
688     /**
689      * @tc.steps: step1. get richEditor controller
690      */
691     ASSERT_NE(richEditorNode_, nullptr);
692     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
693     ASSERT_NE(richEditorPattern, nullptr);
694     auto richEditorController = richEditorPattern->GetRichEditorController();
695     ASSERT_NE(richEditorController, nullptr);
696 
697     /**
698      * @tc.steps: step2. add span
699      */
700     SymbolSpanOptions options1;
701     options1.symbolId = SYMBOL_ID;
702     TextSpanOptions options2;
703     options2.value = INIT_VALUE_1;
704     ImageSpanOptions options3;
705     options3.image = IMAGE_VALUE;
706     auto builderId1 = ElementRegister::GetInstance()->MakeUniqueId();
707     auto builderNode1 = FrameNode::GetOrCreateFrameNode(
__anon93c694140302() 708         V2::ROW_ETS_TAG, builderId1, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(false); });
709     auto index1 = richEditorController->AddPlaceholderSpan(builderNode1, {});
710     EXPECT_EQ(index1, 0);
711     richEditorController->AddTextSpan(options2);
712     richEditorController->AddSymbolSpan(options1);
713     richEditorController->AddTextSpan(options2);
714     richEditorController->AddImageSpan(options3);
715     EXPECT_EQ(static_cast<int32_t>(richEditorNode_->GetChildren().size()), 5);
716 
717     /**
718      * @tc.steps: step3. replace and recover placeholder for non-text.
719      */
720     RefPtr<SpanString> spanString = AceType::MakeRefPtr<SpanString>("");
721     ASSERT_NE(spanString, nullptr);
722     richEditorPattern->SetSubSpansWithAIWrite(spanString, 0, 12);
723     auto spanStr = AceType::MakeRefPtr<SpanString>("test![id1]占位符![id2]");
724     richEditorPattern->textSelector_.Update(0, 10);
725     auto start = richEditorPattern->operationRecords_.size();
726     richEditorPattern->AddSpansAndReplacePlaceholder(spanStr);
727     EXPECT_EQ(richEditorPattern->operationRecords_.size(), start + 4);
728 }
729 
730 /**
731  * @tc.name: GetTextBoxes001
732  * @tc.desc: test GetTextBoxes
733  * @tc.type: FUNC
734  */
735 HWTEST_F(RichEditorEditTestOneNg, GetTextBoxes001, TestSize.Level1)
736 {
737     ASSERT_NE(richEditorNode_, nullptr);
738     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
739     richEditorPattern->textForDisplay_ = "testShowHandles";
740     ASSERT_NE(richEditorPattern, nullptr);
741     richEditorPattern->caretPosition_ = 1;
742     richEditorPattern->textSelector_.baseOffset = 1;
743     richEditorPattern->textSelector_.destinationOffset = 3;
744 
745     std::vector<RectF> res;
746     auto ret = richEditorPattern->GetTextBoxes();
747     EXPECT_EQ(ret, res);
748 
749 
750     TextLineMetrics lineMetrics;
751     richEditorPattern->GetLineCount();
752     EXPECT_EQ(richEditorPattern->GetLineHeight(), 0.0f);
753     EXPECT_EQ(richEditorPattern->GetLetterSpacing(), 0.0f);
754     auto retLineMetrics = richEditorPattern->GetLineMetrics(-1);
755     EXPECT_EQ(retLineMetrics.x, 0);
756 
757     auto retLineMetricsS = richEditorPattern->GetLineMetrics(2);
758     EXPECT_EQ(retLineMetricsS.x, 0);
759 
760     int32_t scroll_from_update = 1;
761     richEditorPattern->richTextRect_ = RectF(0, 4, 100, 140);
762     richEditorPattern->contentRect_ = RectF(0, 1, 100, 160);
763     richEditorPattern->UpdateScrollStateAfterLayout(true);
764     EXPECT_FALSE(richEditorPattern->OnScrollCallback(10, scroll_from_update)) << "Reach Top Boundary";
765 
766     EXPECT_EQ(richEditorPattern->MoveTextRect(0.0f), 0.0f);
767 
768     auto offsetF = OffsetF(0.0f, 0.5f);
769     richEditorPattern->MoveCaretToContentRect(offsetF, 8.0f);
770     EXPECT_EQ(richEditorPattern->GetTextRect(), richEditorPattern->richTextRect_);
771 
772     richEditorPattern->MoveCaretToContentRect(1.0f, 10);
773     EXPECT_EQ(richEditorPattern->GetTextRect(), richEditorPattern->richTextRect_);
774 
775     richEditorPattern->contentChange_ = true;
776     EXPECT_EQ(richEditorPattern->GetCrossOverHeight(), 0.0f);
777 }
778 
779 /**
780  * @tc.name: UpdateTextStyle
781  * @tc.desc: test update span style
782  * @tc.type: FUNC
783  */
784 HWTEST_F(RichEditorEditTestOneNg, UpdateTextStyle, TestSize.Level1)
785 {
786     ASSERT_NE(richEditorNode_, nullptr);
787     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
788     ASSERT_NE(richEditorPattern, nullptr);
789     auto richEditorController = richEditorPattern->GetRichEditorController();
790     ASSERT_NE(richEditorController, nullptr);
791     AddSpan(INIT_VALUE_1);
792     auto newSpan1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
793     TextStyle textStyle;
794     ImageSpanAttribute imageStyle;
795     textStyle.SetFontFeatures(TEXT_FONTFEATURE);
796     textStyle.SetLineHeight(LINE_HEIGHT_VALUE);
797     textStyle.SetLetterSpacing(LETTER_SPACING);
798 
799     struct UpdateSpanStyle updateSpanStyle;
800     updateSpanStyle.updateLineHeight = LINE_HEIGHT_VALUE;
801     updateSpanStyle.updateLetterSpacing = LETTER_SPACING;
802     updateSpanStyle.updateFontFeature = TEXT_FONTFEATURE;
803 
804     richEditorPattern->UpdateTextStyle(newSpan1, updateSpanStyle, textStyle);
805     ASSERT_NE(newSpan1, nullptr);
806     EXPECT_EQ(newSpan1->GetLineHeight(), LINE_HEIGHT_VALUE);
807     EXPECT_EQ(newSpan1->GetLetterSpacing(), LETTER_SPACING);
808     for (const auto& pair : *newSpan1->GetFontFeature()) {
809         EXPECT_EQ(pair.first, "subs");
810         EXPECT_EQ(pair.second, 1);
811     }
812     ClearSpan();
813 }
814 
815 /**
816  * @tc.name: UpdateTextStyle
817  * @tc.desc: test update span style
818  * @tc.type: FUNC
819  */
820 HWTEST_F(RichEditorEditTestOneNg, UpdateTextStyle2, TestSize.Level1)
821 {
822     ASSERT_NE(richEditorNode_, nullptr);
823     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
824     ASSERT_NE(richEditorPattern, nullptr);
825     auto richEditorController = richEditorPattern->GetRichEditorController();
826     ASSERT_NE(richEditorController, nullptr);
827     AddSpan(INIT_VALUE_1);
828     auto newSpan1 = AceType::DynamicCast<SpanNode>(richEditorNode_->GetChildAtIndex(0));
829     TextStyle textStyle;
830     ImageSpanAttribute imageStyle;
831     textStyle.SetFontFeatures(TEXT_FONTFEATURE_2);
832     struct UpdateSpanStyle updateSpanStyle;
833     updateSpanStyle.updateFontFeature = TEXT_FONTFEATURE;
834     richEditorPattern->UpdateTextStyle(newSpan1, updateSpanStyle, textStyle);
835     ASSERT_NE(newSpan1, nullptr);
836     for (const auto& pair : *newSpan1->GetFontFeature()) {
837         EXPECT_EQ(pair.first, "subs");
838         EXPECT_EQ(pair.second, 0);
839     }
840     ClearSpan();
841 }
842 
843 /**
844  * @tc.name: SetTypingStyle
845  * @tc.desc: test Typing Style
846  * @tc.type: FUNC
847  */
848 HWTEST_F(RichEditorEditTestOneNg, SetTypingStyle, TestSize.Level1)
849 {
850     /**
851      * @tc.steps: step1. get richEditor controller
852      */
853     ASSERT_NE(richEditorNode_, nullptr);
854     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
855     ASSERT_NE(richEditorPattern, nullptr);
856     auto richEditorController = richEditorPattern->GetRichEditorController();
857     ASSERT_NE(richEditorController, nullptr);
858     TextStyle style;
859     style.SetLineHeight(LINE_HEIGHT_VALUE);
860     style.SetLetterSpacing(LETTER_SPACING);
861     style.SetFontFeatures(TEXT_FONTFEATURE);
862     TextSpanOptions options;
863     options.value = INIT_VALUE_1;
864     options.style = style;
865     richEditorController->AddTextSpan(options);
866     AddSpan(INIT_VALUE_1);
867     auto info = richEditorController->GetSpansInfo(1, 5);
868     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
869     UpdateSpanStyle typingStyle;
870     richEditorPattern->SetTypingStyle(typingStyle, style);
871     TextSpanOptions options1;
872     options1.style = richEditorPattern->typingTextStyle_;
873     AddSpan(INIT_VALUE_1);
874     auto info1 = richEditorController->GetSpansInfo(1, 5);
875     TextStyleResult textStyle2 = info1.selection_.resultObjects.front().textStyle;
876     EXPECT_EQ(textStyle2.lineHeight, LINE_HEIGHT_VALUE.ConvertToVp());
877     EXPECT_EQ(textStyle2.letterSpacing, LETTER_SPACING.ConvertToVp());
878     for (const auto& pair : textStyle1.fontFeature) {
879         EXPECT_EQ(pair.first, "subs");
880         EXPECT_EQ(pair.second, 1);
881     }
882     ClearSpan();
883 }
884 
885 /**
886  * @tc.name: HasSameTypingStyle001
887  * @tc.desc: test HasSameTypingStyle
888  * @tc.type: FUNC
889  */
890 HWTEST_F(RichEditorEditTestOneNg, HasSameTypingStyle001, TestSize.Level1)
891 {
892     ASSERT_NE(richEditorNode_, nullptr);
893     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
894     ASSERT_NE(richEditorPattern, nullptr);
895     richEditorPattern->caretPosition_ = 0;
896     richEditorPattern->InsertValue(TEST_INSERT_VALUE);
897     auto it = AceType::DynamicCast<SpanNode>(richEditorNode_->GetLastChild());
898     auto spanItem = it->GetSpanItem();
899 
900     spanItem->textStyle_ = std::nullopt;
901     richEditorPattern->typingTextStyle_ = std::nullopt;
902     auto ret = richEditorPattern->HasSameTypingStyle(it);
903     EXPECT_TRUE(ret);
904 
905     spanItem->textStyle_ = TextStyle();
906     richEditorPattern->typingTextStyle_ = std::nullopt;
907     ret = richEditorPattern->HasSameTypingStyle(it);
908     EXPECT_FALSE(ret);
909 
910     spanItem->textStyle_ = std::nullopt;
911     richEditorPattern->typingTextStyle_ = TextStyle();
912     ret = richEditorPattern->HasSameTypingStyle(it);
913     EXPECT_FALSE(ret);
914 
915     spanItem->textStyle_ = TextStyle();
916     richEditorPattern->typingTextStyle_ = TextStyle();
917     ret = richEditorPattern->HasSameTypingStyle(it);
918     EXPECT_TRUE(ret);
919 
920     spanItem->textStyle_.value().fontFamilies_.push_back("test1");
921     ret = richEditorPattern->HasSameTypingStyle(it);
922     EXPECT_FALSE(ret);
923 }
924 
925 /**
926  * @tc.name: SetTypingStyle
927  * @tc.desc: test Typing Style
928  * @tc.type: FUNC
929  */
930 HWTEST_F(RichEditorEditTestOneNg, SetTypingStyle2, TestSize.Level1)
931 {
932     /**
933      * @tc.steps: step1. get richEditor controller
934      */
935     ASSERT_NE(richEditorNode_, nullptr);
936     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
937     ASSERT_NE(richEditorPattern, nullptr);
938     auto richEditorController = richEditorPattern->GetRichEditorController();
939     ASSERT_NE(richEditorController, nullptr);
940     TextStyle style;
941     style.SetFontFeatures(TEXT_FONTFEATURE_2);
942     TextSpanOptions options;
943     options.value = INIT_VALUE_1;
944     options.style = style;
945     richEditorController->AddTextSpan(options);
946     auto info = richEditorController->GetSpansInfo(1, 5);
947     TextStyleResult textStyle1 = info.selection_.resultObjects.front().textStyle;
948     UpdateSpanStyle typingStyle;
949     richEditorPattern->SetTypingStyle(typingStyle, style);
950     TextSpanOptions options1;
951     options1.style = richEditorPattern->typingTextStyle_;
952     auto info1 = richEditorController->GetSpansInfo(1, 5);
953     TextStyleResult textStyle2 = info1.selection_.resultObjects.front().textStyle;
954     for (const auto& pair : textStyle1.fontFeature) {
955         EXPECT_EQ(pair.first, "subs");
956         EXPECT_EQ(pair.second, 0);
957     }
958     ClearSpan();
959 }
960 
961 /**
962  * @tc.name: MoveCaretToContentRect001
963  * @tc.desc: test MoveCaretToContentRect
964  * @tc.type: FUNC
965  */
966 HWTEST_F(RichEditorEditTestOneNg, MoveCaretToContentRect001, TestSize.Level1)
967 {
968     ASSERT_NE(richEditorNode_, nullptr);
969     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
970     ASSERT_NE(richEditorPattern, nullptr);
971 
972     SelectOverlayInfo overlayInfo;
973     auto shareOverlayInfo = std::make_shared<SelectOverlayInfo>(overlayInfo);
974     auto overlayNode = SelectOverlayNode::CreateSelectOverlayNode(shareOverlayInfo);
975     auto manager = SelectContentOverlayManager::GetOverlayManager();
976     CHECK_NULL_VOID(manager);
977     manager->selectOverlayNode_ = overlayNode;
978 
979     richEditorPattern->OnAreaChangedInner();
980     OffsetF Offset = { 1, 2 };
981     EXPECT_NE(richEditorPattern->GetPaintRectGlobalOffset(), Offset);
982 
983     richEditorPattern->contentChange_ = true;
984     richEditorPattern->keyboardAvoidance_ = true;
985     auto pipeline = PipelineContext::GetCurrentContext();
986     pipeline->rootHeight_ = 80.0;
987     EXPECT_EQ(richEditorPattern->GetCrossOverHeight(), 0.0f);
988 
989     int32_t scroll_from_update = 1;
990     richEditorPattern->overlayMod_ = AceType::MakeRefPtr<TextOverlayModifier>();
991     richEditorPattern->richTextRect_ = RectF(0, 4, 100, 140);
992     richEditorPattern->contentRect_ = RectF(0, 5, 100, 160);
993     richEditorPattern->UpdateScrollStateAfterLayout(true);
994     EXPECT_FALSE(richEditorPattern->OnScrollCallback(10, scroll_from_update));
995 
996     /**
997      * @tc.steps: step1. set isShowPlaceholder_
998      */
999     richEditorPattern->richTextRect_ = RectF(0, 4, 100, 120);
1000     richEditorPattern->contentRect_ = RectF(0, 5, 100, 60);
1001     auto offsetF = OffsetF(0.0f, 0.5f);
1002     richEditorPattern->isShowPlaceholder_ = false;
1003     richEditorPattern->MoveCaretToContentRect(offsetF, 80.0f);
1004     EXPECT_EQ(richEditorPattern->GetTextRect(), richEditorPattern->richTextRect_);
1005 
1006     /**
1007      * @tc.steps: step2. set MoveCaretToContentRect second parameter
1008      */
1009     richEditorPattern->MoveCaretToContentRect(offsetF, 40.0f);
1010     EXPECT_EQ(richEditorPattern->GetTextRect(), richEditorPattern->richTextRect_);
1011 
1012     /**
1013      * @tc.steps: step3. set MoveCaretToContentRect first parameter
1014      */
1015     auto offsetFtemp = OffsetF(0.0f, 10.0f);
1016     richEditorPattern->MoveCaretToContentRect(offsetFtemp, 40.0f);
1017     EXPECT_EQ(richEditorPattern->GetTextRect(), richEditorPattern->richTextRect_);
1018 }
1019 
1020 /**
1021  * @tc.name: InitScrollablePattern001
1022  * @tc.desc: test InitScrollablePattern
1023  * @tc.type: FUNC
1024  */
1025 HWTEST_F(RichEditorEditTestOneNg, InitScrollablePattern001, TestSize.Level1)
1026 {
1027     ASSERT_NE(richEditorNode_, nullptr);
1028     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1029     ASSERT_NE(richEditorPattern, nullptr);
1030 
1031     auto pipeline = PipelineContext::GetCurrentContext();
1032     auto theme = AceType::MakeRefPtr<MockThemeManager>();
1033     EXPECT_CALL(*theme, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<RichEditorTheme>()));
1034     pipeline->SetThemeManager(theme);
1035 
1036     richEditorPattern->scrollBar_ = nullptr;
1037     richEditorPattern->InitScrollablePattern();
1038     EXPECT_EQ(richEditorPattern->GetScrollBar(), false);
1039 
1040     richEditorPattern->overlayMod_ = AceType::MakeRefPtr<TextOverlayModifier>();
1041     richEditorPattern->InitScrollablePattern();
1042     EXPECT_EQ(richEditorPattern->GetScrollBar(), false);
1043 
1044     Offset Offset = { 1, 4 };
1045     richEditorPattern->isTextChange_ = true;
1046     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
1047     EXPECT_EQ(richEditorPattern->HasFocus(), false);
1048 
1049     richEditorPattern->isTextChange_ = false;
1050     richEditorPattern->UpdateTextFieldManager(Offset, 1.0f);
1051     EXPECT_EQ(richEditorPattern->HasFocus(), false);
1052 }
1053 
1054 /**
1055  * @tc.name: GetThumbnailCallback002
1056  * @tc.desc: test GetThumbnailCallback
1057  * @tc.type: FUNC
1058  */
1059 HWTEST_F(RichEditorEditTestOneNg, GetThumbnailCallback002, TestSize.Level1)
1060 {
1061     ASSERT_NE(richEditorNode_, nullptr);
1062     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1063 
1064     richEditorPattern->InitDragDropEvent();
1065     EXPECT_EQ(richEditorPattern->dragNode_, nullptr);
1066 }
1067 
1068 /**
1069  * @tc.name: VirtualKeyboardAreaChanged002
1070  * @tc.desc: test OnVirtualKeyboardAreaChanged
1071  * @tc.type: FUNC
1072  */
1073 HWTEST_F(RichEditorEditTestOneNg, VirtualKeyboardAreaChanged002, TestSize.Level1)
1074 {
1075     /**
1076      * @tc.steps: step1. init and call function.
1077     */
1078     ASSERT_NE(richEditorNode_, nullptr);
1079     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1080     ASSERT_NE(richEditorPattern, nullptr);
1081     richEditorPattern->CreateNodePaintMethod();
1082     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
1083     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
1084 
1085     richEditorPattern->OnModifyDone();
1086     richEditorPattern->textSelector_.Update(0, 1);
1087     richEditorPattern->CalculateHandleOffsetAndShowOverlay();
1088     richEditorPattern->ShowSelectOverlay(
1089         richEditorPattern->textSelector_.firstHandle, richEditorPattern->textSelector_.secondHandle, false);
1090     richEditorPattern->OnVirtualKeyboardAreaChanged();
1091     EXPECT_TRUE(richEditorPattern->SelectOverlayIsOn());
1092 }
1093 
1094 /**
1095  * @tc.name: GetSelectedBackgroundColor001
1096  * @tc.desc: test GetSelectedBackgroundColor
1097  * @tc.type: FUNC
1098  */
1099 HWTEST_F(RichEditorEditTestOneNg, GetSelectedBackgroundColor001, TestSize.Level1)
1100 {
1101     /**
1102      * @tc.steps: step1. init and call function.
1103     */
1104     ASSERT_NE(richEditorNode_, nullptr);
1105     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1106     ASSERT_NE(richEditorPattern, nullptr);
1107     richEditorPattern->CreateNodePaintMethod();
1108     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
1109     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
1110     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
1111     ASSERT_NE(themeManager, nullptr);
1112     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<RichEditorTheme>()));
1113     PipelineBase::GetCurrentContext()->themeManager_ = themeManager;
1114     richEditorPattern->selectedBackgroundColor_.reset();
1115     auto ret = richEditorPattern->GetSelectedBackgroundColor();
1116     EXPECT_NE(ret.GetValue(), 0);
1117 }
1118 
1119 /**
1120  * @tc.name: HandleOnDragDrop001
1121  * @tc.desc: test HandleOnDragDrop
1122  * @tc.type: FUNC
1123  */
1124 HWTEST_F(RichEditorEditTestOneNg, HandleOnDragDrop001, TestSize.Level1)
1125 {
1126     /**
1127      * @tc.steps: step1. init and call function.
1128     */
1129     ASSERT_NE(richEditorNode_, nullptr);
1130     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1131     ASSERT_NE(richEditorPattern, nullptr);
1132     richEditorPattern->CreateNodePaintMethod();
1133     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
1134     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
1135     auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
1136     ASSERT_NE(themeManager, nullptr);
1137     EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<RichEditorTheme>()));
1138     PipelineBase::GetCurrentContext()->themeManager_ = themeManager;
1139     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1140     ASSERT_NE(event, nullptr);
1141     RefPtr<UnifiedData> unifiedData = AceType::MakeRefPtr<MockUnifiedData>();
1142     ASSERT_NE(unifiedData, nullptr);
1143     std::string selectedStr = "test123";
1144     OHOS::Ace::UdmfClient::GetInstance()->AddPlainTextRecord(unifiedData, selectedStr);
1145     event->SetData(unifiedData);
1146     richEditorPattern->HandleOnDragDrop(event);
1147     EXPECT_NE(event->GetData(), nullptr);
1148 }
1149 
1150 /**
1151  * @tc.name: ResetKeyboardIfNeed001
1152  * @tc.desc: test ResetKeyboardIfNeed
1153  * @tc.type: FUNC
1154  */
1155 HWTEST_F(RichEditorEditTestOneNg, ResetKeyboardIfNeed001, TestSize.Level1)
1156 {
1157     /**
1158      * @tc.steps: step1. init and call function.
1159     */
1160     ASSERT_NE(richEditorNode_, nullptr);
1161     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1162     ASSERT_NE(richEditorPattern, nullptr);
1163     richEditorPattern->CreateNodePaintMethod();
1164     EXPECT_NE(richEditorPattern->contentMod_, nullptr);
1165     EXPECT_NE(richEditorPattern->overlayMod_, nullptr);
1166     auto focusHub = richEditorPattern->GetFocusHub();
1167     EXPECT_NE(focusHub, nullptr);
1168 
1169     richEditorPattern->imeShown_ = true;
1170     richEditorPattern->isCustomKeyboardAttached_ = true;
1171     focusHub->currentFocus_ = true;
1172     richEditorPattern->action_ = TextInputAction::SEARCH;
1173     richEditorPattern->ResetKeyboardIfNeed();
1174     EXPECT_NE(richEditorPattern->action_, TextInputAction::SEARCH);
1175 }
1176 
1177 /**
1178  * @tc.name: GetChangeSpanStyle001
1179  * @tc.desc: test GetChangeSpanStyle
1180  * @tc.type: FUNC
1181  */
1182 HWTEST_F(RichEditorEditTestOneNg, GetChangeSpanStyle001, TestSize.Level1)
1183 {
1184     /**
1185      * @tc.steps: step1. init and call function.
1186     */
1187     ASSERT_NE(richEditorNode_, nullptr);
1188     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1189     ASSERT_NE(richEditorPattern, nullptr);
1190 
1191     struct UpdateParagraphStyle paragraphStyle;
1192     paragraphStyle.textAlign = TextAlign::END;
1193     paragraphStyle.leadingMargin = std::make_optional<NG::LeadingMargin>();
1194     paragraphStyle.leadingMargin->size = LeadingMarginSize(Dimension(5.0), Dimension(10.0));
1195     richEditorPattern->UpdateParagraphStyle(0, 6, paragraphStyle);
1196     std::optional<struct UpdateParagraphStyle> spanParaStyle = paragraphStyle;
1197 
1198     RichEditorChangeValue changeValue;
1199     RichEditorAbstractSpanResult span1;
1200     changeValue.originalSpans_.emplace_back(span1);
1201     RichEditorAbstractSpanResult span2;
1202     changeValue.originalSpans_.emplace_back(span2);
1203 
1204     RichEditorAbstractSpanResult& firstInfo = changeValue.originalSpans_.front();
1205     int32_t firstLength = static_cast<int32_t>(StringUtils::ToWstring(firstInfo.GetValue()).length());
1206     firstInfo.SetEraseLength(firstLength);
1207     RichEditorAbstractSpanResult& lastInfo = changeValue.originalSpans_.back();
1208     int32_t lastLength = static_cast<int32_t>(StringUtils::ToWstring(lastInfo.GetValue()).length());
1209     lastInfo.SetEraseLength(lastLength);
1210 
1211     std::optional<TextStyle> spanTextStyle;
1212     RefPtr<SpanNode> spanNode = OHOS::Ace::NG::SpanNode::CreateSpanNode(1);
1213     int32_t spanIndex = 0;
1214     richEditorPattern->spans_.clear();
1215     OHOS::Ace::RefPtr<OHOS::Ace::NG::SpanItem> spanItem1 = AceType::MakeRefPtr<ImageSpanItem>();
1216     richEditorPattern->spans_.emplace_back(spanItem1);
1217     OHOS::Ace::RefPtr<OHOS::Ace::NG::SpanItem> spanItem2 = AceType::MakeRefPtr<PlaceholderSpanItem>();
1218     richEditorPattern->spans_.emplace_back(spanItem2);
1219     richEditorPattern->GetChangeSpanStyle(changeValue, spanTextStyle, spanParaStyle, spanNode, spanIndex);
1220     EXPECT_FALSE(spanTextStyle.has_value());
1221     /**
1222      * @tc.steps: step2. change parameter and call function.
1223     */
1224     OHOS::Ace::RefPtr<OHOS::Ace::NG::SpanItem> spanItem3 = AceType::MakeRefPtr<ImageSpanItem>();
1225     richEditorPattern->spans_.emplace_back(spanItem3);
1226     lastInfo.SetSpanIndex(richEditorPattern->spans_.size() - 1);
1227     richEditorPattern->GetChangeSpanStyle(changeValue, spanTextStyle, spanParaStyle, spanNode, spanIndex);
1228     EXPECT_FALSE(spanTextStyle.has_value());
1229     /**
1230      * @tc.steps: step4. change parameter and call function.
1231     */
1232     lastInfo.SetEraseLength(lastLength - 1);
1233     richEditorPattern->GetChangeSpanStyle(changeValue, spanTextStyle, spanParaStyle, spanNode, spanIndex);
1234     EXPECT_FALSE(spanTextStyle.has_value());
1235 }
1236 
1237 /**
1238  * @tc.name: RichEditorPatternTestUpdatePreviewText003
1239  * @tc.desc: test UpdatePreviewText
1240  * @tc.type: FUNC
1241  */
1242 HWTEST_F(RichEditorEditTestOneNg, RichEditorPatternTestUpdatePreviewText003, TestSize.Level1)
1243 {
1244     ASSERT_NE(richEditorNode_, nullptr);
1245     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1246     ASSERT_NE(richEditorPattern, nullptr);
1247 
1248     std::string previewTextValue;
1249     PreviewRange previewRange;
1250 
1251     previewRange.start = 0;
1252     previewRange.end = 0;
1253     ASSERT_EQ(richEditorPattern->UpdatePreviewText(previewTextValue, previewRange), false);
1254 }
1255 
1256 /**
1257  * @tc.name: RichEditorPatternTestSetPreviewText001
1258  * @tc.desc: test SetPreviewText
1259  * @tc.type: FUNC
1260  */
1261 HWTEST_F(RichEditorEditTestOneNg, RichEditorPatternTestSetPreviewText001, TestSize.Level1)
1262 {
1263     ASSERT_NE(richEditorNode_, nullptr);
1264     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1265     ASSERT_NE(richEditorPattern, nullptr);
1266 
1267     std::string previewTextValue = INIT_VALUE_1;
1268     PreviewRange previewRange;
1269 
1270     previewRange.start = -1;
1271     previewRange.end = -1;
1272     ASSERT_EQ(richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange), 0);
1273 
1274     previewRange.start = 0;
1275     previewRange.end = -1;
1276     ASSERT_EQ(richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange), -1);
1277 
1278     previewRange.start = -1;
1279     previewRange.end = 0;
1280     ASSERT_EQ(richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange), -1);
1281 
1282     previewRange.start = 0;
1283     previewRange.end = 0;
1284     ASSERT_EQ(richEditorPattern->SetPreviewText(PREVIEW_TEXT_VALUE1, previewRange), 0);
1285 }
1286 
1287 /**
1288  * @tc.name: RichEditorPatternTestGetPreviewTextStyle001
1289  * @tc.desc: test GetPreviewTextStyle
1290  * @tc.type: FUNC
1291  */
1292 HWTEST_F(RichEditorEditTestOneNg, RichEditorPatternTestGetPreviewTextStyle001, TestSize.Level1)
1293 {
1294     ASSERT_NE(richEditorNode_, nullptr);
1295     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1296     ASSERT_NE(richEditorPattern, nullptr);
1297     auto host = richEditorPattern->GetHost();
1298     ASSERT_NE(host, nullptr);
1299 
1300     auto layoutProperty = host->layoutProperty_;
1301     host->layoutProperty_ = nullptr;
1302     EXPECT_EQ(richEditorPattern->GetPreviewTextStyle(), PreviewTextStyle::UNDERLINE);
1303     host->layoutProperty_ = layoutProperty;
1304 
1305     ASSERT_NE(host->layoutProperty_, nullptr);
1306     auto property = richEditorPattern->GetLayoutProperty<RichEditorLayoutProperty>();
1307     ASSERT_NE(property, nullptr);
1308 
1309     EXPECT_EQ(richEditorPattern->GetPreviewTextStyle(), PreviewTextStyle::UNDERLINE);
1310 
1311     property->UpdatePreviewTextStyle("normal");
1312     EXPECT_EQ(richEditorPattern->GetPreviewTextStyle(), PreviewTextStyle::NORMAL);
1313 
1314     property->UpdatePreviewTextStyle("underline");
1315     EXPECT_EQ(richEditorPattern->GetPreviewTextStyle(), PreviewTextStyle::UNDERLINE);
1316 
1317     property->UpdatePreviewTextStyle("unknown");
1318     EXPECT_EQ(richEditorPattern->GetPreviewTextStyle(), PreviewTextStyle::UNDERLINE);
1319 }
1320 
1321 /**
1322  * @tc.name: HandleOnCut001
1323  * @tc.desc: test RichEditorPattern HandleOnCut
1324  * @tc.type: FUNC
1325  */
1326 HWTEST_F(RichEditorEditTestOneNg, HandleOnCut001, TestSize.Level1)
1327 {
1328     ASSERT_NE(richEditorNode_, nullptr);
1329     auto richEditorPattern = richEditorNode_->GetPattern<RichEditorPattern>();
1330     ASSERT_NE(richEditorPattern, nullptr);
1331     richEditorPattern->copyOption_ = CopyOptions::None;
1332     richEditorPattern->HandleOnCut();
1333     richEditorPattern->copyOption_ = CopyOptions::InApp;
1334     richEditorPattern->previewLongPress_ = true;
1335     richEditorPattern->HandleOnCut();
1336     ASSERT_EQ(richEditorPattern->textSelector_.IsValid(), false);
1337     richEditorPattern->textSelector_.baseOffset = -2;
1338     richEditorPattern->textSelector_.destinationOffset = -2;
1339     richEditorPattern->HandleOnCut();
1340     ASSERT_EQ(richEditorPattern->textSelector_.IsValid(), false);
1341 }
1342 
1343 /**
1344  * @tc.name: HandleOnCut004
1345  * @tc.desc: test HandleOnCut
1346  * @tc.type: FUNC
1347  */
1348 HWTEST_F(RichEditorEditTestOneNg, HandleOnCut004, TestSize.Level1)
1349 {
1350     /**
1351      * @tc.steps: step1. init callback
1352      */
1353     RichEditorModelNG richEditorModel;
1354     richEditorModel.Create();
1355     auto host = ViewStackProcessor::GetInstance()->GetMainFrameNode();
1356     ASSERT_NE(host, nullptr);
1357     auto richEditorPattern = host->GetPattern<RichEditorPattern>();
1358     ASSERT_NE(richEditorPattern, nullptr);
1359     auto eventHub = richEditorPattern->GetEventHub<RichEditorEventHub>();
1360     ASSERT_NE(eventHub, nullptr);
1361     bool isEventCalled = false;
__anon93c694140402(NG::TextCommonEvent& event) 1362     auto onCutWithEvent = [&isEventCalled](NG::TextCommonEvent& event) {
1363         isEventCalled = true;
1364         event.SetPreventDefault(true);
1365     };
1366     richEditorModel.SetOnCut(std::move(onCutWithEvent));
1367 
1368     /**
1369      * @tc.steps: step2. call the callback function
1370      * @tc.expected: when PreventDefault is true, UpdateType_ and isEventCalled is valid
1371      */
1372     richEditorPattern->copyOption_ = CopyOptions::InApp;
1373     richEditorPattern->caretPosition_ = 0;
1374     richEditorPattern->textSelector_.baseOffset = 0;
1375     richEditorPattern->textSelector_.destinationOffset = 1;
1376     richEditorPattern->caretUpdateType_ = CaretUpdateType::PRESSED;
1377     richEditorPattern->previewLongPress_ = true;
1378     richEditorPattern->HandleOnCut();
1379     EXPECT_EQ(richEditorPattern->caretUpdateType_, CaretUpdateType::PRESSED);
1380     EXPECT_EQ(isEventCalled, true);
1381 }
1382 
1383 } // namespace OHOS::Ace::NG