File indexing completed on 2024-06-02 05:26:28
0001 /* 0002 SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "richtextcomposertest.h" 0008 #include "../richtextcomposer.h" 0009 #include <KCodecs> 0010 #include <QSignalSpy> 0011 #include <QTest> 0012 0013 #include <KActionCollection> 0014 #include <KIconLoader> 0015 #include <QAction> 0016 0017 #include "kpimtextedit/richtextcomposer.h" 0018 #include "kpimtextedit/richtextcomposercontroler.h" 0019 #include "kpimtextedit/richtextcomposerimages.h" 0020 #include <QBuffer> 0021 #include <QStandardPaths> 0022 #include <QTextBlock> 0023 #include <QTextCursor> 0024 0025 using namespace KPIMTextEdit; 0026 0027 Q_DECLARE_METATYPE(KPIMTextEdit::RichTextComposer::Mode) 0028 RichTextComposerTest::RichTextComposerTest(QObject *parent) 0029 : QObject(parent) 0030 { 0031 qRegisterMetaType<KPIMTextEdit::RichTextComposer::Mode>(); 0032 QIcon::setThemeName(QStringLiteral("breeze")); 0033 QStandardPaths::setTestModeEnabled(true); 0034 } 0035 0036 RichTextComposerTest::~RichTextComposerTest() = default; 0037 0038 void RichTextComposerTest::testFormattingUsed() 0039 { 0040 // This method tries to test everything that krichtextedit makes available, so 0041 // we can sure that in KMail, when the user uses some formatting, the mail is actually 0042 // sent as HTML mail 0043 0044 KPIMTextEdit::RichTextComposer textEdit; 0045 textEdit.createActions(new KActionCollection(this)); 0046 0047 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0048 0049 // Insert some text. 0050 QTextCursor cursor(textEdit.document()); 0051 cursor.insertText(QStringLiteral("Hello World!!")); 0052 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0053 cursor.setPosition(1); 0054 textEdit.setTextCursor(cursor); 0055 0056 // 0057 // Test link 0058 // 0059 QString someUrl = QStringLiteral("www.test.de"); 0060 QString altText = QStringLiteral("Hello"); 0061 textEdit.composerControler()->updateLink(someUrl, altText); 0062 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0063 QCOMPARE(textEdit.composerControler()->currentLinkUrl(), someUrl); 0064 QCOMPARE(textEdit.composerControler()->currentLinkText(), altText); 0065 0066 cursor.setPosition(1); 0067 textEdit.setTextCursor(cursor); 0068 textEdit.composerControler()->updateLink(QString(), QStringLiteral("Hello")); 0069 QVERIFY(textEdit.composerControler()->currentLinkUrl().isEmpty()); 0070 QVERIFY(!textEdit.composerControler()->currentLinkText().isEmpty()); 0071 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0072 0073 // 0074 // Test alignment 0075 // 0076 cursor.setPosition(1); 0077 textEdit.setTextCursor(cursor); 0078 textEdit.composerControler()->alignRight(); 0079 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0080 QCOMPARE(textEdit.alignment(), Qt::AlignRight); 0081 textEdit.composerControler()->alignLeft(); 0082 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0083 textEdit.composerControler()->alignCenter(); 0084 QCOMPARE(textEdit.alignment(), Qt::AlignHCenter); 0085 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0086 textEdit.composerControler()->alignJustify(); 0087 QCOMPARE(textEdit.alignment(), Qt::AlignJustify); 0088 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0089 textEdit.composerControler()->alignLeft(); 0090 QCOMPARE(textEdit.alignment(), Qt::AlignLeft); 0091 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0092 0093 // 0094 // Test layout direction 0095 // 0096 textEdit.selectAll(); 0097 QTextCharFormat direction; 0098 direction.setLayoutDirection(Qt::RightToLeft); 0099 textEdit.mergeCurrentCharFormat(direction); 0100 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0101 direction.setLayoutDirection(Qt::LeftToRight); 0102 textEdit.mergeCurrentCharFormat(direction); 0103 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0104 0105 // 0106 // Test lists 0107 // 0108 textEdit.composerControler()->setListStyle(QTextListFormat::ListCircle); 0109 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0110 textEdit.composerControler()->setListStyle(0); 0111 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0112 0113 // 0114 // Test font attributes 0115 // 0116 textEdit.setFontFamily(QStringLiteral("Times")); 0117 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0118 textEdit.setFontFamily(textEdit.document()->defaultFont().family()); 0119 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0120 textEdit.composerControler()->setFontSize(48); 0121 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0122 textEdit.composerControler()->setFontSize(textEdit.document()->defaultFont().pointSize()); 0123 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0124 QFont myFont = textEdit.document()->defaultFont(); 0125 myFont.setStyle(QFont::StyleOblique); 0126 textEdit.composerControler()->setFont(myFont); 0127 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0128 textEdit.composerControler()->setFont(textEdit.document()->defaultFont()); 0129 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0130 0131 // 0132 // Test bold, italic, underline and strikeout 0133 // 0134 textEdit.composerControler()->setTextBold(true); 0135 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0136 textEdit.composerControler()->setTextBold(false); 0137 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0138 textEdit.composerControler()->setTextUnderline(true); 0139 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0140 textEdit.composerControler()->setTextUnderline(false); 0141 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0142 textEdit.composerControler()->setTextItalic(true); 0143 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0144 textEdit.composerControler()->setTextItalic(false); 0145 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0146 textEdit.composerControler()->setTextStrikeOut(true); 0147 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0148 textEdit.composerControler()->setTextStrikeOut(false); 0149 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0150 0151 // 0152 // Color 0153 // 0154 QColor oldForeground = textEdit.document()->firstBlock().charFormat().foreground().color(); 0155 textEdit.composerControler()->setTextForegroundColor(Qt::red); 0156 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0157 textEdit.composerControler()->setTextForegroundColor(oldForeground); 0158 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0159 QColor oldBackground = textEdit.document()->firstBlock().charFormat().background().color(); 0160 textEdit.composerControler()->setTextBackgroundColor(Qt::red); 0161 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0162 textEdit.composerControler()->setTextBackgroundColor(oldBackground); 0163 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0164 0165 // 0166 // Horizontal rule 0167 // 0168 textEdit.composerControler()->insertHorizontalRule(); 0169 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0170 // No way to easily remove the horizontal line, so clear the text edit and start over 0171 textEdit.clear(); 0172 cursor.insertText(QStringLiteral("Hello World!!")); 0173 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0174 cursor.setPosition(1); 0175 textEdit.setTextCursor(cursor); 0176 0177 // 0178 // Sub and superscript 0179 // 0180 textEdit.composerControler()->setTextSuperScript(true); 0181 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0182 textEdit.composerControler()->setTextSuperScript(false); 0183 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0184 textEdit.composerControler()->setTextSubScript(true); 0185 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0186 textEdit.composerControler()->setTextSubScript(false); 0187 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0188 0189 // 0190 // Image 0191 // 0192 const QString imagePath = KIconLoader::global()->iconPath(QStringLiteral("folder-new"), KIconLoader::Small, false); 0193 textEdit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(imagePath)); 0194 QVERIFY(textEdit.composerControler()->isFormattingUsed()); 0195 cursor = textEdit.textCursor(); 0196 cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor, 1); 0197 cursor.removeSelectedText(); 0198 QVERIFY(!textEdit.composerControler()->isFormattingUsed()); 0199 } 0200 0201 void RichTextComposerTest::testQuoting() 0202 { 0203 KPIMTextEdit::RichTextComposer edit; 0204 edit.createActions(new KActionCollection(this)); 0205 QVERIFY(edit.isLineQuoted(QStringLiteral("> Hello"))); 0206 QVERIFY(edit.isLineQuoted(QStringLiteral(">Hello"))); 0207 QVERIFY(!edit.isLineQuoted(QStringLiteral("Hello"))); 0208 QCOMPARE(edit.quoteLength(QStringLiteral("Hello")), 0); 0209 QCOMPARE(edit.quoteLength(QStringLiteral(">Hello")), 1); 0210 QCOMPARE(edit.quoteLength(QStringLiteral("> Hello")), 2); 0211 QCOMPARE(edit.quoteLength(QStringLiteral(">>>Hello")), 3); 0212 QCOMPARE(edit.quoteLength(QStringLiteral("> > > Hello")), 6); 0213 QCOMPARE(edit.quoteLength(QStringLiteral("|Hello")), 1); 0214 QCOMPARE(edit.quoteLength(QStringLiteral("| |Hello")), 3); 0215 } 0216 0217 void RichTextComposerTest::testCleanText() 0218 { 0219 KPIMTextEdit::RichTextComposer edit; 0220 edit.createActions(new KActionCollection(this)); 0221 QString html(QStringLiteral("<html><head></head><body>Heelllo World<br>Bye!</body></html>")); 0222 QString plain(QStringLiteral("Heelllo World\nBye!")); 0223 edit.setTextOrHtml(html); 0224 edit.composerControler()->composerImages()->addImage( 0225 QUrl::fromLocalFile(KIconLoader::global()->iconPath(QStringLiteral("folder-new"), KIconLoader::Small, false))); 0226 QVERIFY(edit.textMode() == KPIMTextEdit::RichTextComposer::Rich); 0227 QCOMPARE(edit.composerControler()->toCleanPlainText(), plain); 0228 0229 edit.show(); // < otherwise toWrappedPlainText can't work, it needs a layout 0230 QCOMPARE(edit.composerControler()->toWrappedPlainText(), plain); 0231 } 0232 0233 void RichTextComposerTest::testEnter_data() 0234 { 0235 QTest::addColumn<QString>("initalText"); 0236 QTest::addColumn<QString>("expectedText"); 0237 QTest::addColumn<int>("cursorPos"); 0238 0239 QTest::newRow("") << QStringLiteral("> Hello World") << QStringLiteral("> Hello \n> World") << 8; 0240 QTest::newRow("") << QStringLiteral("Hello World") << QStringLiteral("Hello \nWorld") << 6; 0241 QTest::newRow("") << QStringLiteral("> Hello World") << QStringLiteral("> Hello World\n") << 13; 0242 QTest::newRow("") << QStringLiteral(">Hello World") << QStringLiteral(">Hello \n>World") << 7; 0243 QTest::newRow("") << QStringLiteral("> > Hello World") << QStringLiteral("> > Hello \n> > World") << 10; 0244 QTest::newRow("") << QStringLiteral("| | Hello World") << QStringLiteral("| | Hello \n| | World") << 10; 0245 } 0246 0247 void RichTextComposerTest::testEnter() 0248 { 0249 QFETCH(QString, initalText); 0250 QFETCH(QString, expectedText); 0251 QFETCH(int, cursorPos); 0252 0253 KPIMTextEdit::RichTextComposer edit; 0254 edit.createActions(new KActionCollection(this)); 0255 edit.setPlainText(initalText); 0256 QTextCursor textCursor(edit.document()); 0257 textCursor.setPosition(cursorPos); 0258 edit.setTextCursor(textCursor); 0259 0260 QTest::keyClick(&edit, Qt::Key_Return); 0261 QCOMPARE(edit.toPlainText(), expectedText); 0262 } 0263 0264 void RichTextComposerTest::testImages() 0265 { 0266 KPIMTextEdit::RichTextComposer edit; 0267 edit.createActions(new KActionCollection(this)); 0268 QString image1Path = KIconLoader::global()->iconPath(QStringLiteral("folder-new"), KIconLoader::Small, false); 0269 QString image2Path = KIconLoader::global()->iconPath(QStringLiteral("arrow-up"), KIconLoader::Small, false); 0270 0271 // Add one image, check that embeddedImages() returns the right stuff 0272 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image1Path)); 0273 KPIMTextEdit::ImageList images = edit.composerControler()->composerImages()->embeddedImages(); 0274 KPIMTextEdit::ImageWithNameList imagesWithNames = edit.composerControler()->composerImages()->imagesWithName(); 0275 QCOMPARE(images.size(), 1); 0276 QCOMPARE(imagesWithNames.size(), 1); 0277 EmbeddedImage *image = images.first().data(); 0278 ImageWithName *imageWithName = imagesWithNames.first().data(); 0279 QCOMPARE(image->imageName, QString::fromLatin1("folder-new.png")); 0280 QCOMPARE(imageWithName->name, QString::fromLatin1("folder-new.png")); 0281 0282 // Also check that it loads the correct image 0283 QImage diskImage(image1Path); 0284 QBuffer buffer; 0285 buffer.open(QIODevice::WriteOnly); 0286 diskImage.save(&buffer, "PNG"); 0287 QBuffer imageWithNameBuffer; 0288 imageWithNameBuffer.open(QIODevice::WriteOnly); 0289 imageWithName->image.save(&imageWithNameBuffer, "PNG"); 0290 QByteArray encodedImage = KCodecs::Codec::codecForName("base64")->encode(buffer.buffer()); 0291 QCOMPARE(image->image, encodedImage); 0292 QCOMPARE(buffer.buffer(), imageWithNameBuffer.buffer()); 0293 0294 // No image should be there after clearing 0295 edit.clear(); 0296 QVERIFY(edit.composerControler()->composerImages()->embeddedImages().isEmpty()); 0297 QVERIFY(edit.composerControler()->composerImages()->imagesWithName().isEmpty()); 0298 0299 // Check that manually removing the image also empties the image list 0300 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image1Path)); 0301 QCOMPARE(edit.composerControler()->composerImages()->embeddedImages().size(), 1); 0302 QCOMPARE(edit.composerControler()->composerImages()->imagesWithName().size(), 1); 0303 QTextCursor cursor = edit.textCursor(); 0304 cursor.setPosition(0, QTextCursor::MoveAnchor); 0305 cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 1); 0306 cursor.removeSelectedText(); 0307 QVERIFY(edit.composerControler()->composerImages()->embeddedImages().isEmpty()); 0308 QVERIFY(edit.composerControler()->composerImages()->imagesWithName().isEmpty()); 0309 0310 // Check that adding the identical image two times only adds the image once 0311 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image1Path)); 0312 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image1Path)); 0313 QCOMPARE(edit.composerControler()->composerImages()->embeddedImages().size(), 1); 0314 QCOMPARE(edit.composerControler()->composerImages()->imagesWithName().size(), 1); 0315 0316 // Another different image added, and we should have two images 0317 edit.clear(); 0318 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image1Path)); 0319 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image2Path)); 0320 images = edit.composerControler()->composerImages()->embeddedImages(); 0321 imagesWithNames = edit.composerControler()->composerImages()->imagesWithName(); 0322 QCOMPARE(images.size(), 2); 0323 QCOMPARE(imagesWithNames.size(), 2); 0324 KPIMTextEdit::EmbeddedImage *image1 = images.first().data(); 0325 KPIMTextEdit::EmbeddedImage *image2 = images.last().data(); 0326 KPIMTextEdit::ImageWithName *imageWithName1 = imagesWithNames.first().data(); 0327 KPIMTextEdit::ImageWithName *imageWithName2 = imagesWithNames.last().data(); 0328 QCOMPARE(image1->imageName, 0329 QString::fromLatin1("folder-new2.png")); // ### FIXME: should be folder-new.png, but QTextEdit provides no way to remove cached resources! 0330 QCOMPARE(imageWithName1->name, QString::fromLatin1("folder-new2.png")); 0331 QCOMPARE(image2->imageName, QString::fromLatin1("arrow-up.png")); 0332 QCOMPARE(imageWithName2->name, QString::fromLatin1("arrow-up.png")); 0333 QVERIFY(image1->contentID != image2->contentID); 0334 } 0335 0336 void RichTextComposerTest::testImageHtmlCode() 0337 { 0338 KPIMTextEdit::RichTextComposer edit; 0339 edit.createActions(new KActionCollection(this)); 0340 QString image1Path = KIconLoader::global()->iconPath(QStringLiteral("folder-new"), KIconLoader::Small, false); 0341 QString image2Path = KIconLoader::global()->iconPath(QStringLiteral("arrow-up"), KIconLoader::Small, false); 0342 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image1Path)); 0343 edit.composerControler()->composerImages()->addImage(QUrl::fromLocalFile(image2Path)); 0344 KPIMTextEdit::ImageList images = edit.composerControler()->composerImages()->embeddedImages(); 0345 QCOMPARE(images.size(), 2); 0346 KPIMTextEdit::EmbeddedImage *image1 = images.first().data(); 0347 KPIMTextEdit::EmbeddedImage *image2 = images.last().data(); 0348 QString startHtml = QStringLiteral("<img src=\"arrow-up.png\"><img src=\"folder-new.png\">Bla<b>Blub</b>"); 0349 QString endHtml = QStringLiteral("<img src=\"cid:%1\"><img src=\"cid:%2\">Bla<b>Blub</b>").arg(image2->contentID, image1->contentID); 0350 QCOMPARE(KPIMTextEdit::RichTextComposerImages::imageNamesToContentIds(startHtml.toLatin1(), images), endHtml.toLatin1()); 0351 } 0352 0353 void RichTextComposerTest::testDeleteLine_data() 0354 { 0355 QTest::addColumn<QString>("initalText"); 0356 QTest::addColumn<QString>("expectedText"); 0357 QTest::addColumn<int>("cursorPos"); 0358 0359 QTest::newRow("delete1") << QStringLiteral("line1\nline2\nline3") << QStringLiteral("line1\nline3") << 6; 0360 QTest::newRow("delete2") << QStringLiteral("line1\nline2\nline3") << QStringLiteral("line2\nline3") << 5; 0361 QTest::newRow("delete3") << QStringLiteral("line1\nline2\nline3") << QStringLiteral("line1\nline3") << 11; 0362 QTest::newRow("delete4") << QStringLiteral("line1\nline2\nline3") << QStringLiteral("line2\nline3") << 0; 0363 QTest::newRow("delete5") << QStringLiteral("line1\nline2\nline3") << QStringLiteral("line1\nline2") << 17; 0364 QTest::newRow("delete6") << QStringLiteral("line1") << QString() << 0; 0365 QTest::newRow("delete7") << QStringLiteral("line1") << QString() << 5; 0366 0367 // Now, test deletion with word wrapping. The line with the Ms is so long that it will get wrapped 0368 QTest::newRow("delete8") << QStringLiteral("line1\nMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\nline3") 0369 << QStringLiteral("line1\nMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\nline3") << 6; 0370 QTest::newRow("delete9") << QStringLiteral("line1\nMMMMMMM MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\nline3") 0371 << QStringLiteral("line1\nMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\nline3") << 13; 0372 } 0373 0374 void RichTextComposerTest::testDeleteLine() 0375 { 0376 #if 0 0377 QFETCH(QString, initalText); 0378 QFETCH(QString, expectedText); 0379 QFETCH(int, cursorPos); 0380 0381 KPIMTextEdit::RichTextComposer edit; 0382 edit.createActions(new KActionCollection(this)); 0383 edit.setPlainText(initalText); 0384 QTextCursor cursor = edit.textCursor(); 0385 cursor.setPosition(cursorPos); 0386 edit.setTextCursor(cursor); 0387 0388 edit.show(); // we need a layout for this to work 0389 0390 edit.composerControler()->deleteCurrentLine(); 0391 QCOMPARE(edit.toPlainText(), expectedText); 0392 #endif 0393 } 0394 0395 void RichTextComposerTest::testLoadImage() 0396 { 0397 KPIMTextEdit::RichTextComposer edit; 0398 edit.createActions(new KActionCollection(this)); 0399 QString image1Path = KIconLoader::global()->iconPath(QStringLiteral("folder-new"), KIconLoader::Small, false); 0400 QString image2Path = KIconLoader::global()->iconPath(QStringLiteral("arrow-up"), KIconLoader::Small, false); 0401 QImage image1; 0402 QImage image2; 0403 QVERIFY(image1.load(image1Path)); 0404 QVERIFY(image2.load(image2Path)); 0405 0406 edit.setHtml(QStringLiteral("Bla<img src=\"folder-new.png\">Bla")); 0407 0408 // First try to load an image with a name that doesn't match, it should fail 0409 edit.composerControler()->composerImages()->loadImage(image1, QStringLiteral("doesntmatch"), QStringLiteral("folder-new")); 0410 QVERIFY(!edit.document()->resource(QTextDocument::ImageResource, QUrl(QStringLiteral("folder-new"))).isValid()); 0411 0412 // Now, load the image for real 0413 edit.composerControler()->composerImages()->loadImage(image1, QStringLiteral("folder-new.png"), QStringLiteral("folder-new")); 0414 QVERIFY(edit.document()->resource(QTextDocument::ImageResource, QUrl(QStringLiteral("folder-new"))).isValid()); 0415 0416 // New test with a new textedit (so that we don't use the cached resources 0417 // This example has two images in the same text block, make sure that doesn't crash (bug 204214) 0418 KPIMTextEdit::RichTextComposer edit2; 0419 edit2.createActions(new KActionCollection(this)); 0420 edit2.setHtml(QStringLiteral("<img src=\"folder-new.png\"><img src=\"folder-new.png\">")); 0421 edit2.composerControler()->composerImages()->loadImage(image1, QStringLiteral("folder-new.png"), QStringLiteral("folder-new")); 0422 QVERIFY(edit.document()->resource(QTextDocument::ImageResource, QUrl(QStringLiteral("folder-new"))).isValid()); 0423 QCOMPARE(edit.composerControler()->composerImages()->embeddedImages().size(), 1); 0424 } 0425 0426 void RichTextComposerTest::testWrappedPlainText_data() 0427 { 0428 QTest::addColumn<QString>("input"); 0429 QTest::addColumn<QString>("output"); 0430 0431 QString defaultStr = QStringLiteral( 0432 "http://example.org/test-test-test-test-test-test-test-test-test-test-test-test-test\n " 0433 "https://example.org/test-test-test-test-test-test-test-test-test-test-test-test-test\ntest " 0434 "ftp://example.org/test-test-test-test-test-test-test-test-test-test-test-test-test\nftps://example.org/" 0435 "test-test-test-test-test-test-test-test-test-test-test-test-test\n " 0436 "ldap://example.org/test-test-test-test-test-test-test-test-test-test-test-test-test"); 0437 QTest::newRow("default") << defaultStr << defaultStr; 0438 QTest::newRow("empty") << QString() << QString(); 0439 QTest::newRow("wrap") << QStringLiteral("foosdfsdf sdsf sdfsdfsfs fsf sdfs df sfsdf dsf sdfsdf sf sf sfsdf sdsdf") 0440 << QStringLiteral("foosdfsdf sdsf sdfsdfsfs fsf sdfs df sfsdf \ndsf sdfsdf sf sf sfsdf sdsdf"); 0441 QTest::newRow("wrap-2") << QStringLiteral("test-test-test-test-test-test-test-test-test-test-test-test-test") 0442 << QStringLiteral("test-test-test-test-test-test-test-test-\ntest-test-test-test-test"); 0443 QTest::newRow("wrap-3") << QStringLiteral("test-test-test-test-test-test-test-test-test-test-test-test-test\n\n") 0444 << QStringLiteral("test-test-test-test-test-test-test-test-\ntest-test-test-test-test\n\n"); 0445 } 0446 0447 void RichTextComposerTest::testWrappedPlainText() 0448 { 0449 QFETCH(QString, input); 0450 QFETCH(QString, output); 0451 KPIMTextEdit::RichTextComposer edit; 0452 edit.createActions(new KActionCollection(this)); 0453 edit.setPlainText(input); 0454 0455 edit.show(); // < otherwise toWrappedPlainText can't work, it needs a layout 0456 0457 QCOMPARE(edit.composerControler()->toWrappedPlainText(), output); 0458 } 0459 0460 void RichTextComposerTest::testEnableDisableActions() 0461 { 0462 KPIMTextEdit::RichTextComposer composer; 0463 auto actionCollection = new KActionCollection(&composer); 0464 composer.createActions(actionCollection); 0465 bool enableAction = true; 0466 composer.setEnableActions(enableAction); 0467 for (QAction *act : composer.actions()) { 0468 QCOMPARE(act->isEnabled(), enableAction); 0469 } 0470 0471 enableAction = false; 0472 composer.setEnableActions(enableAction); 0473 for (QAction *act : composer.actions()) { 0474 QCOMPARE(act->isEnabled(), enableAction); 0475 } 0476 } 0477 0478 void RichTextComposerTest::shouldHaveDefaultValue() 0479 { 0480 KPIMTextEdit::RichTextComposer composer; 0481 auto actionCollection = new KActionCollection(&composer); 0482 composer.createActions(actionCollection); 0483 QCOMPARE(composer.linePosition(), 0); 0484 QCOMPARE(composer.columnNumber(), 0); 0485 QCOMPARE(composer.textMode(), KPIMTextEdit::RichTextComposer::Plain); 0486 QVERIFY(!composer.acceptRichText()); 0487 QVERIFY(!composer.quotePrefixName().isEmpty()); 0488 } 0489 0490 void RichTextComposerTest::shouldChangeMode() 0491 { 0492 KPIMTextEdit::RichTextComposer composer; 0493 auto actionCollection = new KActionCollection(&composer); 0494 composer.createActions(actionCollection); 0495 QSignalSpy spy(&composer, &RichTextComposer::textModeChanged); 0496 composer.activateRichText(); 0497 QCOMPARE(composer.textMode(), KPIMTextEdit::RichTextComposer::Rich); 0498 QVERIFY(composer.acceptRichText()); 0499 QCOMPARE(spy.count(), 1); 0500 } 0501 0502 QTEST_MAIN(RichTextComposerTest) 0503 0504 #include "moc_richtextcomposertest.cpp"