diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_mainwindow.cpp | 44 | ||||
| -rw-r--r-- | tests/test_threadlistmodel.cpp | 42 |
2 files changed, 86 insertions, 0 deletions
diff --git a/tests/test_mainwindow.cpp b/tests/test_mainwindow.cpp index b4d9e4a..ab904f9 100644 --- a/tests/test_mainwindow.cpp +++ b/tests/test_mainwindow.cpp @@ -25,10 +25,13 @@ #include <QStandardPaths> #include <QTemporaryDir> +#include <QTableView> + #include "config.h" #include "keymap.h" #include "mainwindow.h" #include "messageview.h" +#include "threadlistmodel.h" /// MainWindow is mostly wiring, and the parts that need a real database are /// still verified manually. What is checked here is the action registry: the @@ -47,6 +50,7 @@ private slots: void uiStateIsNotWrittenIntoTheUserConfig(); void uiStateSurvivesARestart(); void missingUiStateLeavesTheDefaults(); + void headerStateFromADifferentColumnLayoutIsDiscarded(); }; void TestMainWindow::everyKnownActionIsRegistered() @@ -222,6 +226,46 @@ void TestMainWindow::missingUiStateLeavesTheDefaults() QStandardPaths::setTestModeEnabled(false); } +void TestMainWindow::headerStateFromADifferentColumnLayoutIsDiscarded() +{ + // The upgrade hazard: a 0.3.0 state file holds a three-column header blob, + // and 0.4.0 added the attachment column in front. QHeaderView:: + // restoreState() returns TRUE for a blob with fewer sections than the + // model and applies the old widths shifted one column right, mangling the + // layout with no error to detect it by (verified on Qt 6.11). The stored + // column count is what makes that detectable. + QStandardPaths::setTestModeEnabled(true); + QFile::remove(MainWindow::uiStatePath()); + + { + const Config config; + MainWindow window(config); + window.close(); + } + + // Forge a state file from an older layout: same blob, wrong column count. + { + QSettings state(MainWindow::uiStatePath(), QSettings::IniFormat); + state.setValue(QStringLiteral("threadlist/columns"), + int(ThreadListModel::ColumnCount) - 1); + state.setValue(QStringLiteral("threadlist/header"), + QByteArray("not a header this model could have saved")); + } + + // Constructing must not apply it, and must not crash on the garbage blob. + const Config config; + MainWindow reopened(config); + + auto *view = reopened.findChild<QTableView *>(); + QVERIFY(view); + QCOMPARE(view->columnWidth(ThreadListModel::AttachmentColumn), 28); + QCOMPARE(view->columnWidth(ThreadListModel::DateColumn), 130); + QCOMPARE(view->columnWidth(ThreadListModel::SubjectColumn), 520); + + QFile::remove(MainWindow::uiStatePath()); + QStandardPaths::setTestModeEnabled(false); +} + // Constructing a MainWindow needs a QApplication and a platform plugin. The // test has no display under ctest, so it runs offscreen unless the caller // asked for something else. diff --git a/tests/test_threadlistmodel.cpp b/tests/test_threadlistmodel.cpp index e8a5fa8..97f7fde 100644 --- a/tests/test_threadlistmodel.cpp +++ b/tests/test_threadlistmodel.cpp @@ -38,6 +38,7 @@ private slots: void unreadStylingSurvivesAnAccountChip(); void accountChipUsesTheConfiguredColour(); void deletedThreadsAreRedAndStruckThrough(); + void attachmentColumnIsFirstAndMarksOnlyTaggedThreads(); void spamThreadsAreOrangeAndStruckThrough(); void doomedStylingCoversEveryColumn(); void ordinaryThreadsCarryNoRowColour(); @@ -472,5 +473,46 @@ void TestThreadListModel::modelPassesQtTester() model.clear(); } +void TestThreadListModel::attachmentColumnIsFirstAndMarksOnlyTaggedThreads() +{ + // Leftmost, and narrow: the point is to see an attachment without opening + // the thread, which only works if the column is never scrolled away. + QCOMPARE(ThreadListModel::AttachmentColumn, 0); + + ThreadSummary plain = makeThread(QStringLiteral("t1"), + QStringLiteral("no attachment")); + ThreadSummary withFile = makeThread(QStringLiteral("t2"), + QStringLiteral("has one")); + // notmuch applies this tag itself while indexing, so no MIME parsing and + // no extra worker query are involved. + withFile.tags.append(QStringLiteral("attachment")); + + ThreadListModel model; + model.appendBatch({ plain, withFile }); + + const QModelIndex plainCell = + model.index(0, ThreadListModel::AttachmentColumn); + const QModelIndex fileCell = + model.index(1, ThreadListModel::AttachmentColumn); + + QVERIFY(model.data(plainCell, Qt::DisplayRole).toString().isEmpty()); + QCOMPARE(model.data(fileCell, Qt::DisplayRole).toString(), + ThreadListModel::attachmentGlyph()); + + // The glyph must be something a font can draw. An unrenderable codepoint + // shows as a tofu box, which reads as breakage rather than as a marker. + QVERIFY(!ThreadListModel::attachmentGlyph().isEmpty()); + + // Only the marked thread gets a tooltip, or an empty cell would claim to + // have an attachment on hover. + QVERIFY(model.data(plainCell, Qt::ToolTipRole).toString().isEmpty()); + QVERIFY(!model.data(fileCell, Qt::ToolTipRole).toString().isEmpty()); + + // The header carries no text: a label would set a minimum width far wider + // than the icon and defeat the narrow column. + QVERIFY(model.headerData(ThreadListModel::AttachmentColumn, Qt::Horizontal, + Qt::DisplayRole).toString().isEmpty()); +} + QTEST_MAIN(TestThreadListModel) #include "test_threadlistmodel.moc" |
