Refactor Database and Database widgets (#2491)
The Database, DatabaseWidget, and DatabaseTabWidget classes share many responsibilities in inconsistent ways resulting in impenetrable and unmaintainable code and a diverse set of bugs and architecture restrictions. This patch reworks the architecture, responsibilities of, and dependencies between these classes. The core changes are: * Move loading and saving logic from widgets into the Database class * Get rid of the DatabaseManagerStruct and move all the information contained in it into the Database * Let database objects keep track of modifications and dirty/clean state instead of handing this to external widgets * Move GUI interactions for loading and saving from the DatabaseTabWidget into the DatabaseWidget (resolves #2494 as a side-effect) * Heavily clean up DatabaseTabWidget and degrade it to a slightly glorified QTabWidget * Use QSharedPointers for all Database objects * Remove the modifiedImmediate signal and replace it with a markAsModified() method * Implement proper tabName() method instead of reading back titles from GUI widgets (resolves #1389 and its duplicates #2146 #855) * Fix unwanted AES-KDF downgrade if database uses Argon2 and has CustomData * Improve code This patch is also the first major step towards solving issues #476 and #2322.
This commit is contained in:
@@ -57,7 +57,7 @@ void TestAutoType::init()
|
||||
config()->set("AutoTypeEntryTitleMatch", false);
|
||||
m_test->clearActions();
|
||||
|
||||
m_db = new Database();
|
||||
m_db = QSharedPointer<Database>::create();
|
||||
m_dbList.clear();
|
||||
m_dbList.append(m_db);
|
||||
m_group = new Group();
|
||||
@@ -126,7 +126,6 @@ void TestAutoType::init()
|
||||
|
||||
void TestAutoType::cleanup()
|
||||
{
|
||||
delete m_db;
|
||||
}
|
||||
|
||||
void TestAutoType::testInternal()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define KEEPASSX_TESTAUTOTYPE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class AutoType;
|
||||
class AutoTypePlatformInterface;
|
||||
@@ -53,8 +54,8 @@ private:
|
||||
AutoTypePlatformInterface* m_platform;
|
||||
AutoTypeTestInterface* m_test;
|
||||
AutoType* m_autoType;
|
||||
Database* m_db;
|
||||
QList<Database*> m_dbList;
|
||||
QSharedPointer<Database> m_db;
|
||||
QList<QSharedPointer<Database>> m_dbList;
|
||||
Group* m_group;
|
||||
Entry* m_entry1;
|
||||
Entry* m_entry2;
|
||||
|
||||
@@ -671,7 +671,8 @@ void TestCli::testMerge()
|
||||
|
||||
QFile readBack(targetFile1.fileName());
|
||||
readBack.open(QIODevice::ReadOnly);
|
||||
QScopedPointer<Database> mergedDb(reader.readDatabase(&readBack, oldKey));
|
||||
auto mergedDb = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&readBack, oldKey, mergedDb.data());
|
||||
readBack.close();
|
||||
QVERIFY(mergedDb);
|
||||
auto* entry1 = mergedDb->rootGroup()->findEntryByPath("/Internet/Some Website");
|
||||
@@ -691,7 +692,8 @@ void TestCli::testMerge()
|
||||
|
||||
readBack.setFileName(targetFile2.fileName());
|
||||
readBack.open(QIODevice::ReadOnly);
|
||||
mergedDb.reset(reader.readDatabase(&readBack, key));
|
||||
mergedDb = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&readBack, key, mergedDb.data());
|
||||
readBack.close();
|
||||
QVERIFY(mergedDb);
|
||||
entry1 = mergedDb->rootGroup()->findEntryByPath("/Internet/Some Website");
|
||||
@@ -740,7 +742,8 @@ void TestCli::testRemove()
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("a"));
|
||||
QFile readBack(m_dbFile->fileName());
|
||||
readBack.open(QIODevice::ReadOnly);
|
||||
QScopedPointer<Database> readBackDb(reader.readDatabase(&readBack, key));
|
||||
auto readBackDb = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&readBack, key, readBackDb.data());
|
||||
readBack.close();
|
||||
QVERIFY(readBackDb);
|
||||
QVERIFY(!readBackDb->rootGroup()->findEntryByPath("/Sample Entry"));
|
||||
@@ -757,7 +760,8 @@ void TestCli::testRemove()
|
||||
|
||||
readBack.setFileName(fileCopy.fileName());
|
||||
readBack.open(QIODevice::ReadOnly);
|
||||
readBackDb.reset(reader.readDatabase(&readBack, key));
|
||||
readBackDb = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&readBack, key, readBackDb.data());
|
||||
readBack.close();
|
||||
QVERIFY(readBackDb);
|
||||
QVERIFY(!readBackDb->rootGroup()->findEntryByPath("/Sample Entry"));
|
||||
|
||||
@@ -31,8 +31,8 @@ const QString TestCsvExporter::ExpectedHeaderLine =
|
||||
|
||||
void TestCsvExporter::init()
|
||||
{
|
||||
m_db = new Database();
|
||||
m_csvExporter = new CsvExporter();
|
||||
m_db = QSharedPointer<Database>::create();
|
||||
m_csvExporter = QSharedPointer<CsvExporter>::create();
|
||||
}
|
||||
|
||||
void TestCsvExporter::initTestCase()
|
||||
@@ -42,17 +42,15 @@ void TestCsvExporter::initTestCase()
|
||||
|
||||
void TestCsvExporter::cleanup()
|
||||
{
|
||||
delete m_db;
|
||||
delete m_csvExporter;
|
||||
}
|
||||
|
||||
void TestCsvExporter::testExport()
|
||||
{
|
||||
Group* groupRoot = m_db->rootGroup();
|
||||
Group* group = new Group();
|
||||
auto* group = new Group();
|
||||
group->setName("Test Group Name");
|
||||
group->setParent(groupRoot);
|
||||
Entry* entry = new Entry();
|
||||
auto* entry = new Entry();
|
||||
entry->setGroup(group);
|
||||
entry->setTitle("Test Entry Title");
|
||||
entry->setUsername("Test Username");
|
||||
@@ -65,7 +63,7 @@ void TestCsvExporter::testExport()
|
||||
m_csvExporter->exportDatabase(&buffer, m_db);
|
||||
|
||||
QString expectedResult =
|
||||
QString().append(ExpectedHeaderLine).append("\"Test Group Name\",\"Test Entry Title\",\"Test Username\",\"Test "
|
||||
QString().append(ExpectedHeaderLine).append("\"Root/Test Group Name\",\"Test Entry Title\",\"Test Username\",\"Test "
|
||||
"Password\",\"http://test.url\",\"Test Notes\"\n");
|
||||
|
||||
QCOMPARE(QString::fromUtf8(buffer.buffer().constData()), expectedResult);
|
||||
@@ -83,13 +81,13 @@ void TestCsvExporter::testEmptyDatabase()
|
||||
void TestCsvExporter::testNestedGroups()
|
||||
{
|
||||
Group* groupRoot = m_db->rootGroup();
|
||||
Group* group = new Group();
|
||||
auto* group = new Group();
|
||||
group->setName("Test Group Name");
|
||||
group->setParent(groupRoot);
|
||||
Group* childGroup = new Group();
|
||||
auto* childGroup = new Group();
|
||||
childGroup->setName("Test Sub Group Name");
|
||||
childGroup->setParent(group);
|
||||
Entry* entry = new Entry();
|
||||
auto* entry = new Entry();
|
||||
entry->setGroup(childGroup);
|
||||
entry->setTitle("Test Entry Title");
|
||||
|
||||
@@ -100,5 +98,5 @@ void TestCsvExporter::testNestedGroups()
|
||||
QCOMPARE(QString::fromUtf8(buffer.buffer().constData()),
|
||||
QString()
|
||||
.append(ExpectedHeaderLine)
|
||||
.append("\"Test Group Name/Test Sub Group Name\",\"Test Entry Title\",\"\",\"\",\"\",\"\"\n"));
|
||||
.append("\"Root/Test Group Name/Test Sub Group Name\",\"Test Entry Title\",\"\",\"\",\"\",\"\"\n"));
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define KEEPASSX_TESTCSVEXPORTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class Database;
|
||||
class CsvExporter;
|
||||
@@ -40,8 +41,8 @@ private slots:
|
||||
void testNestedGroups();
|
||||
|
||||
private:
|
||||
Database* m_db;
|
||||
CsvExporter* m_csvExporter;
|
||||
QSharedPointer<Database> m_db;
|
||||
QSharedPointer<CsvExporter> m_csvExporter;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_TESTCSVEXPORTER_H
|
||||
|
||||
@@ -40,14 +40,18 @@ void TestDatabase::testEmptyRecycleBinOnDisabled()
|
||||
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinDisabled.kdbx");
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("123"));
|
||||
QScopedPointer<Database> db(Database::openDatabaseFile(filename, key));
|
||||
QVERIFY(db);
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(filename, key, nullptr, false));
|
||||
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
// Explicitly mark DB as read-write in case it was opened from a read-only drive.
|
||||
// Prevents assertion failures on CI systems when the data dir is not writable
|
||||
db->setReadOnly(false);
|
||||
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(databaseModified()));
|
||||
|
||||
db->emptyRecycleBin();
|
||||
// The database must be unmodified in this test after emptying the recycle bin.
|
||||
QCOMPARE(spyModified.count(), 0);
|
||||
QTRY_COMPARE(spyModified.count(), 0);
|
||||
}
|
||||
|
||||
void TestDatabase::testEmptyRecycleBinOnNotCreated()
|
||||
@@ -55,14 +59,15 @@ void TestDatabase::testEmptyRecycleBinOnNotCreated()
|
||||
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinNotYetCreated.kdbx");
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("123"));
|
||||
QScopedPointer<Database> db(Database::openDatabaseFile(filename, key));
|
||||
QVERIFY(db);
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(filename, key, nullptr, false));
|
||||
db->setReadOnly(false);
|
||||
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(databaseModified()));
|
||||
|
||||
db->emptyRecycleBin();
|
||||
// The database must be unmodified in this test after emptying the recycle bin.
|
||||
QCOMPARE(spyModified.count(), 0);
|
||||
QTRY_COMPARE(spyModified.count(), 0);
|
||||
}
|
||||
|
||||
void TestDatabase::testEmptyRecycleBinOnEmpty()
|
||||
@@ -70,14 +75,15 @@ void TestDatabase::testEmptyRecycleBinOnEmpty()
|
||||
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinEmpty.kdbx");
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("123"));
|
||||
QScopedPointer<Database> db(Database::openDatabaseFile(filename, key));
|
||||
QVERIFY(db);
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(filename, key, nullptr, false));
|
||||
db->setReadOnly(false);
|
||||
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(databaseModified()));
|
||||
|
||||
db->emptyRecycleBin();
|
||||
// The database must be unmodified in this test after emptying the recycle bin.
|
||||
QCOMPARE(spyModified.count(), 0);
|
||||
QTRY_COMPARE(spyModified.count(), 0);
|
||||
}
|
||||
|
||||
void TestDatabase::testEmptyRecycleBinWithHierarchicalData()
|
||||
@@ -85,8 +91,9 @@ void TestDatabase::testEmptyRecycleBinWithHierarchicalData()
|
||||
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/RecycleBinWithData.kdbx");
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("123"));
|
||||
QScopedPointer<Database> db(Database::openDatabaseFile(filename, key));
|
||||
QVERIFY(db);
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(filename, key, nullptr, false));
|
||||
db->setReadOnly(false);
|
||||
|
||||
QFile originalFile(filename);
|
||||
qint64 initialSize = originalFile.size();
|
||||
@@ -97,6 +104,8 @@ void TestDatabase::testEmptyRecycleBinWithHierarchicalData()
|
||||
QVERIFY(db->metadata()->recycleBin()->children().empty());
|
||||
|
||||
QTemporaryFile afterCleanup;
|
||||
afterCleanup.open();
|
||||
|
||||
KeePass2Writer writer;
|
||||
writer.writeDatabase(&afterCleanup, db.data());
|
||||
QVERIFY(afterCleanup.size() < initialSize);
|
||||
|
||||
@@ -30,7 +30,7 @@ void TestDeletedObjects::initTestCase()
|
||||
QVERIFY(Crypto::init());
|
||||
}
|
||||
|
||||
void TestDeletedObjects::createAndDelete(Database* db, int delObjectsSize)
|
||||
void TestDeletedObjects::createAndDelete(QSharedPointer<Database> db, int delObjectsSize)
|
||||
{
|
||||
QCOMPARE(db->deletedObjects().size(), delObjectsSize);
|
||||
Group* root = db->rootGroup();
|
||||
@@ -89,32 +89,27 @@ void TestDeletedObjects::testDeletedObjectsFromFile()
|
||||
KdbxXmlReader reader(KeePass2::FILE_VERSION_3_1);
|
||||
reader.setStrictMode(true);
|
||||
QString xmlFile = QString(KEEPASSX_TEST_DATA_DIR).append("/NewDatabase.xml");
|
||||
Database* db = reader.readDatabase(xmlFile);
|
||||
auto db = reader.readDatabase(xmlFile);
|
||||
|
||||
createAndDelete(db, 2);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestDeletedObjects::testDeletedObjectsFromNewDb()
|
||||
{
|
||||
Database* db = new Database();
|
||||
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
createAndDelete(db, 0);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestDeletedObjects::testDatabaseChange()
|
||||
{
|
||||
Database* db = new Database();
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
Group* root = db->rootGroup();
|
||||
int delObjectsSize = 0;
|
||||
Database* db2 = new Database();
|
||||
auto db2 = QSharedPointer<Database>::create();
|
||||
Group* root2 = db2->rootGroup();
|
||||
int delObjectsSize2 = 0;
|
||||
|
||||
Entry* e = new Entry();
|
||||
auto* e = new Entry();
|
||||
e->setGroup(root);
|
||||
|
||||
QCOMPARE(db->deletedObjects().size(), delObjectsSize);
|
||||
@@ -130,11 +125,11 @@ void TestDeletedObjects::testDatabaseChange()
|
||||
QCOMPARE(db->deletedObjects().size(), delObjectsSize);
|
||||
QCOMPARE(db2->deletedObjects().size(), ++delObjectsSize2);
|
||||
|
||||
Group* g1 = new Group();
|
||||
auto* g1 = new Group();
|
||||
g1->setParent(root);
|
||||
QUuid g1Uuid = QUuid::createUuid();
|
||||
g1->setUuid(g1Uuid);
|
||||
Entry* e1 = new Entry();
|
||||
auto* e1 = new Entry();
|
||||
e1->setGroup(g1);
|
||||
QUuid e1Uuid = QUuid::createUuid();
|
||||
e1->setUuid(e1Uuid);
|
||||
@@ -146,8 +141,8 @@ void TestDeletedObjects::testDatabaseChange()
|
||||
QCOMPARE(db->deletedObjects().at(delObjectsSize - 2).uuid, e1Uuid);
|
||||
QCOMPARE(db->deletedObjects().at(delObjectsSize - 1).uuid, g1Uuid);
|
||||
|
||||
Group* group = new Group();
|
||||
Entry* entry = new Entry();
|
||||
auto* group = new Group();
|
||||
auto* entry = new Entry();
|
||||
entry->setGroup(group);
|
||||
entry->setGroup(root);
|
||||
|
||||
@@ -155,6 +150,4 @@ void TestDeletedObjects::testDatabaseChange()
|
||||
QCOMPARE(db2->deletedObjects().size(), delObjectsSize2);
|
||||
|
||||
delete group;
|
||||
delete db;
|
||||
delete db2;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class TestDeletedObjects : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
void createAndDelete(Database* db, int delObjectsSize);
|
||||
void createAndDelete(QSharedPointer<Database> db, int delObjectsSize);
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
@@ -37,7 +37,7 @@ void TestKdbx2::initTestCase()
|
||||
/**
|
||||
* Helper method for verifying contents of the sample KDBX 2 file.
|
||||
*/
|
||||
void TestKdbx2::verifyKdbx2Db(Database* db)
|
||||
void TestKdbx2::verifyKdbx2Db(QSharedPointer<Database> db)
|
||||
{
|
||||
QVERIFY(db);
|
||||
QCOMPARE(db->rootGroup()->name(), QString("Format200"));
|
||||
@@ -67,12 +67,13 @@ void TestKdbx2::testFormat200()
|
||||
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/Format200.kdbx");
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("a"));
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
QVERIFY(reader.readDatabase(filename, key, db.data()));
|
||||
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_2 & KeePass2::FILE_VERSION_CRITICAL_MASK);
|
||||
|
||||
QVERIFY2(!reader.hasError(), reader.errorString().toStdString().c_str());
|
||||
verifyKdbx2Db(db.data());
|
||||
verifyKdbx2Db(db);
|
||||
}
|
||||
|
||||
void TestKdbx2::testFormat200Upgrade()
|
||||
@@ -80,8 +81,9 @@ void TestKdbx2::testFormat200Upgrade()
|
||||
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/Format200.kdbx");
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("a"));
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
reader.readDatabase(filename, key, db.data());
|
||||
QVERIFY2(!reader.hasError(), reader.errorString().toStdString().c_str());
|
||||
QVERIFY(!db.isNull());
|
||||
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_2 & KeePass2::FILE_VERSION_CRITICAL_MASK);
|
||||
@@ -92,20 +94,21 @@ void TestKdbx2::testFormat200Upgrade()
|
||||
|
||||
// write KDBX 3 to upgrade it
|
||||
KeePass2Writer writer;
|
||||
writer.writeDatabase(&buffer, db.data());
|
||||
QVERIFY(writer.writeDatabase(&buffer, db.data()));
|
||||
if (writer.hasError()) {
|
||||
QFAIL(qPrintable(QString("Error while writing database: %1").arg(writer.errorString())));
|
||||
}
|
||||
|
||||
// read buffer back
|
||||
buffer.seek(0);
|
||||
QScopedPointer<Database> targetDb(reader.readDatabase(&buffer, key));
|
||||
auto targetDb = QSharedPointer<Database>::create();
|
||||
QVERIFY(reader.readDatabase(&buffer, key, targetDb.data()));
|
||||
if (reader.hasError()) {
|
||||
QFAIL(qPrintable(QString("Error while reading database: %1").arg(reader.errorString())));
|
||||
}
|
||||
|
||||
// database should now be upgraded to KDBX 3 without data loss
|
||||
verifyKdbx2Db(targetDb.data());
|
||||
verifyKdbx2Db(targetDb);
|
||||
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_3_1 & KeePass2::FILE_VERSION_CRITICAL_MASK);
|
||||
QCOMPARE(targetDb->kdf()->uuid(), KeePass2::KDF_AES_KDBX3);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ private slots:
|
||||
void testFormat200Upgrade();
|
||||
|
||||
private:
|
||||
void verifyKdbx2Db(Database* db);
|
||||
void verifyKdbx2Db(QSharedPointer<Database> db);
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_TEST_KDBX2_H
|
||||
|
||||
@@ -33,7 +33,7 @@ void TestKdbx3::initTestCaseImpl()
|
||||
{
|
||||
}
|
||||
|
||||
Database* TestKdbx3::readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString)
|
||||
QSharedPointer<Database> TestKdbx3::readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString)
|
||||
{
|
||||
KdbxXmlReader reader(KeePass2::FILE_VERSION_3_1);
|
||||
reader.setStrictMode(strictMode);
|
||||
@@ -43,7 +43,7 @@ Database* TestKdbx3::readXml(const QString& path, bool strictMode, bool& hasErro
|
||||
return db;
|
||||
}
|
||||
|
||||
Database* TestKdbx3::readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString)
|
||||
QSharedPointer<Database> TestKdbx3::readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString)
|
||||
{
|
||||
KdbxXmlReader reader(KeePass2::FILE_VERSION_3_1);
|
||||
reader.setStrictMode(strictMode);
|
||||
@@ -63,12 +63,12 @@ void TestKdbx3::writeXml(QBuffer* buf, Database* db, bool& hasError, QString& er
|
||||
|
||||
void TestKdbx3::readKdbx(QIODevice* device,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString)
|
||||
{
|
||||
KeePass2Reader reader;
|
||||
db.reset(reader.readDatabase(device, key));
|
||||
reader.readDatabase(device, key, db.data());
|
||||
hasError = reader.hasError();
|
||||
if (hasError) {
|
||||
errorString = reader.errorString();
|
||||
@@ -78,12 +78,12 @@ void TestKdbx3::readKdbx(QIODevice* device,
|
||||
|
||||
void TestKdbx3::readKdbx(const QString& path,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString)
|
||||
{
|
||||
KeePass2Reader reader;
|
||||
db.reset(reader.readDatabase(path, key));
|
||||
reader.readDatabase(path, key, db.data());
|
||||
hasError = reader.hasError();
|
||||
if (hasError) {
|
||||
errorString = reader.errorString();
|
||||
@@ -108,7 +108,8 @@ void TestKdbx3::testFormat300()
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("a"));
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(reader.readDatabase(filename, key, db.data()));
|
||||
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_3);
|
||||
QVERIFY(db.data());
|
||||
QVERIFY(!reader.hasError());
|
||||
@@ -123,11 +124,12 @@ void TestKdbx3::testNonAscii()
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create(QString::fromUtf8("\xce\x94\xc3\xb6\xd8\xb6")));
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(filename, key, nullptr, false));
|
||||
QVERIFY(db.data());
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->metadata()->name(), QString("NonAsciiTest"));
|
||||
QCOMPARE(db->compressionAlgo(), Database::CompressionNone);
|
||||
QCOMPARE(db->compressionAlgorithm(), Database::CompressionNone);
|
||||
}
|
||||
|
||||
void TestKdbx3::testCompressed()
|
||||
@@ -136,11 +138,12 @@ void TestKdbx3::testCompressed()
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create(""));
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(filename, key, nullptr, false));
|
||||
QVERIFY(db.data());
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->metadata()->name(), QString("Compressed"));
|
||||
QCOMPARE(db->compressionAlgo(), Database::CompressionGZip);
|
||||
QCOMPARE(db->compressionAlgorithm(), Database::CompressionGZip);
|
||||
}
|
||||
|
||||
void TestKdbx3::testProtectedStrings()
|
||||
@@ -149,7 +152,8 @@ void TestKdbx3::testProtectedStrings()
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("masterpw"));
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(filename, key, nullptr, false));
|
||||
QVERIFY(db.data());
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->metadata()->name(), QString("Protected Strings Test"));
|
||||
@@ -175,8 +179,6 @@ void TestKdbx3::testBrokenHeaderHash()
|
||||
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/BrokenHeaderHash.kdbx");
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create(""));
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
QVERIFY(!db.data());
|
||||
QVERIFY(reader.hasError());
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(!db->open(filename, key, nullptr, false));
|
||||
}
|
||||
|
||||
@@ -34,18 +34,18 @@ private slots:
|
||||
protected:
|
||||
void initTestCaseImpl() override;
|
||||
|
||||
Database* readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
Database* readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
QSharedPointer<Database> readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
QSharedPointer<Database> readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
void writeXml(QBuffer* buf, Database* db, bool& hasError, QString& errorString) override;
|
||||
|
||||
void readKdbx(QIODevice* device,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString) override;
|
||||
void readKdbx(const QString& path,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString) override;
|
||||
void writeKdbx(QIODevice* device, Database* db, bool& hasError, QString& errorString) override;
|
||||
|
||||
@@ -37,7 +37,7 @@ void TestKdbx4::initTestCaseImpl()
|
||||
m_kdbxSourceDb->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)));
|
||||
}
|
||||
|
||||
Database* TestKdbx4::readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString)
|
||||
QSharedPointer<Database> TestKdbx4::readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString)
|
||||
{
|
||||
KdbxXmlReader reader(KeePass2::FILE_VERSION_4);
|
||||
reader.setStrictMode(strictMode);
|
||||
@@ -47,7 +47,7 @@ Database* TestKdbx4::readXml(const QString& path, bool strictMode, bool& hasErro
|
||||
return db;
|
||||
}
|
||||
|
||||
Database* TestKdbx4::readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString)
|
||||
QSharedPointer<Database> TestKdbx4::readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString)
|
||||
{
|
||||
KdbxXmlReader reader(KeePass2::FILE_VERSION_4);
|
||||
reader.setStrictMode(strictMode);
|
||||
@@ -67,12 +67,12 @@ void TestKdbx4::writeXml(QBuffer* buf, Database* db, bool& hasError, QString& er
|
||||
|
||||
void TestKdbx4::readKdbx(QIODevice* device,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString)
|
||||
{
|
||||
KeePass2Reader reader;
|
||||
db.reset(reader.readDatabase(device, key));
|
||||
reader.readDatabase(device, key, db.data());
|
||||
hasError = reader.hasError();
|
||||
if (hasError) {
|
||||
errorString = reader.errorString();
|
||||
@@ -82,12 +82,12 @@ void TestKdbx4::readKdbx(QIODevice* device,
|
||||
|
||||
void TestKdbx4::readKdbx(const QString& path,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString)
|
||||
{
|
||||
KeePass2Reader reader;
|
||||
db.reset(reader.readDatabase(path, key));
|
||||
reader.readDatabase(path, key, db.data());
|
||||
hasError = reader.hasError();
|
||||
if (hasError) {
|
||||
errorString = reader.errorString();
|
||||
@@ -116,7 +116,8 @@ void TestKdbx4::testFormat400()
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("t"));
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(filename, key, db.data());
|
||||
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_4);
|
||||
QVERIFY(db.data());
|
||||
QVERIFY(!reader.hasError());
|
||||
@@ -174,7 +175,8 @@ void TestKdbx4::testFormat400Upgrade()
|
||||
// read buffer back
|
||||
buffer.seek(0);
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> targetDb(reader.readDatabase(&buffer, key));
|
||||
auto targetDb = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&buffer, key, targetDb.data());
|
||||
if (reader.hasError()) {
|
||||
QFAIL(qPrintable(QString("Error while reading database: %1").arg(reader.errorString())));
|
||||
}
|
||||
@@ -292,14 +294,15 @@ void TestKdbx4::testUpgradeMasterKeyIntegrity()
|
||||
// paranoid check that we cannot decrypt the database without a key
|
||||
buffer.seek(0);
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> db2;
|
||||
db2.reset(reader.readDatabase(&buffer, QSharedPointer<CompositeKey>::create()));
|
||||
auto db2 = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&buffer, QSharedPointer<CompositeKey>::create(), db2.data());
|
||||
QVERIFY(reader.hasError());
|
||||
|
||||
// check that we can read back the database with the original composite key,
|
||||
// i.e., no components have been lost on the way
|
||||
buffer.seek(0);
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKey));
|
||||
db2 = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&buffer, compositeKey, db2.data());
|
||||
if (reader.hasError()) {
|
||||
QFAIL(qPrintable(reader.errorString()));
|
||||
}
|
||||
@@ -396,7 +399,8 @@ void TestKdbx4::testCustomData()
|
||||
// read buffer back
|
||||
buffer.seek(0);
|
||||
KeePass2Reader reader;
|
||||
QSharedPointer<Database> newDb(reader.readDatabase(&buffer, QSharedPointer<CompositeKey>::create()));
|
||||
auto newDb = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&buffer, QSharedPointer<CompositeKey>::create(), newDb.data());
|
||||
|
||||
// test all custom data are read back successfully from KDBX
|
||||
QCOMPARE(newDb->publicCustomData(), publicCustomData);
|
||||
|
||||
@@ -35,18 +35,18 @@ private slots:
|
||||
protected:
|
||||
void initTestCaseImpl() override;
|
||||
|
||||
Database* readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
Database* readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
QSharedPointer<Database> readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
QSharedPointer<Database> readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString) override;
|
||||
void writeXml(QBuffer* buf, Database* db, bool& hasError, QString& errorString) override;
|
||||
|
||||
void readKdbx(const QString& path,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString) override;
|
||||
void readKdbx(QIODevice* device,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString) override;
|
||||
void writeKdbx(QIODevice* device, Database* db, bool& hasError, QString& errorString) override;
|
||||
|
||||
@@ -177,15 +177,13 @@ void TestKeePass1Reader::testFileKey()
|
||||
QString dbFilename = QString("%1/%2.kdb").arg(QString(KEEPASSX_TEST_DATA_DIR), name);
|
||||
QString keyFilename = QString("%1/%2.key").arg(QString(KEEPASSX_TEST_DATA_DIR), name);
|
||||
|
||||
Database* db = reader.readDatabase(dbFilename, QString(), keyFilename);
|
||||
auto db = reader.readDatabase(dbFilename, QString(), keyFilename);
|
||||
QVERIFY(db);
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->rootGroup()->children().size(), 1);
|
||||
QCOMPARE(db->rootGroup()->children().at(0)->name(), name);
|
||||
|
||||
reopenDatabase(db, QString(), keyFilename);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestKeePass1Reader::testFileKey_data()
|
||||
@@ -205,15 +203,13 @@ void TestKeePass1Reader::testCompositeKey()
|
||||
QString dbFilename = QString("%1/%2.kdb").arg(QString(KEEPASSX_TEST_DATA_DIR), name);
|
||||
QString keyFilename = QString("%1/FileKeyHex.key").arg(QString(KEEPASSX_TEST_DATA_DIR));
|
||||
|
||||
Database* db = reader.readDatabase(dbFilename, "mypassword", keyFilename);
|
||||
auto db = reader.readDatabase(dbFilename, "mypassword", keyFilename);
|
||||
QVERIFY(db);
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->rootGroup()->children().size(), 1);
|
||||
QCOMPARE(db->rootGroup()->children().at(0)->name(), name);
|
||||
|
||||
reopenDatabase(db, "mypassword", keyFilename);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestKeePass1Reader::testTwofish()
|
||||
@@ -224,13 +220,11 @@ void TestKeePass1Reader::testTwofish()
|
||||
|
||||
QString dbFilename = QString("%1/%2.kdb").arg(QString(KEEPASSX_TEST_DATA_DIR), name);
|
||||
|
||||
Database* db = reader.readDatabase(dbFilename, "masterpw", 0);
|
||||
auto db = reader.readDatabase(dbFilename, "masterpw", 0);
|
||||
QVERIFY(db);
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->rootGroup()->children().size(), 1);
|
||||
QCOMPARE(db->rootGroup()->children().at(0)->name(), name);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestKeePass1Reader::testCP1252Password()
|
||||
@@ -242,18 +236,15 @@ void TestKeePass1Reader::testCP1252Password()
|
||||
QString dbFilename = QString("%1/%2.kdb").arg(QString(KEEPASSX_TEST_DATA_DIR), name);
|
||||
QString password = QString::fromUtf8("\xe2\x80\x9e\x70\x61\x73\x73\x77\x6f\x72\x64\xe2\x80\x9d");
|
||||
|
||||
Database* db = reader.readDatabase(dbFilename, password, 0);
|
||||
auto db = reader.readDatabase(dbFilename, password, 0);
|
||||
QVERIFY(db);
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->rootGroup()->children().size(), 1);
|
||||
QCOMPARE(db->rootGroup()->children().at(0)->name(), name);
|
||||
|
||||
delete db;
|
||||
}
|
||||
|
||||
void TestKeePass1Reader::cleanupTestCase()
|
||||
{
|
||||
delete m_db;
|
||||
}
|
||||
|
||||
QDateTime TestKeePass1Reader::genDT(int year, int month, int day, int hour, int min)
|
||||
@@ -263,13 +254,15 @@ QDateTime TestKeePass1Reader::genDT(int year, int month, int day, int hour, int
|
||||
return QDateTime(date, time, Qt::UTC);
|
||||
}
|
||||
|
||||
void TestKeePass1Reader::reopenDatabase(Database* db, const QString& password, const QString& keyfileName)
|
||||
void TestKeePass1Reader::reopenDatabase(QSharedPointer<Database> db,
|
||||
const QString& password,
|
||||
const QString& keyfileName)
|
||||
{
|
||||
QBuffer buffer;
|
||||
buffer.open(QIODevice::ReadWrite);
|
||||
|
||||
KeePass2Writer writer;
|
||||
writer.writeDatabase(&buffer, db);
|
||||
writer.writeDatabase(&buffer, db.data());
|
||||
QVERIFY(!writer.hasError());
|
||||
QVERIFY(buffer.seek(0));
|
||||
|
||||
@@ -284,7 +277,7 @@ void TestKeePass1Reader::reopenDatabase(Database* db, const QString& password, c
|
||||
}
|
||||
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> newDb(reader.readDatabase(&buffer, key));
|
||||
QVERIFY(newDb);
|
||||
auto newDb = QSharedPointer<Database>::create();
|
||||
QVERIFY(reader.readDatabase(&buffer, key, newDb.data()));
|
||||
QVERIFY(!reader.hasError());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class Database;
|
||||
|
||||
@@ -43,9 +44,9 @@ private slots:
|
||||
|
||||
private:
|
||||
static QDateTime genDT(int year, int month, int day, int hour, int min);
|
||||
static void reopenDatabase(Database* db, const QString& password, const QString& keyfileName);
|
||||
static void reopenDatabase(QSharedPointer<Database> db, const QString& password, const QString& keyfileName);
|
||||
|
||||
Database* m_db;
|
||||
QSharedPointer<Database> m_db;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_TESTKEEPASS1READER_H
|
||||
|
||||
@@ -34,7 +34,7 @@ void TestKeePass2Format::initTestCase()
|
||||
// read raw XML database
|
||||
bool hasError;
|
||||
QString errorString;
|
||||
m_xmlDb.reset(readXml(QString(KEEPASSX_TEST_DATA_DIR).append("/NewDatabase.xml"), true, hasError, errorString));
|
||||
m_xmlDb = readXml(QString(KEEPASSX_TEST_DATA_DIR).append("/NewDatabase.xml"), true, hasError, errorString);
|
||||
if (hasError) {
|
||||
QFAIL(qPrintable(QString("Error while reading XML: ").append(errorString)));
|
||||
}
|
||||
@@ -44,7 +44,7 @@ void TestKeePass2Format::initTestCase()
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("test"));
|
||||
|
||||
m_kdbxSourceDb.reset(new Database());
|
||||
m_kdbxSourceDb = QSharedPointer<Database>::create();
|
||||
m_kdbxSourceDb->setKey(key);
|
||||
m_kdbxSourceDb->metadata()->setName("TESTDB");
|
||||
Group* group = m_kdbxSourceDb->rootGroup();
|
||||
@@ -351,7 +351,7 @@ void TestKeePass2Format::testXmlBroken()
|
||||
QVERIFY(QFile::exists(xmlFile));
|
||||
bool hasError;
|
||||
QString errorString;
|
||||
QScopedPointer<Database> db(readXml(xmlFile, strictMode, hasError, errorString));
|
||||
auto db = readXml(xmlFile, strictMode, hasError, errorString);
|
||||
if (hasError) {
|
||||
qWarning("Reader error: %s", qPrintable(errorString));
|
||||
}
|
||||
@@ -392,7 +392,7 @@ void TestKeePass2Format::testXmlEmptyUuids()
|
||||
QVERIFY(QFile::exists(xmlFile));
|
||||
bool hasError;
|
||||
QString errorString;
|
||||
QScopedPointer<Database> dbp(readXml(xmlFile, true, hasError, errorString));
|
||||
auto db = readXml(xmlFile, true, hasError, errorString);
|
||||
if (hasError) {
|
||||
qWarning("Reader error: %s", qPrintable(errorString));
|
||||
}
|
||||
@@ -446,7 +446,7 @@ void TestKeePass2Format::testXmlInvalidXmlChars()
|
||||
QVERIFY(!hasError);
|
||||
buffer.seek(0);
|
||||
|
||||
QScopedPointer<Database> dbRead(readXml(&buffer, true, hasError, errorString));
|
||||
auto dbRead = readXml(&buffer, true, hasError, errorString);
|
||||
if (hasError) {
|
||||
qWarning("Database read error: %s", qPrintable(errorString));
|
||||
}
|
||||
@@ -474,7 +474,7 @@ void TestKeePass2Format::testXmlRepairUuidHistoryItem()
|
||||
QVERIFY(QFile::exists(xmlFile));
|
||||
bool hasError;
|
||||
QString errorString;
|
||||
QScopedPointer<Database> db(readXml(xmlFile, false, hasError, errorString));
|
||||
auto db = readXml(xmlFile, false, hasError, errorString);
|
||||
if (hasError) {
|
||||
qWarning("Database read error: %s", qPrintable(errorString));
|
||||
}
|
||||
@@ -503,6 +503,7 @@ void TestKeePass2Format::testReadBackTargetDb()
|
||||
QString errorString;
|
||||
|
||||
m_kdbxTargetBuffer.seek(0);
|
||||
m_kdbxTargetDb = QSharedPointer<Database>::create();
|
||||
readKdbx(&m_kdbxTargetBuffer, key, m_kdbxTargetDb, hasError, errorString);
|
||||
if (hasError) {
|
||||
QFAIL(qPrintable(QString("Error while reading database: ").append(errorString)));
|
||||
@@ -548,7 +549,7 @@ void TestKeePass2Format::testKdbxDeviceFailure()
|
||||
QScopedPointer<Database> db(new Database());
|
||||
db->setKey(key);
|
||||
// Disable compression so we write a predictable number of bytes.
|
||||
db->setCompressionAlgo(Database::CompressionNone);
|
||||
db->setCompressionAlgorithm(Database::CompressionNone);
|
||||
|
||||
auto entry = new Entry();
|
||||
entry->setParent(db->rootGroup());
|
||||
@@ -569,7 +570,7 @@ void TestKeePass2Format::testKdbxDeviceFailure()
|
||||
*/
|
||||
void TestKeePass2Format::testDuplicateAttachments()
|
||||
{
|
||||
QScopedPointer<Database> db(new Database());
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
db->setKey(QSharedPointer<CompositeKey>::create());
|
||||
|
||||
const QByteArray attachment1("abc");
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <QBuffer>
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QScopedPointer>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "core/Database.h"
|
||||
|
||||
@@ -67,25 +67,25 @@ private slots:
|
||||
protected:
|
||||
virtual void initTestCaseImpl() = 0;
|
||||
|
||||
virtual Database* readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString) = 0;
|
||||
virtual Database* readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString) = 0;
|
||||
virtual QSharedPointer<Database> readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString) = 0;
|
||||
virtual QSharedPointer<Database> readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString) = 0;
|
||||
virtual void writeXml(QBuffer* buf, Database* db, bool& hasError, QString& errorString) = 0;
|
||||
|
||||
virtual void readKdbx(QIODevice* device,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString) = 0;
|
||||
virtual void readKdbx(const QString& path,
|
||||
QSharedPointer<const CompositeKey> key,
|
||||
QScopedPointer<Database>& db,
|
||||
QSharedPointer<Database> db,
|
||||
bool& hasError,
|
||||
QString& errorString) = 0;
|
||||
virtual void writeKdbx(QIODevice* device, Database* db, bool& hasError, QString& errorString) = 0;
|
||||
|
||||
QScopedPointer<Database> m_xmlDb;
|
||||
QScopedPointer<Database> m_kdbxSourceDb;
|
||||
QScopedPointer<Database> m_kdbxTargetDb;
|
||||
QSharedPointer<Database> m_xmlDb;
|
||||
QSharedPointer<Database> m_kdbxSourceDb;
|
||||
QSharedPointer<Database> m_kdbxTargetDb;
|
||||
|
||||
private:
|
||||
QBuffer m_kdbxTargetBuffer;
|
||||
|
||||
@@ -87,8 +87,8 @@ void TestKeys::testFileKey()
|
||||
|
||||
compositeKey->addKey(fileKey);
|
||||
|
||||
QScopedPointer<Database> db(reader.readDatabase(dbFilename, compositeKey));
|
||||
QVERIFY(db);
|
||||
auto db = QSharedPointer<Database>::create();
|
||||
QVERIFY(db->open(dbFilename, compositeKey, nullptr, false));
|
||||
QVERIFY(!reader.hasError());
|
||||
QCOMPARE(db->metadata()->name(), QString("%1 Database").arg(name));
|
||||
}
|
||||
@@ -152,7 +152,8 @@ void TestKeys::testCreateAndOpenFileKey()
|
||||
dbBuffer.reset();
|
||||
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> dbRead(reader.readDatabase(&dbBuffer, compositeKey));
|
||||
auto dbRead = QSharedPointer<Database>::create();
|
||||
reader.readDatabase(&dbBuffer, compositeKey, dbRead.data());
|
||||
if (reader.hasError()) {
|
||||
QFAIL(reader.errorString().toUtf8().constData());
|
||||
}
|
||||
@@ -236,7 +237,7 @@ void TestKeys::testCompositeKeyComponents()
|
||||
compositeKeyEnc->addKey(fileKeyEnc);
|
||||
compositeKeyEnc->addChallengeResponseKey(challengeResponseKeyEnc);
|
||||
|
||||
QScopedPointer<Database> db1(new Database());
|
||||
auto db1 = QSharedPointer<Database>::create();
|
||||
db1->setKey(compositeKeyEnc);
|
||||
|
||||
KeePass2Writer writer;
|
||||
@@ -245,27 +246,27 @@ void TestKeys::testCompositeKeyComponents()
|
||||
QVERIFY(writer.writeDatabase(&buffer, db1.data()));
|
||||
|
||||
buffer.seek(0);
|
||||
QScopedPointer<Database> db2;
|
||||
auto db2 = QSharedPointer<Database>::create();
|
||||
KeePass2Reader reader;
|
||||
auto compositeKeyDec1 = QSharedPointer<CompositeKey>::create();
|
||||
|
||||
// try decryption and subsequently add key components until decryption is successful
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKeyDec1));
|
||||
QVERIFY(!reader.readDatabase(&buffer, compositeKeyDec1, db2.data()));
|
||||
QVERIFY(reader.hasError());
|
||||
|
||||
compositeKeyDec1->addKey(passwordKeyEnc);
|
||||
buffer.seek(0);
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKeyDec1));
|
||||
QVERIFY(!reader.readDatabase(&buffer, compositeKeyDec1, db2.data()));
|
||||
QVERIFY(reader.hasError());
|
||||
|
||||
compositeKeyDec1->addKey(fileKeyEnc);
|
||||
buffer.seek(0);
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKeyDec1));
|
||||
QVERIFY(!reader.readDatabase(&buffer, compositeKeyDec1, db2.data()));
|
||||
QVERIFY(reader.hasError());
|
||||
|
||||
compositeKeyDec1->addChallengeResponseKey(challengeResponseKeyEnc);
|
||||
buffer.seek(0);
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKeyDec1));
|
||||
QVERIFY(reader.readDatabase(&buffer, compositeKeyDec1, db2.data()));
|
||||
// now we should be able to open the database
|
||||
if (reader.hasError()) {
|
||||
QFAIL(qPrintable(reader.errorString()));
|
||||
@@ -277,7 +278,7 @@ void TestKeys::testCompositeKeyComponents()
|
||||
compositeKeyDec2->addKey(fileKeyEnc);
|
||||
compositeKeyDec2->addChallengeResponseKey(challengeResponseKeyEnc);
|
||||
buffer.seek(0);
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKeyDec2));
|
||||
QVERIFY(!reader.readDatabase(&buffer, compositeKeyDec2, db2.data()));
|
||||
QVERIFY(reader.hasError());
|
||||
|
||||
auto compositeKeyDec3 = QSharedPointer<CompositeKey>::create();
|
||||
@@ -290,7 +291,7 @@ void TestKeys::testCompositeKeyComponents()
|
||||
compositeKeyDec3->addKey(fileKeyWrong);
|
||||
compositeKeyDec3->addChallengeResponseKey(challengeResponseKeyEnc);
|
||||
buffer.seek(0);
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKeyDec3));
|
||||
QVERIFY(!reader.readDatabase(&buffer, compositeKeyDec3, db2.data()));
|
||||
QVERIFY(reader.hasError());
|
||||
|
||||
auto compositeKeyDec4 = QSharedPointer<CompositeKey>::create();
|
||||
@@ -298,6 +299,6 @@ void TestKeys::testCompositeKeyComponents()
|
||||
compositeKeyDec4->addKey(fileKeyEnc);
|
||||
compositeKeyDec4->addChallengeResponseKey(QSharedPointer<MockChallengeResponseKey>::create(QByteArray(16, 0x20)));
|
||||
buffer.seek(0);
|
||||
db2.reset(reader.readDatabase(&buffer, compositeKeyDec4));
|
||||
QVERIFY(!reader.readDatabase(&buffer, compositeKeyDec4, db2.data()));
|
||||
QVERIFY(reader.hasError());
|
||||
}
|
||||
|
||||
@@ -1363,10 +1363,10 @@ void TestMerge::testMergeNotModified()
|
||||
QScopedPointer<Database> dbSource(
|
||||
createTestDatabaseStructureClone(dbDestination.data(), Entry::CloneNoFlags, Group::CloneIncludeEntries));
|
||||
|
||||
QSignalSpy modifiedSignalSpy(dbDestination.data(), SIGNAL(modified()));
|
||||
QSignalSpy modifiedSignalSpy(dbDestination.data(), SIGNAL(databaseModified()));
|
||||
Merger merger(dbSource.data(), dbDestination.data());
|
||||
merger.merge();
|
||||
QVERIFY(modifiedSignalSpy.empty());
|
||||
QTRY_VERIFY(modifiedSignalSpy.empty());
|
||||
}
|
||||
|
||||
void TestMerge::testMergeModified()
|
||||
@@ -1375,7 +1375,7 @@ void TestMerge::testMergeModified()
|
||||
QScopedPointer<Database> dbSource(
|
||||
createTestDatabaseStructureClone(dbDestination.data(), Entry::CloneNoFlags, Group::CloneIncludeEntries));
|
||||
|
||||
QSignalSpy modifiedSignalSpy(dbDestination.data(), SIGNAL(modified()));
|
||||
QSignalSpy modifiedSignalSpy(dbDestination.data(), SIGNAL(databaseModified()));
|
||||
// Make sure the two changes have a different timestamp.
|
||||
QTest::qSleep(1);
|
||||
Entry* entry = dbSource->rootGroup()->findEntryByPath("entry1");
|
||||
@@ -1385,7 +1385,7 @@ void TestMerge::testMergeModified()
|
||||
|
||||
Merger merger(dbSource.data(), dbDestination.data());
|
||||
merger.merge();
|
||||
QVERIFY(!modifiedSignalSpy.empty());
|
||||
QTRY_VERIFY(!modifiedSignalSpy.empty());
|
||||
}
|
||||
|
||||
Database* TestMerge::createTestDatabase()
|
||||
|
||||
@@ -61,67 +61,83 @@ void TestModified::testSignals()
|
||||
|
||||
QScopedPointer<Database> db(new Database());
|
||||
auto* root = db->rootGroup();
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(databaseModified()));
|
||||
|
||||
db->setKey(compositeKey);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
auto* group1 = new Group();
|
||||
group1->setParent(root);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
auto* group2 = new Group();
|
||||
group2->setParent(root);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
group2->setParent(root, 0);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
auto* entry1 = new Entry();
|
||||
entry1->setGroup(group1);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
QScopedPointer<Database> db2(new Database());
|
||||
auto* root2 = db2->rootGroup();
|
||||
QSignalSpy spyModified2(db2.data(), SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified2(db2.data(), SIGNAL(databaseModified()));
|
||||
|
||||
group1->setParent(root2);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
QCOMPARE(spyModified2.count(), ++spyCount2);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
++spyCount2;
|
||||
QTRY_COMPARE(spyModified2.count(), spyCount2);
|
||||
|
||||
entry1->setTitle("test");
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QCOMPARE(spyModified2.count(), ++spyCount2);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
++spyCount2;
|
||||
QTRY_COMPARE(spyModified2.count(), spyCount2);
|
||||
|
||||
auto* entry2 = new Entry();
|
||||
entry2->setGroup(group2);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
QCOMPARE(spyModified2.count(), spyCount2);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified2.count(), spyCount2);
|
||||
|
||||
entry2->setGroup(root2);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
QCOMPARE(spyModified2.count(), ++spyCount2);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
++spyCount2;
|
||||
QTRY_COMPARE(spyModified2.count(), spyCount2);
|
||||
|
||||
entry2->setTitle("test2");
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QCOMPARE(spyModified2.count(), ++spyCount2);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
++spyCount2;
|
||||
QTRY_COMPARE(spyModified2.count(), spyCount2);
|
||||
|
||||
auto* group3 = new Group();
|
||||
group3->setParent(root);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
auto* group4 = new Group();
|
||||
group4->setParent(group3);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
delete group4;
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
delete entry2;
|
||||
QCOMPARE(spyModified2.count(), ++spyCount2);
|
||||
++spyCount2;
|
||||
QTRY_COMPARE(spyModified2.count(), spyCount2);
|
||||
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QCOMPARE(spyModified2.count(), spyCount2);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified2.count(), spyCount2);
|
||||
}
|
||||
|
||||
void TestModified::testGroupSets()
|
||||
@@ -133,58 +149,68 @@ void TestModified::testGroupSets()
|
||||
auto* group = new Group();
|
||||
group->setParent(root);
|
||||
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(databaseModified()));
|
||||
|
||||
root->setUuid(QUuid::createUuid());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
root->setUuid(root->uuid());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
root->setName("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
root->setName(root->name());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
root->setNotes("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
root->setNotes(root->notes());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
root->setIcon(1);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
root->setIcon(root->iconNumber());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
root->setIcon(QUuid::createUuid());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
root->setIcon(root->iconUuid());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
|
||||
group->setUuid(QUuid::createUuid());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
group->setUuid(group->uuid());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
group->setName("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
group->setName(group->name());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
group->setNotes("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
group->setNotes(group->notes());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
group->setIcon(1);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
group->setIcon(group->iconNumber());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
group->setIcon(QUuid::createUuid());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
group->setIcon(group->iconUuid());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
}
|
||||
|
||||
void TestModified::testEntrySets()
|
||||
@@ -198,106 +224,127 @@ void TestModified::testEntrySets()
|
||||
auto* entry = new Entry();
|
||||
entry->setGroup(group);
|
||||
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(databaseModified()));
|
||||
|
||||
entry->setUuid(QUuid::createUuid());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setUuid(entry->uuid());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setTitle("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setTitle(entry->title());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setUrl("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setUrl(entry->url());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setUsername("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setUsername(entry->username());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setPassword("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setPassword(entry->password());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setNotes("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setNotes(entry->notes());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setIcon(1);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setIcon(entry->iconNumber());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setIcon(QUuid::createUuid());
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setIcon(entry->iconUuid());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setTags("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setTags(entry->tags());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setExpires(true);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setExpires(entry->timeInfo().expires());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setExpiryTime(Clock::currentDateTimeUtc().addYears(1));
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setExpiryTime(entry->timeInfo().expiryTime());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setAutoTypeEnabled(false);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setAutoTypeEnabled(entry->autoTypeEnabled());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setAutoTypeObfuscation(1);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setAutoTypeObfuscation(entry->autoTypeObfuscation());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setDefaultAutoTypeSequence("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setDefaultAutoTypeSequence(entry->defaultAutoTypeSequence());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setForegroundColor(Qt::red);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setForegroundColor(entry->foregroundColor());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setBackgroundColor(Qt::red);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setBackgroundColor(entry->backgroundColor());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->setOverrideUrl("test");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->setOverrideUrl(entry->overrideUrl());
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->attributes()->set("test key", "test value", false);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->attributes()->set("test key", entry->attributes()->value("test key"), false);
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->attributes()->set("test key", entry->attributes()->value("test key"), true);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->attributes()->set("test key", "new test value", true);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->attributes()->set("test key2", "test value2", true);
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->attributes()->set("test key2", entry->attributes()->value("test key2"), true);
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
}
|
||||
|
||||
void TestModified::testHistoryItems()
|
||||
@@ -601,20 +648,23 @@ void TestModified::testCustomData()
|
||||
auto* entry = new Entry();
|
||||
entry->setGroup(group);
|
||||
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(modifiedImmediate()));
|
||||
QSignalSpy spyModified(db.data(), SIGNAL(databaseModified()));
|
||||
|
||||
db->metadata()->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
db->metadata()->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
entry->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
entry->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
|
||||
group->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), ++spyCount);
|
||||
++spyCount;
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
group->customData()->set("Key", "Value");
|
||||
QCOMPARE(spyModified.count(), spyCount);
|
||||
QTRY_COMPARE(spyModified.count(), spyCount);
|
||||
}
|
||||
|
||||
@@ -110,37 +110,36 @@ void TestGui::init()
|
||||
m_dbFilePath = m_dbFile->fileName();
|
||||
m_dbFile->close();
|
||||
|
||||
// make sure window is activated or focus tests may fail
|
||||
m_mainWindow->activateWindow();
|
||||
QApplication::processEvents();
|
||||
|
||||
fileDialog()->setNextFileName(m_dbFilePath);
|
||||
triggerAction("actionDatabaseOpen");
|
||||
|
||||
auto* databaseOpenWidget = m_mainWindow->findChild<QWidget*>("databaseOpenWidget");
|
||||
auto* databaseOpenWidget = m_tabWidget->currentDatabaseWidget()->findChild<QWidget*>("databaseOpenWidget");
|
||||
QVERIFY(databaseOpenWidget);
|
||||
auto* editPassword = databaseOpenWidget->findChild<QLineEdit*>("editPassword");
|
||||
QVERIFY(editPassword);
|
||||
editPassword->setFocus();
|
||||
|
||||
QTest::keyClicks(editPassword, "a");
|
||||
QTest::keyClick(editPassword, Qt::Key_Enter);
|
||||
|
||||
QTRY_VERIFY(m_tabWidget->currentDatabaseWidget());
|
||||
|
||||
m_dbWidget = m_tabWidget->currentDatabaseWidget();
|
||||
m_db = m_dbWidget->database();
|
||||
|
||||
// make sure window is activated or focus tests may fail
|
||||
m_mainWindow->activateWindow();
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
// Every test ends with closing the temp database without saving
|
||||
void TestGui::cleanup()
|
||||
{
|
||||
// DO NOT save the database
|
||||
m_db->markAsClean();
|
||||
MessageBox::setNextAnswer(QMessageBox::No);
|
||||
triggerAction("actionDatabaseClose");
|
||||
QApplication::processEvents();
|
||||
MessageBox::setNextAnswer(QMessageBox::NoButton);
|
||||
|
||||
if (m_db) {
|
||||
delete m_db;
|
||||
}
|
||||
if (m_dbWidget) {
|
||||
delete m_dbWidget;
|
||||
}
|
||||
@@ -301,13 +300,14 @@ void TestGui::createDatabaseCallback()
|
||||
void TestGui::testMergeDatabase()
|
||||
{
|
||||
// It is safe to ignore the warning this line produces
|
||||
QSignalSpy dbMergeSpy(m_dbWidget.data(), SIGNAL(databaseMerged(Database*)));
|
||||
QSignalSpy dbMergeSpy(m_dbWidget.data(), SIGNAL(databaseMerged(QSharedPointer<Database>)));
|
||||
QApplication::processEvents();
|
||||
|
||||
// set file to merge from
|
||||
fileDialog()->setNextFileName(QString(KEEPASSX_TEST_DATA_DIR).append("/MergeDatabase.kdbx"));
|
||||
triggerAction("actionDatabaseMerge");
|
||||
|
||||
auto* databaseOpenMergeWidget = m_mainWindow->findChild<QWidget*>("databaseOpenMergeWidget");
|
||||
auto* databaseOpenMergeWidget = m_tabWidget->currentDatabaseWidget()->findChild<QWidget*>("databaseOpenMergeWidget");
|
||||
auto* editPasswordMerge = databaseOpenMergeWidget->findChild<QLineEdit*>("editPassword");
|
||||
QVERIFY(editPasswordMerge->isVisible());
|
||||
|
||||
@@ -317,7 +317,7 @@ void TestGui::testMergeDatabase()
|
||||
QTest::keyClick(editPasswordMerge, Qt::Key_Enter);
|
||||
|
||||
QTRY_COMPARE(dbMergeSpy.count(), 1);
|
||||
QTRY_VERIFY(m_tabWidget->tabText(m_tabWidget->currentIndex()).contains("*"));
|
||||
QTRY_VERIFY(m_tabWidget->tabName(m_tabWidget->currentIndex()).contains("*"));
|
||||
|
||||
m_db = m_tabWidget->currentDatabaseWidget()->database();
|
||||
|
||||
@@ -352,7 +352,7 @@ void TestGui::testAutoreloadDatabase()
|
||||
|
||||
// the General group contains one entry from the new db data
|
||||
QCOMPARE(m_db->rootGroup()->findChildByName("General")->entries().size(), 1);
|
||||
QVERIFY(!m_tabWidget->tabText(m_tabWidget->currentIndex()).endsWith("*"));
|
||||
QVERIFY(!m_tabWidget->tabName(m_tabWidget->currentIndex()).endsWith("*"));
|
||||
|
||||
// Reset the state
|
||||
cleanup();
|
||||
@@ -370,7 +370,7 @@ void TestGui::testAutoreloadDatabase()
|
||||
|
||||
// Ensure the merge did not take place
|
||||
QCOMPARE(m_db->rootGroup()->findChildByName("General")->entries().size(), 0);
|
||||
QVERIFY(m_tabWidget->tabText(m_tabWidget->currentIndex()).endsWith("*"));
|
||||
QVERIFY(m_tabWidget->tabName(m_tabWidget->currentIndex()).endsWith("*"));
|
||||
|
||||
// Reset the state
|
||||
cleanup();
|
||||
@@ -393,13 +393,13 @@ void TestGui::testAutoreloadDatabase()
|
||||
m_db = m_dbWidget->database();
|
||||
|
||||
QCOMPARE(m_db->rootGroup()->findChildByName("General")->entries().size(), 1);
|
||||
QVERIFY(m_tabWidget->tabText(m_tabWidget->currentIndex()).endsWith("*"));
|
||||
QTRY_VERIFY(m_tabWidget->tabText(m_tabWidget->currentIndex()).endsWith("*"));
|
||||
}
|
||||
|
||||
void TestGui::testTabs()
|
||||
{
|
||||
QCOMPARE(m_tabWidget->count(), 1);
|
||||
QCOMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), m_dbFileName);
|
||||
QCOMPARE(m_tabWidget->tabName(m_tabWidget->currentIndex()), m_dbFileName);
|
||||
}
|
||||
|
||||
void TestGui::testEditEntry()
|
||||
@@ -424,15 +424,16 @@ void TestGui::testEditEntry()
|
||||
|
||||
// Edit the first entry ("Sample Entry")
|
||||
QTest::mouseClick(entryEditWidget, Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
auto* titleEdit = editEntryWidget->findChild<QLineEdit*>("titleEdit");
|
||||
QTest::keyClicks(titleEdit, "_test");
|
||||
|
||||
// Apply the edit
|
||||
auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
|
||||
QVERIFY(editEntryWidgetButtonBox);
|
||||
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
QCOMPARE(entry->title(), QString("Sample Entry_test"));
|
||||
QCOMPARE(entry->historyItems().size(), ++editCount);
|
||||
|
||||
@@ -473,15 +474,16 @@ void TestGui::testEditEntry()
|
||||
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
|
||||
auto* messageWiget = editEntryWidget->findChild<MessageWidget*>("messageWidget");
|
||||
QTRY_VERIFY(messageWiget->isVisible());
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
QCOMPARE(passwordEdit->text(), QString("newpass"));
|
||||
passwordEdit->setText(originalPassword);
|
||||
|
||||
// Save the edit (press OK)
|
||||
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
|
||||
QApplication::processEvents();
|
||||
|
||||
// Confirm edit was made
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
QCOMPARE(entry->title(), QString("Sample Entry_test"));
|
||||
QCOMPARE(entry->foregroundColor(), fgColor);
|
||||
QCOMPARE(entryItem.data(Qt::ForegroundRole), QVariant(fgColor));
|
||||
@@ -490,11 +492,11 @@ void TestGui::testEditEntry()
|
||||
QCOMPARE(entry->historyItems().size(), ++editCount);
|
||||
|
||||
// Confirm modified indicator is showing
|
||||
QTRY_COMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("%1*").arg(m_dbFileName));
|
||||
QTRY_COMPARE(m_tabWidget->tabName(m_tabWidget->currentIndex()), QString("%1*").arg(m_dbFileName));
|
||||
|
||||
// Test copy & paste newline sanitization
|
||||
QTest::mouseClick(entryEditWidget, Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
titleEdit->setText("multiline\ntitle");
|
||||
editEntryWidget->findChild<QLineEdit*>("usernameEdit")->setText("multiline\nusername");
|
||||
editEntryWidget->findChild<QLineEdit*>("passwordEdit")->setText("multiline\npassword");
|
||||
@@ -550,11 +552,11 @@ void TestGui::testSearchEditEntry()
|
||||
auto* searchTextEdit = searchWidget->findChild<QLineEdit*>("searchEdit");
|
||||
QTest::mouseClick(searchTextEdit, Qt::LeftButton);
|
||||
QTest::keyClicks(searchTextEdit, "Doggy");
|
||||
QTRY_VERIFY(m_dbWidget->isInSearchMode());
|
||||
QTRY_VERIFY(m_dbWidget->isSearchActive());
|
||||
|
||||
// Goto "Doggy"'s edit view
|
||||
QTest::keyClick(searchTextEdit, Qt::Key_Return);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
|
||||
// Check the path in header is "parent-group > entry"
|
||||
QCOMPARE(m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget")->findChild<QLabel*>("headerLabel")->text(),
|
||||
@@ -577,7 +579,7 @@ void TestGui::testAddEntry()
|
||||
|
||||
// Click the new entry button and check that we enter edit mode
|
||||
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
|
||||
// Add entry "test" and confirm added
|
||||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
@@ -586,7 +588,7 @@ void TestGui::testAddEntry()
|
||||
auto* editEntryWidgetButtonBox = editEntryWidget->findChild<QDialogButtonBox*>("buttonBox");
|
||||
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
|
||||
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
QModelIndex item = entryView->model()->index(1, 1);
|
||||
Entry* entry = entryView->entryFromIndex(item);
|
||||
|
||||
@@ -629,7 +631,7 @@ void TestGui::testPasswordEntryEntropy()
|
||||
|
||||
// Click the new entry button and check that we enter edit mode
|
||||
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
|
||||
// Add entry "test" and confirm added
|
||||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
@@ -701,7 +703,7 @@ void TestGui::testDicewareEntryEntropy()
|
||||
|
||||
// Click the new entry button and check that we enter edit mode
|
||||
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
|
||||
// Add entry "test" and confirm added
|
||||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
@@ -736,7 +738,7 @@ void TestGui::testTotp()
|
||||
auto* entryView = m_dbWidget->findChild<EntryView*>("entryView");
|
||||
|
||||
QCOMPARE(entryView->model()->rowCount(), 1);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
QModelIndex item = entryView->model()->index(0, 1);
|
||||
Entry* entry = entryView->entryFromIndex(item);
|
||||
clickIndex(item, entryView, Qt::LeftButton);
|
||||
@@ -766,7 +768,7 @@ void TestGui::testTotp()
|
||||
QVERIFY(entryEditWidget->isVisible());
|
||||
QVERIFY(entryEditWidget->isEnabled());
|
||||
QTest::mouseClick(entryEditWidget, Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
|
||||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
editEntryWidget->setCurrentPage(1);
|
||||
@@ -822,7 +824,7 @@ void TestGui::testSearch()
|
||||
QTest::keyClicks(searchTextEdit, "ZZZ");
|
||||
QTRY_COMPARE(searchTextEdit->text(), QString("ZZZ"));
|
||||
QTRY_VERIFY(clearButton->isVisible());
|
||||
QTRY_VERIFY(m_dbWidget->isInSearchMode());
|
||||
QTRY_VERIFY(m_dbWidget->isSearchActive());
|
||||
QTRY_COMPARE(entryView->model()->rowCount(), 0);
|
||||
// Press the search clear button
|
||||
clearButton->trigger();
|
||||
@@ -834,10 +836,10 @@ void TestGui::testSearch()
|
||||
QTest::keyClick(searchTextEdit, Qt::Key_Escape);
|
||||
QTRY_VERIFY(searchTextEdit->text().isEmpty());
|
||||
QTRY_VERIFY(searchTextEdit->hasFocus());
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
// Search for "some"
|
||||
QTest::keyClicks(searchTextEdit, "some");
|
||||
QTRY_VERIFY(m_dbWidget->isInSearchMode());
|
||||
QTRY_VERIFY(m_dbWidget->isSearchActive());
|
||||
QTRY_COMPARE(entryView->model()->rowCount(), 3);
|
||||
// Search for "someTHING"
|
||||
QTest::keyClicks(searchTextEdit, "THING");
|
||||
@@ -894,12 +896,12 @@ void TestGui::testSearch()
|
||||
// Refocus back to search edit
|
||||
QTest::mouseClick(searchTextEdit, Qt::LeftButton);
|
||||
QTRY_VERIFY(searchTextEdit->hasFocus());
|
||||
QVERIFY(m_dbWidget->isInSearchMode());
|
||||
QVERIFY(m_dbWidget->isSearchActive());
|
||||
|
||||
QModelIndex item = entryView->model()->index(0, 1);
|
||||
Entry* entry = entryView->entryFromIndex(item);
|
||||
QTest::keyClick(searchTextEdit, Qt::Key_Return);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
|
||||
// Perform the edit and save it
|
||||
EditEntryWidget* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
@@ -910,12 +912,12 @@ void TestGui::testSearch()
|
||||
QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton);
|
||||
|
||||
// Confirm the edit was made and we are back in search mode
|
||||
QTRY_VERIFY(m_dbWidget->isInSearchMode());
|
||||
QTRY_VERIFY(m_dbWidget->isSearchActive());
|
||||
QCOMPARE(entry->title(), origTitle.append("_edited"));
|
||||
|
||||
// Cancel search, should return to normal view
|
||||
QTest::keyClick(m_mainWindow.data(), Qt::Key_Escape);
|
||||
QTRY_COMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||
QTRY_COMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
}
|
||||
|
||||
void TestGui::testDeleteEntry()
|
||||
@@ -929,7 +931,7 @@ void TestGui::testDeleteEntry()
|
||||
auto* entryDeleteAction = m_mainWindow->findChild<QAction*>("actionEntryDelete");
|
||||
QWidget* entryDeleteWidget = toolBar->widgetForAction(entryDeleteAction);
|
||||
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
clickIndex(entryView->model()->index(1, 1), entryView, Qt::LeftButton);
|
||||
QVERIFY(entryDeleteWidget->isVisible());
|
||||
QVERIFY(entryDeleteWidget->isEnabled());
|
||||
@@ -1022,7 +1024,7 @@ void TestGui::testEntryPlaceholders()
|
||||
|
||||
// Click the new entry button and check that we enter edit mode
|
||||
QTest::mouseClick(entryNewWidget, Qt::LeftButton);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::EditMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::EditMode);
|
||||
|
||||
// Add entry "test" and confirm added
|
||||
auto* editEntryWidget = m_dbWidget->findChild<EditEntryWidget*>("editEntryWidget");
|
||||
@@ -1037,7 +1039,7 @@ void TestGui::testEntryPlaceholders()
|
||||
|
||||
QCOMPARE(entryView->model()->rowCount(), 2);
|
||||
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||
QCOMPARE(m_dbWidget->currentMode(), DatabaseWidget::Mode::ViewMode);
|
||||
QModelIndex item = entryView->model()->index(1, 1);
|
||||
Entry* entry = entryView->entryFromIndex(item);
|
||||
|
||||
@@ -1105,7 +1107,7 @@ void TestGui::testSaveAs()
|
||||
|
||||
triggerAction("actionDatabaseSaveAs");
|
||||
|
||||
QCOMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("testSaveAs"));
|
||||
QCOMPARE(m_tabWidget->tabName(m_tabWidget->currentIndex()), QString("testSaveAs"));
|
||||
|
||||
checkDatabase(tmpFileName);
|
||||
|
||||
@@ -1122,7 +1124,7 @@ void TestGui::testSave()
|
||||
QTRY_COMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("testSave*"));
|
||||
|
||||
triggerAction("actionDatabaseSave");
|
||||
QCOMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("testSave"));
|
||||
QCOMPARE(m_tabWidget->tabName(m_tabWidget->currentIndex()), QString("testSave"));
|
||||
|
||||
checkDatabase();
|
||||
}
|
||||
@@ -1159,15 +1161,15 @@ void TestGui::testKeePass1Import()
|
||||
fileDialog()->setNextFileName(QString(KEEPASSX_TEST_DATA_DIR).append("/basic.kdb"));
|
||||
triggerAction("actionImportKeePass1");
|
||||
|
||||
auto* keepass1OpenWidget = m_mainWindow->findChild<QWidget*>("keepass1OpenWidget");
|
||||
auto* keepass1OpenWidget = m_tabWidget->currentDatabaseWidget()->findChild<QWidget*>("keepass1OpenWidget");
|
||||
auto* editPassword = keepass1OpenWidget->findChild<QLineEdit*>("editPassword");
|
||||
QVERIFY(editPassword);
|
||||
|
||||
QTest::keyClicks(editPassword, "masterpw");
|
||||
QTest::keyClick(editPassword, Qt::Key_Enter);
|
||||
|
||||
QCOMPARE(m_tabWidget->count(), 2);
|
||||
QCOMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("basic [New database]*"));
|
||||
QTRY_COMPARE(m_tabWidget->count(), 2);
|
||||
QTRY_COMPARE(m_tabWidget->tabName(m_tabWidget->currentIndex()), QString("basic [New Database]*"));
|
||||
|
||||
// Close the KeePass1 Database
|
||||
MessageBox::setNextAnswer(QMessageBox::No);
|
||||
@@ -1182,7 +1184,7 @@ void TestGui::testDatabaseLocking()
|
||||
MessageBox::setNextAnswer(QMessageBox::Cancel);
|
||||
triggerAction("actionLockDatabases");
|
||||
|
||||
QCOMPARE(m_tabWidget->tabText(0).remove('&'), origDbName + " [locked]");
|
||||
QCOMPARE(m_tabWidget->tabName(0), origDbName + " [Locked]");
|
||||
|
||||
auto* actionDatabaseMerge = m_mainWindow->findChild<QAction*>("actionDatabaseMerge", Qt::FindChildrenRecursively);
|
||||
QCOMPARE(actionDatabaseMerge->isEnabled(), false);
|
||||
@@ -1197,7 +1199,7 @@ void TestGui::testDatabaseLocking()
|
||||
QTest::keyClicks(editPassword, "a");
|
||||
QTest::keyClick(editPassword, Qt::Key_Enter);
|
||||
|
||||
QCOMPARE(m_tabWidget->tabText(0).remove('&'), origDbName);
|
||||
QCOMPARE(m_tabWidget->tabName(0), origDbName);
|
||||
|
||||
actionDatabaseMerge = m_mainWindow->findChild<QAction*>("actionDatabaseMerge", Qt::FindChildrenRecursively);
|
||||
QCOMPARE(actionDatabaseMerge->isEnabled(), true);
|
||||
@@ -1304,10 +1306,8 @@ void TestGui::checkDatabase(QString dbFileName)
|
||||
|
||||
auto key = QSharedPointer<CompositeKey>::create();
|
||||
key->addKey(QSharedPointer<PasswordKey>::create("a"));
|
||||
KeePass2Reader reader;
|
||||
QScopedPointer<Database> dbSaved(reader.readDatabase(dbFileName, key));
|
||||
QVERIFY(dbSaved);
|
||||
QVERIFY(!reader.hasError());
|
||||
auto dbSaved = QSharedPointer<Database>::create();
|
||||
QVERIFY(dbSaved->open(dbFileName, key, nullptr, false));
|
||||
QCOMPARE(dbSaved->metadata()->name(), m_db->metadata()->name());
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
#include <QSharedPointer>
|
||||
|
||||
class Database;
|
||||
class DatabaseTabWidget;
|
||||
@@ -88,7 +89,7 @@ private:
|
||||
QScopedPointer<MainWindow> m_mainWindow;
|
||||
QPointer<DatabaseTabWidget> m_tabWidget;
|
||||
QPointer<DatabaseWidget> m_dbWidget;
|
||||
QPointer<Database> m_db;
|
||||
QSharedPointer<Database> m_db;
|
||||
QByteArray m_dbData;
|
||||
QScopedPointer<TemporaryFile> m_dbFile;
|
||||
QString m_dbFileName;
|
||||
|
||||
Reference in New Issue
Block a user