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