Skip to content

Commit

Permalink
Fix assert hit when viewing entry history
Browse files Browse the repository at this point in the history
* Fixes #11371
* Adds test for showing entry history
* Improved page switching capabilities for entry edit widget
  • Loading branch information
droidmonkey committed Oct 27, 2024
1 parent 5d24495 commit 2738a72
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 23 deletions.
3 changes: 2 additions & 1 deletion src/gui/DatabaseWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ DatabaseWidget::DatabaseWidget(QSharedPointer<Database> db, QWidget* parent)
m_previewSplitter->setSizes({1, 1});

m_editEntryWidget->setObjectName("editEntryWidget");
m_historyEditEntryWidget->setObjectName("editEntryHistoryWidget");
m_editGroupWidget->setObjectName("editGroupWidget");
m_reportsDialog->setObjectName("reportsDialog");
m_databaseSettingDialog->setObjectName("databaseSettingsDialog");
Expand Down Expand Up @@ -277,7 +278,7 @@ DatabaseWidget::Mode DatabaseWidget::currentMode() const
mode = Mode::ReportsMode;
} else if (widget == m_databaseSettingDialog) {
mode = Mode::DatabaseSettingsMode;
} else if (widget == m_editEntryWidget) {
} else if (widget == m_editEntryWidget || widget == m_historyEditEntryWidget) {
mode = Mode::EditEntryMode;
} else if (widget == m_editGroupWidget) {
mode = Mode::EditGroupMode;
Expand Down
15 changes: 12 additions & 3 deletions src/gui/EditWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,25 @@ void EditWidget::addPage(const QString& labelText, const QIcon& icon, QWidget* w
m_ui->categoryList->addCategory(labelText, icon);
}

bool EditWidget::hasPage(QWidget* widget)
bool EditWidget::hasPage(const QWidget* widget) const
{
return pageIndex(widget) >= 0;
}

int EditWidget::pageIndex(const QWidget* widget) const
{
if (!widget) {
return -1;
}

for (int i = 0; i < m_ui->stackedWidget->count(); i++) {
auto* scrollArea = qobject_cast<QScrollArea*>(m_ui->stackedWidget->widget(i));
if (scrollArea && scrollArea->widget() == widget) {
return true;
return i;
}
}

return false;
return -1;
}

void EditWidget::setPageHidden(QWidget* widget, bool hidden)
Expand Down
3 changes: 2 additions & 1 deletion src/gui/EditWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class EditWidget : public DialogyWidget
~EditWidget() override;

void addPage(const QString& labelText, const QIcon& icon, QWidget* widget);
bool hasPage(QWidget* widget);
bool hasPage(const QWidget* widget) const;
int pageIndex(const QWidget* widget) const;
void setPageHidden(QWidget* widget, bool hidden);
void setCurrentPage(int index);
void setHeadline(const QString& text);
Expand Down
47 changes: 44 additions & 3 deletions src/gui/entry/EditEntryWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,47 @@ EditEntryWidget::EditEntryWidget(QWidget* parent)

EditEntryWidget::~EditEntryWidget() = default;

bool EditEntryWidget::switchToPage(Page page)
{
auto index = pageIndex(widgetForPage(page));
if (index >= 0) {
setCurrentPage(index);
return true;
}
return false;
}

QWidget* EditEntryWidget::widgetForPage(Page page) const
{
switch (page) {
case Page::Main:
return m_mainWidget;
case Page::Advanced:
return m_advancedWidget;
case Page::Icon:
return m_iconsWidget;
case Page::AutoType:
return m_autoTypeWidget;
case Page::Browser:
#ifdef WITH_XC_BROWSER
return m_browserWidget;
#else
return nullptr;
#endif
case Page::SSHAgent:
#ifdef WITH_XC_SSHAGENT
return m_sshAgentWidget;
#else
return nullptr;
#endif
case Page::Properties:
return m_editWidgetProperties;
case Page::History:
return m_historyWidget;
}
return nullptr;
}

void EditEntryWidget::setupMain()
{
m_mainUi->setupUi(m_mainWidget);
Expand Down Expand Up @@ -886,7 +927,7 @@ void EditEntryWidget::loadEntry(Entry* entry,
setForms(entry);
setReadOnly(m_history);

setCurrentPage(0);
switchToPage(Page::Main);
setPageHidden(m_historyWidget, m_history || m_entry->historyItems().count() < 1);
#ifdef WITH_XC_SSHAGENT
setPageHidden(m_sshAgentWidget, !sshAgent()->isEnabled());
Expand Down Expand Up @@ -1131,7 +1172,7 @@ bool EditEntryWidget::commitEntry()
MessageBox::Yes | MessageBox::No,
MessageBox::Yes);
if (res == MessageBox::Yes) {
setCurrentPage(3);
switchToPage(Page::AutoType);
return false;
}
}
Expand All @@ -1146,7 +1187,7 @@ bool EditEntryWidget::commitEntry()
MessageBox::Yes | MessageBox::No,
MessageBox::Yes);
if (res == MessageBox::Yes) {
setCurrentPage(3);
switchToPage(Page::AutoType);
return false;
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/gui/entry/EditEntryWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ class EditEntryWidget : public EditWidget
Entry* currentEntry() const;
void clear();

enum class Page
{
Main,
Advanced,
Icon,
AutoType,
Browser,
SSHAgent,
Properties,
History
};
bool switchToPage(Page page);

signals:
void editFinished(bool accepted);
void historyEntryActivated(Entry* entry);
Expand Down Expand Up @@ -162,6 +175,8 @@ private slots:

void displayAttribute(QModelIndex index, bool showProtected);

QWidget* widgetForPage(Page page) const;

QPointer<Entry> m_entry;
QSharedPointer<Database> m_db;

Expand Down
50 changes: 35 additions & 15 deletions tests/gui/TestGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,28 @@ void TestGui::testEditEntry()
QCOMPARE(entry->historyItems().size(), ++editCount);
QVERIFY(!applyButton->isEnabled());

// Test viewing entry history
auto historyView = editEntryWidget->findChild<QTreeView*>("historyView");
auto showButton = editEntryWidget->findChild<QPushButton*>("showButton");
QVERIFY(historyView);
editEntryWidget->switchToPage(EditEntryWidget::Page::History);
QApplication::processEvents();
QVERIFY(historyView->isVisible());
QVERIFY(!showButton->isEnabled());
// Select the second row in the history view
historyView->setCurrentIndex(historyView->model()->index(1, 0));
QVERIFY(showButton->isEnabled());
QTest::mouseClick(showButton, Qt::LeftButton);
// Verify that the entry history widget is shown
auto entryHistoryWidget = m_dbWidget->findChild<QWidget*>("editEntryHistoryWidget");
QVERIFY(entryHistoryWidget);
QVERIFY(entryHistoryWidget->isVisible());
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditEntryMode);
QTest::keyClick(entryHistoryWidget, Qt::Key_Escape);
QVERIFY(historyView->isVisible());

// Test the "known bad" checkbox
editEntryWidget->setCurrentPage(1);
editEntryWidget->switchToPage(EditEntryWidget::Page::Advanced);
auto excludeReportsCheckBox = editEntryWidget->findChild<QCheckBox*>("excludeReportsCheckBox");
QVERIFY(excludeReportsCheckBox);
QCOMPARE(excludeReportsCheckBox->isChecked(), false);
Expand All @@ -651,7 +671,7 @@ void TestGui::testEditEntry()
QCOMPARE(tags->tags().last(), QString("tag 2_is!awesome"));

// Test entry colors (simulate choosing a color)
editEntryWidget->setCurrentPage(1);
editEntryWidget->switchToPage(EditEntryWidget::Page::Advanced);
auto fgColor = QString("#FF0000");
auto bgColor = QString("#0000FF");
// Set foreground color
Expand All @@ -668,7 +688,7 @@ void TestGui::testEditEntry()
QCOMPARE(entry->historyItems().size(), ++editCount);

// Test protected attributes
editEntryWidget->setCurrentPage(1);
editEntryWidget->switchToPage(EditEntryWidget::Page::Advanced);
auto* attrTextEdit = editEntryWidget->findChild<QPlainTextEdit*>("attributesEdit");
QTest::mouseClick(editEntryWidget->findChild<QAbstractButton*>("addAttributeButton"), Qt::LeftButton);
QString attrText = "TEST TEXT";
Expand All @@ -678,7 +698,7 @@ void TestGui::testEditEntry()
QVERIFY(attrTextEdit->toPlainText().contains("PROTECTED"));
QTest::mouseClick(editEntryWidget->findChild<QAbstractButton*>("revealAttributeButton"), Qt::LeftButton);
QCOMPARE(attrTextEdit->toPlainText(), attrText);
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);

// Save the edit (press OK)
QTest::mouseClick(okButton, Qt::LeftButton);
Expand Down Expand Up @@ -1057,7 +1077,7 @@ void TestGui::testTotp()
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditEntryMode);

auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
editEntryWidget->setCurrentPage(1);
editEntryWidget->switchToPage(EditEntryWidget::Page::Advanced);
auto* attrTextEdit = editEntryWidget->findChild<QPlainTextEdit*>("attributesEdit");
QTest::mouseClick(editEntryWidget->findChild<QAbstractButton*>("revealAttributeButton"), Qt::LeftButton);
QCOMPARE(attrTextEdit->toPlainText(), expectedFinalSeed);
Expand Down Expand Up @@ -1779,7 +1799,7 @@ void TestGui::testDatabaseSettings()
QTest::keyClicks(titleEdit, "Test autosaveDelay 1");

// 2.b) Save changes
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);
auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);

Expand All @@ -1793,7 +1813,7 @@ void TestGui::testDatabaseSettings()
QTest::keyClicks(titleEdit, "Test autosaveDelay 2");

// 2.e) Save changes
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);
editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);

Expand All @@ -1813,7 +1833,7 @@ void TestGui::testDatabaseSettings()
QTest::keyClicks(titleEdit, "Test autosaveDelay 3");

// 4.b) Save changes
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);
editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);

Expand All @@ -1832,7 +1852,7 @@ void TestGui::testDatabaseSettings()
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditEntryMode);
QTest::keyClicks(titleEdit, "Test autosaveDelay 4");
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);
editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
Tools::wait(150); // due to modify timer
Expand Down Expand Up @@ -2124,7 +2144,7 @@ void TestGui::testAutoType()
QTest::keyClicks(usernameComboBox, "AutocompletionUsername");

// 1.b) Uncheck Auto-Type checkbox
editEntryWidget->setCurrentPage(3);
editEntryWidget->switchToPage(EditEntryWidget::Page::AutoType);
auto* enableAutoTypeButton = editEntryWidget->findChild<QCheckBox*>("enableButton");
QVERIFY(enableAutoTypeButton);
QVERIFY(enableAutoTypeButton->isVisible());
Expand All @@ -2134,7 +2154,7 @@ void TestGui::testAutoType()
QVERIFY(!enableAutoTypeButton->isChecked());

// 1.c) Save changes
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);
auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);

Expand All @@ -2148,13 +2168,13 @@ void TestGui::testAutoType()
QTest::keyClicks(usernameComboBox, "AutocompletionUsername");

// 2.b) Confirm AutoType is enabled and default
editEntryWidget->setCurrentPage(3);
editEntryWidget->switchToPage(EditEntryWidget::Page::AutoType);
QVERIFY(enableAutoTypeButton->isChecked());
auto* inheritSequenceButton = editEntryWidget->findChild<QRadioButton*>("inheritSequenceButton");
QVERIFY(inheritSequenceButton->isChecked());

// 2.c) Save changes
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);

// 3. Create an entry with custom Auto-Type sequence
Expand All @@ -2167,7 +2187,7 @@ void TestGui::testAutoType()
QTest::keyClicks(usernameComboBox, "AutocompletionUsername");

// 3.b) Confirm AutoType is enabled and set custom sequence
editEntryWidget->setCurrentPage(3);
editEntryWidget->switchToPage(EditEntryWidget::Page::AutoType);
QVERIFY(enableAutoTypeButton->isChecked());
auto* customSequenceButton = editEntryWidget->findChild<QRadioButton*>("customSequenceButton");
QTest::mouseClick(customSequenceButton, Qt::LeftButton);
Expand All @@ -2180,7 +2200,7 @@ void TestGui::testAutoType()
QTest::keyClicks(sequenceEdit, "{USERNAME}{TAB}{TAB}{PASSWORD}{ENTER}");

// 3.c) Save changes
editEntryWidget->setCurrentPage(0);
editEntryWidget->switchToPage(EditEntryWidget::Page::Main);
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
QApplication::processEvents();

Expand Down

0 comments on commit 2738a72

Please sign in to comment.