123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- /*
- * Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
- * Copyright (C) 2013 Felix Geyer <debfx@fobos.de>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 or (at your option)
- * version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <QScopedPointer>
- #include "TestEntry.h"
- #include "TestGlobal.h"
- #include "core/Clock.h"
- #include "core/Metadata.h"
- #include "crypto/Crypto.h"
- QTEST_GUILESS_MAIN(TestEntry)
- void TestEntry::initTestCase()
- {
- QVERIFY(Crypto::init());
- }
- void TestEntry::testHistoryItemDeletion()
- {
- QScopedPointer<Entry> entry(new Entry());
- QPointer<Entry> historyEntry = new Entry();
- entry->addHistoryItem(historyEntry);
- QCOMPARE(entry->historyItems().size(), 1);
- QList<Entry*> historyEntriesToRemove;
- historyEntriesToRemove.append(historyEntry);
- entry->removeHistoryItems(historyEntriesToRemove);
- QCOMPARE(entry->historyItems().size(), 0);
- QVERIFY(historyEntry.isNull());
- }
- void TestEntry::testCopyDataFrom()
- {
- QScopedPointer<Entry> entry(new Entry());
- entry->setTitle("testtitle");
- entry->attributes()->set("attr1", "abc");
- entry->attributes()->set("attr2", "def");
- entry->attachments()->set("test", "123");
- entry->attachments()->set("test2", "456");
- AutoTypeAssociations::Association assoc;
- assoc.window = "1";
- assoc.sequence = "2";
- entry->autoTypeAssociations()->add(assoc);
- assoc.window = "3";
- assoc.sequence = "4";
- entry->autoTypeAssociations()->add(assoc);
- QScopedPointer<Entry> entry2(new Entry());
- entry2->copyDataFrom(entry.data());
- QCOMPARE(entry2->title(), QString("testtitle"));
- QCOMPARE(entry2->attributes()->value("attr1"), QString("abc"));
- QCOMPARE(entry2->attributes()->value("attr2"), QString("def"));
- QCOMPARE(entry2->attachments()->keys().size(), 2);
- QCOMPARE(entry2->attachments()->value("test"), QByteArray("123"));
- QCOMPARE(entry2->attachments()->value("test2"), QByteArray("456"));
- QCOMPARE(entry2->autoTypeAssociations()->size(), 2);
- QCOMPARE(entry2->autoTypeAssociations()->get(0).window, QString("1"));
- QCOMPARE(entry2->autoTypeAssociations()->get(1).window, QString("3"));
- }
- void TestEntry::testClone()
- {
- QScopedPointer<Entry> entryOrg(new Entry());
- entryOrg->setUuid(QUuid::createUuid());
- entryOrg->setTitle("Original Title");
- entryOrg->beginUpdate();
- entryOrg->setTitle("New Title");
- entryOrg->endUpdate();
- TimeInfo entryOrgTime = entryOrg->timeInfo();
- QDateTime dateTime = Clock::datetimeUtc(60);
- entryOrgTime.setCreationTime(dateTime);
- entryOrg->setTimeInfo(entryOrgTime);
- QScopedPointer<Entry> entryCloneNone(entryOrg->clone(Entry::CloneNoFlags));
- QCOMPARE(entryCloneNone->uuid(), entryOrg->uuid());
- QCOMPARE(entryCloneNone->title(), QString("New Title"));
- QCOMPARE(entryCloneNone->historyItems().size(), 0);
- QCOMPARE(entryCloneNone->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
- QScopedPointer<Entry> entryCloneNewUuid(entryOrg->clone(Entry::CloneNewUuid));
- QVERIFY(entryCloneNewUuid->uuid() != entryOrg->uuid());
- QVERIFY(!entryCloneNewUuid->uuid().isNull());
- QCOMPARE(entryCloneNewUuid->title(), QString("New Title"));
- QCOMPARE(entryCloneNewUuid->historyItems().size(), 0);
- QCOMPARE(entryCloneNewUuid->timeInfo().creationTime(), entryOrg->timeInfo().creationTime());
- // Reset modification time
- entryOrgTime.setLastModificationTime(Clock::datetimeUtc(60));
- entryOrg->setTimeInfo(entryOrgTime);
- QScopedPointer<Entry> entryCloneRename(entryOrg->clone(Entry::CloneRenameTitle));
- QCOMPARE(entryCloneRename->uuid(), entryOrg->uuid());
- QCOMPARE(entryCloneRename->title(), QString("New Title - Clone"));
- // Cloning should not modify time info unless explicity requested
- QCOMPARE(entryCloneRename->timeInfo(), entryOrg->timeInfo());
- QScopedPointer<Entry> entryCloneResetTime(entryOrg->clone(Entry::CloneResetTimeInfo));
- QCOMPARE(entryCloneResetTime->uuid(), entryOrg->uuid());
- QCOMPARE(entryCloneResetTime->title(), QString("New Title"));
- QCOMPARE(entryCloneResetTime->historyItems().size(), 0);
- QVERIFY(entryCloneResetTime->timeInfo().creationTime() != entryOrg->timeInfo().creationTime());
- // Date back history of original entry
- Entry* firstHistoryItem = entryOrg->historyItems()[0];
- TimeInfo entryOrgHistoryTimeInfo = firstHistoryItem->timeInfo();
- QDateTime datedBackEntryOrgModificationTime = entryOrgHistoryTimeInfo.lastModificationTime().addMSecs(-10);
- entryOrgHistoryTimeInfo.setLastModificationTime(datedBackEntryOrgModificationTime);
- entryOrgHistoryTimeInfo.setCreationTime(datedBackEntryOrgModificationTime);
- firstHistoryItem->setTimeInfo(entryOrgHistoryTimeInfo);
- QScopedPointer<Entry> entryCloneHistory(entryOrg->clone(Entry::CloneIncludeHistory | Entry::CloneResetTimeInfo));
- QCOMPARE(entryCloneHistory->uuid(), entryOrg->uuid());
- QCOMPARE(entryCloneHistory->title(), QString("New Title"));
- QCOMPARE(entryCloneHistory->historyItems().size(), entryOrg->historyItems().size());
- QCOMPARE(entryCloneHistory->historyItems().at(0)->title(), QString("Original Title"));
- QVERIFY(entryCloneHistory->timeInfo().creationTime() != entryOrg->timeInfo().creationTime());
- // Timeinfo of history items should not be modified
- QList<Entry*> entryOrgHistory = entryOrg->historyItems(), clonedHistory = entryCloneHistory->historyItems();
- auto entryOrgHistoryItem = entryOrgHistory.constBegin();
- for (auto entryCloneHistoryItem = clonedHistory.constBegin(); entryCloneHistoryItem != clonedHistory.constEnd();
- ++entryCloneHistoryItem, ++entryOrgHistoryItem) {
- QCOMPARE((*entryOrgHistoryItem)->timeInfo(), (*entryCloneHistoryItem)->timeInfo());
- }
- Database db;
- auto* entryOrgClone = entryOrg->clone(Entry::CloneNoFlags);
- entryOrgClone->setGroup(db.rootGroup());
- Entry* entryCloneUserRef = entryOrgClone->clone(Entry::CloneUserAsRef);
- entryCloneUserRef->setGroup(db.rootGroup());
- QCOMPARE(entryCloneUserRef->uuid(), entryOrgClone->uuid());
- QCOMPARE(entryCloneUserRef->title(), QString("New Title"));
- QCOMPARE(entryCloneUserRef->historyItems().size(), 0);
- QCOMPARE(entryCloneUserRef->timeInfo().creationTime(), entryOrgClone->timeInfo().creationTime());
- QVERIFY(entryCloneUserRef->attributes()->isReference(EntryAttributes::UserNameKey));
- QCOMPARE(entryCloneUserRef->resolvePlaceholder(entryCloneUserRef->username()), entryOrgClone->username());
- Entry* entryClonePassRef = entryOrgClone->clone(Entry::ClonePassAsRef);
- entryClonePassRef->setGroup(db.rootGroup());
- QCOMPARE(entryClonePassRef->uuid(), entryOrgClone->uuid());
- QCOMPARE(entryClonePassRef->title(), QString("New Title"));
- QCOMPARE(entryClonePassRef->historyItems().size(), 0);
- QCOMPARE(entryClonePassRef->timeInfo().creationTime(), entryOrgClone->timeInfo().creationTime());
- QVERIFY(entryClonePassRef->attributes()->isReference(EntryAttributes::PasswordKey));
- QCOMPARE(entryClonePassRef->resolvePlaceholder(entryCloneUserRef->password()), entryOrg->password());
- QCOMPARE(entryClonePassRef->attributes()->referenceUuid(EntryAttributes::PasswordKey), entryOrgClone->uuid());
- }
- void TestEntry::testResolveUrl()
- {
- QScopedPointer<Entry> entry(new Entry());
- QString testUrl("www.google.com");
- QString testCmd("cmd://firefox " + testUrl);
- QString testFileUnix("/home/example/test.txt");
- QString testFileWindows("c:/WINDOWS/test.txt");
- QString testComplexCmd("cmd://firefox --start-now --url 'http://" + testUrl + "' --quit");
- QString nonHttpUrl("ftp://google.com");
- QString noUrl("random text inserted here");
- // Test standard URL's
- QCOMPARE(entry->resolveUrl(""), QString(""));
- QCOMPARE(entry->resolveUrl(testUrl), "https://" + testUrl);
- QCOMPARE(entry->resolveUrl("http://" + testUrl), "http://" + testUrl);
- // Test file:// URL's
- QCOMPARE(entry->resolveUrl("file://" + testFileUnix), "file://" + testFileUnix);
- QCOMPARE(entry->resolveUrl(testFileUnix), "file://" + testFileUnix);
- QCOMPARE(entry->resolveUrl("file:///" + testFileWindows), "file:///" + testFileWindows);
- QCOMPARE(entry->resolveUrl(testFileWindows), "file:///" + testFileWindows);
- // Test cmd:// with no URL
- QCOMPARE(entry->resolveUrl("cmd://firefox"), QString(""));
- QCOMPARE(entry->resolveUrl("cmd://firefox --no-url"), QString(""));
- // Test cmd:// with URL's
- QCOMPARE(entry->resolveUrl(testCmd), "https://" + testUrl);
- QCOMPARE(entry->resolveUrl(testComplexCmd), "http://" + testUrl);
- // Test non-http URL
- QCOMPARE(entry->resolveUrl(nonHttpUrl), QString(""));
- // Test no URL
- QCOMPARE(entry->resolveUrl(noUrl), QString(""));
- }
- void TestEntry::testResolveUrlPlaceholders()
- {
- Entry entry;
- entry.setUrl("https://user:pw@keepassxc.org:80/path/example.php?q=e&s=t+2#fragment");
- QString rmvscm("//user:pw@keepassxc.org:80/path/example.php?q=e&s=t+2#fragment"); // Entry URL without scheme name.
- QString scm("https"); // Scheme name of the entry URL.
- QString host("keepassxc.org"); // Host component of the entry URL.
- QString port("80"); // Port number of the entry URL.
- QString path("/path/example.php"); // Path component of the entry URL.
- QString query("q=e&s=t+2"); // Query information of the entry URL.
- QString userinfo("user:pw"); // User information of the entry URL.
- QString username("user"); // User name of the entry URL.
- QString password("pw"); // Password of the entry URL.
- QString fragment("fragment"); // Fragment of the entry URL.
- QCOMPARE(entry.resolvePlaceholder("{URL:RMVSCM}"), rmvscm);
- QCOMPARE(entry.resolvePlaceholder("{URL:WITHOUTSCHEME}"), rmvscm);
- QCOMPARE(entry.resolvePlaceholder("{URL:SCM}"), scm);
- QCOMPARE(entry.resolvePlaceholder("{URL:SCHEME}"), scm);
- QCOMPARE(entry.resolvePlaceholder("{URL:HOST}"), host);
- QCOMPARE(entry.resolvePlaceholder("{URL:PORT}"), port);
- QCOMPARE(entry.resolvePlaceholder("{URL:PATH}"), path);
- QCOMPARE(entry.resolvePlaceholder("{URL:QUERY}"), query);
- QCOMPARE(entry.resolvePlaceholder("{URL:USERINFO}"), userinfo);
- QCOMPARE(entry.resolvePlaceholder("{URL:USERNAME}"), username);
- QCOMPARE(entry.resolvePlaceholder("{URL:PASSWORD}"), password);
- QCOMPARE(entry.resolvePlaceholder("{URL:FRAGMENT}"), fragment);
- }
- void TestEntry::testResolveRecursivePlaceholders()
- {
- Database db;
- auto* root = db.rootGroup();
- auto* entry1 = new Entry();
- entry1->setGroup(root);
- entry1->setUuid(QUuid::createUuid());
- entry1->setTitle("{USERNAME}");
- entry1->setUsername("{PASSWORD}");
- entry1->setPassword("{URL}");
- entry1->setUrl("{S:CustomTitle}");
- entry1->attributes()->set("CustomTitle", "RecursiveValue");
- QCOMPARE(entry1->resolveMultiplePlaceholders(entry1->title()), QString("RecursiveValue"));
- auto* entry2 = new Entry();
- entry2->setGroup(root);
- entry2->setUuid(QUuid::createUuid());
- entry2->setTitle("Entry2Title");
- entry2->setUsername("{S:CustomUserNameAttribute}");
- entry2->setPassword(QString("{REF:P@I:%1}").arg(entry1->uuidToHex()));
- entry2->setUrl("http://{S:IpAddress}:{S:Port}/{S:Uri}");
- entry2->attributes()->set("CustomUserNameAttribute", "CustomUserNameValue");
- entry2->attributes()->set("IpAddress", "127.0.0.1");
- entry2->attributes()->set("Port", "1234");
- entry2->attributes()->set("Uri", "uri/path");
- auto* entry3 = new Entry();
- entry3->setGroup(root);
- entry3->setUuid(QUuid::createUuid());
- entry3->setTitle(QString("{REF:T@I:%1}").arg(entry2->uuidToHex()));
- entry3->setUsername(QString("{REF:U@I:%1}").arg(entry2->uuidToHex()));
- entry3->setPassword(QString("{REF:P@I:%1}").arg(entry2->uuidToHex()));
- entry3->setUrl(QString("{REF:A@I:%1}").arg(entry2->uuidToHex()));
- QCOMPARE(entry3->resolveMultiplePlaceholders(entry3->title()), QString("Entry2Title"));
- QCOMPARE(entry3->resolveMultiplePlaceholders(entry3->username()), QString("CustomUserNameValue"));
- QCOMPARE(entry3->resolveMultiplePlaceholders(entry3->password()), QString("RecursiveValue"));
- QCOMPARE(entry3->resolveMultiplePlaceholders(entry3->url()), QString("http://127.0.0.1:1234/uri/path"));
- auto* entry4 = new Entry();
- entry4->setGroup(root);
- entry4->setUuid(QUuid::createUuid());
- entry4->setTitle(QString("{REF:T@I:%1}").arg(entry3->uuidToHex()));
- entry4->setUsername(QString("{REF:U@I:%1}").arg(entry3->uuidToHex()));
- entry4->setPassword(QString("{REF:P@I:%1}").arg(entry3->uuidToHex()));
- entry4->setUrl(QString("{REF:A@I:%1}").arg(entry3->uuidToHex()));
- QCOMPARE(entry4->resolveMultiplePlaceholders(entry4->title()), QString("Entry2Title"));
- QCOMPARE(entry4->resolveMultiplePlaceholders(entry4->username()), QString("CustomUserNameValue"));
- QCOMPARE(entry4->resolveMultiplePlaceholders(entry4->password()), QString("RecursiveValue"));
- QCOMPARE(entry4->resolveMultiplePlaceholders(entry4->url()), QString("http://127.0.0.1:1234/uri/path"));
- auto* entry5 = new Entry();
- entry5->setGroup(root);
- entry5->setUuid(QUuid::createUuid());
- entry5->attributes()->set("Scheme", "http");
- entry5->attributes()->set("Host", "host.org");
- entry5->attributes()->set("Port", "2017");
- entry5->attributes()->set("Path", "/some/path");
- entry5->attributes()->set("UserName", "username");
- entry5->attributes()->set("Password", "password");
- entry5->attributes()->set("Query", "q=e&t=s");
- entry5->attributes()->set("Fragment", "fragment");
- entry5->setUrl("{S:Scheme}://{S:UserName}:{S:Password}@{S:Host}:{S:Port}{S:Path}?{S:Query}#{S:Fragment}");
- entry5->setTitle("title+{URL:Path}+{URL:Fragment}+title");
- const QString url("http://username:password@host.org:2017/some/path?q=e&t=s#fragment");
- QCOMPARE(entry5->resolveMultiplePlaceholders(entry5->url()), url);
- QCOMPARE(entry5->resolveMultiplePlaceholders(entry5->title()), QString("title+/some/path+fragment+title"));
- auto* entry6 = new Entry();
- entry6->setGroup(root);
- entry6->setUuid(QUuid::createUuid());
- entry6->setTitle(QString("{REF:T@I:%1}").arg(entry3->uuidToHex()));
- entry6->setUsername(QString("{TITLE}"));
- entry6->setPassword(QString("{PASSWORD}"));
- QCOMPARE(entry6->resolvePlaceholder(entry6->title()), QString("Entry2Title"));
- QCOMPARE(entry6->resolvePlaceholder(entry6->username()), QString("Entry2Title"));
- QCOMPARE(entry6->resolvePlaceholder(entry6->password()), QString("{PASSWORD}"));
- auto* entry7 = new Entry();
- entry7->setGroup(root);
- entry7->setUuid(QUuid::createUuid());
- entry7->setTitle(QString("{REF:T@I:%1} and something else").arg(entry3->uuidToHex()));
- entry7->setUsername(QString("{TITLE}"));
- entry7->setPassword(QString("PASSWORD"));
- QCOMPARE(entry7->resolvePlaceholder(entry7->title()), QString("Entry2Title and something else"));
- QCOMPARE(entry7->resolvePlaceholder(entry7->username()), QString("Entry2Title and something else"));
- QCOMPARE(entry7->resolvePlaceholder(entry7->password()), QString("PASSWORD"));
- }
- void TestEntry::testResolveReferencePlaceholders()
- {
- Database db;
- auto* root = db.rootGroup();
- auto* entry1 = new Entry();
- entry1->setGroup(root);
- entry1->setUuid(QUuid::createUuid());
- entry1->setTitle("Title1");
- entry1->setUsername("Username1");
- entry1->setPassword("Password1");
- entry1->setUrl("Url1");
- entry1->setNotes("Notes1");
- entry1->attributes()->set("CustomAttribute1", "CustomAttributeValue1");
- auto* group = new Group();
- group->setParent(root);
- auto* entry2 = new Entry();
- entry2->setGroup(group);
- entry2->setUuid(QUuid::createUuid());
- entry2->setTitle("Title2");
- entry2->setUsername("Username2");
- entry2->setPassword("Password2");
- entry2->setUrl("Url2");
- entry2->setNotes("Notes2");
- entry2->attributes()->set("CustomAttribute2", "CustomAttributeValue2");
- auto* entry3 = new Entry();
- entry3->setGroup(group);
- entry3->setUuid(QUuid::createUuid());
- entry3->setTitle("{S:AttributeTitle}");
- entry3->setUsername("{S:AttributeUsername}");
- entry3->setPassword("{S:AttributePassword}");
- entry3->setUrl("{S:AttributeUrl}");
- entry3->setNotes("{S:AttributeNotes}");
- entry3->attributes()->set("AttributeTitle", "TitleValue");
- entry3->attributes()->set("AttributeUsername", "UsernameValue");
- entry3->attributes()->set("AttributePassword", "PasswordValue");
- entry3->attributes()->set("AttributeUrl", "UrlValue");
- entry3->attributes()->set("AttributeNotes", "NotesValue");
- auto* tstEntry = new Entry();
- tstEntry->setGroup(root);
- tstEntry->setUuid(QUuid::createUuid());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@I:%1}").arg(entry1->uuidToHex())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@T:%1}").arg(entry1->title())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@U:%1}").arg(entry1->username())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@P:%1}").arg(entry1->password())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@A:%1}").arg(entry1->url())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@N:%1}").arg(entry1->notes())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(
- QString("{REF:T@O:%1}").arg(entry1->attributes()->value("CustomAttribute1"))),
- entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@I:%1}").arg(entry1->uuidToHex())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@T:%1}").arg(entry1->title())), entry1->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:U@U:%1}").arg(entry1->username())),
- entry1->username());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:P@P:%1}").arg(entry1->password())),
- entry1->password());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:A@A:%1}").arg(entry1->url())), entry1->url());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:N@N:%1}").arg(entry1->notes())), entry1->notes());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@I:%1}").arg(entry2->uuidToHex())), entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@T:%1}").arg(entry2->title())), entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@U:%1}").arg(entry2->username())), entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@P:%1}").arg(entry2->password())), entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@A:%1}").arg(entry2->url())), entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@N:%1}").arg(entry2->notes())), entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(
- QString("{REF:T@O:%1}").arg(entry2->attributes()->value("CustomAttribute2"))),
- entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@T:%1}").arg(entry2->title())), entry2->title());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:U@U:%1}").arg(entry2->username())),
- entry2->username());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:P@P:%1}").arg(entry2->password())),
- entry2->password());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:A@A:%1}").arg(entry2->url())), entry2->url());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:N@N:%1}").arg(entry2->notes())), entry2->notes());
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@I:%1}").arg(entry3->uuidToHex())),
- entry3->attributes()->value("AttributeTitle"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:U@I:%1}").arg(entry3->uuidToHex())),
- entry3->attributes()->value("AttributeUsername"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:P@I:%1}").arg(entry3->uuidToHex())),
- entry3->attributes()->value("AttributePassword"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:A@I:%1}").arg(entry3->uuidToHex())),
- entry3->attributes()->value("AttributeUrl"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:N@I:%1}").arg(entry3->uuidToHex())),
- entry3->attributes()->value("AttributeNotes"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@I:%1}").arg(entry3->uuidToHex().toUpper())),
- entry3->attributes()->value("AttributeTitle"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:U@I:%1}").arg(entry3->uuidToHex().toUpper())),
- entry3->attributes()->value("AttributeUsername"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:P@I:%1}").arg(entry3->uuidToHex().toUpper())),
- entry3->attributes()->value("AttributePassword"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:A@I:%1}").arg(entry3->uuidToHex().toUpper())),
- entry3->attributes()->value("AttributeUrl"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:N@I:%1}").arg(entry3->uuidToHex().toUpper())),
- entry3->attributes()->value("AttributeNotes"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:t@i:%1}").arg(entry3->uuidToHex().toLower())),
- entry3->attributes()->value("AttributeTitle"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:u@i:%1}").arg(entry3->uuidToHex().toLower())),
- entry3->attributes()->value("AttributeUsername"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:p@i:%1}").arg(entry3->uuidToHex().toLower())),
- entry3->attributes()->value("AttributePassword"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:a@i:%1}").arg(entry3->uuidToHex().toLower())),
- entry3->attributes()->value("AttributeUrl"));
- QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:n@i:%1}").arg(entry3->uuidToHex().toLower())),
- entry3->attributes()->value("AttributeNotes"));
- }
- void TestEntry::testResolveNonIdPlaceholdersToUuid()
- {
- Database db;
- auto* root = db.rootGroup();
- auto* referencedEntryTitle = new Entry();
- referencedEntryTitle->setGroup(root);
- referencedEntryTitle->setTitle("myTitle");
- referencedEntryTitle->setUuid(QUuid::createUuid());
- auto* referencedEntryUsername = new Entry();
- referencedEntryUsername->setGroup(root);
- referencedEntryUsername->setUsername("myUser");
- referencedEntryUsername->setUuid(QUuid::createUuid());
- auto* referencedEntryPassword = new Entry();
- referencedEntryPassword->setGroup(root);
- referencedEntryPassword->setPassword("myPassword");
- referencedEntryPassword->setUuid(QUuid::createUuid());
- auto* referencedEntryUrl = new Entry();
- referencedEntryUrl->setGroup(root);
- referencedEntryUrl->setUrl("myUrl");
- referencedEntryUrl->setUuid(QUuid::createUuid());
- auto* referencedEntryNotes = new Entry();
- referencedEntryNotes->setGroup(root);
- referencedEntryNotes->setNotes("myNotes");
- referencedEntryNotes->setUuid(QUuid::createUuid());
- const QList<QChar> placeholders{'T', 'U', 'P', 'A', 'N'};
- for (const QChar& searchIn : placeholders) {
- const Entry* referencedEntry = nullptr;
- QString newEntryNotesRaw("{REF:I@%1:%2}");
- switch (searchIn.toLatin1()) {
- case 'T':
- referencedEntry = referencedEntryTitle;
- newEntryNotesRaw = newEntryNotesRaw.arg(searchIn, referencedEntry->title());
- break;
- case 'U':
- referencedEntry = referencedEntryUsername;
- newEntryNotesRaw = newEntryNotesRaw.arg(searchIn, referencedEntry->username());
- break;
- case 'P':
- referencedEntry = referencedEntryPassword;
- newEntryNotesRaw = newEntryNotesRaw.arg(searchIn, referencedEntry->password());
- break;
- case 'A':
- referencedEntry = referencedEntryUrl;
- newEntryNotesRaw = newEntryNotesRaw.arg(searchIn, referencedEntry->url());
- break;
- case 'N':
- referencedEntry = referencedEntryNotes;
- newEntryNotesRaw = newEntryNotesRaw.arg(searchIn, referencedEntry->notes());
- break;
- default:
- break;
- }
- auto* newEntry = new Entry();
- newEntry->setGroup(root);
- newEntry->setNotes(newEntryNotesRaw);
- const QString newEntryNotesResolved = newEntry->resolveMultiplePlaceholders(newEntry->notes());
- QCOMPARE(newEntryNotesResolved, referencedEntry->uuidToHex());
- }
- }
- void TestEntry::testResolveClonedEntry()
- {
- Database db;
- auto* root = db.rootGroup();
- auto* original = new Entry();
- original->setGroup(root);
- original->setUuid(QUuid::createUuid());
- original->setTitle("Title");
- original->setUsername("SomeUsername");
- original->setPassword("SomePassword");
- QCOMPARE(original->resolveMultiplePlaceholders(original->username()), original->username());
- QCOMPARE(original->resolveMultiplePlaceholders(original->password()), original->password());
- // Top-level clones.
- Entry* clone1 = original->clone(Entry::CloneNewUuid);
- clone1->setGroup(root);
- Entry* clone2 = original->clone(Entry::CloneUserAsRef | Entry::CloneNewUuid);
- clone2->setGroup(root);
- Entry* clone3 = original->clone(Entry::ClonePassAsRef | Entry::CloneNewUuid);
- clone3->setGroup(root);
- Entry* clone4 = original->clone(Entry::CloneUserAsRef | Entry::ClonePassAsRef | Entry::CloneNewUuid);
- clone4->setGroup(root);
- QCOMPARE(clone1->resolveMultiplePlaceholders(clone1->username()), original->username());
- QCOMPARE(clone1->resolveMultiplePlaceholders(clone1->password()), original->password());
- QCOMPARE(clone2->resolveMultiplePlaceholders(clone2->username()), original->username());
- QCOMPARE(clone2->resolveMultiplePlaceholders(clone2->password()), original->password());
- QCOMPARE(clone3->resolveMultiplePlaceholders(clone3->username()), original->username());
- QCOMPARE(clone3->resolveMultiplePlaceholders(clone3->password()), original->password());
- QCOMPARE(clone4->resolveMultiplePlaceholders(clone4->username()), original->username());
- QCOMPARE(clone4->resolveMultiplePlaceholders(clone4->password()), original->password());
- // Second-level clones.
- Entry* cclone1 = clone4->clone(Entry::CloneNewUuid);
- cclone1->setGroup(root);
- Entry* cclone2 = clone4->clone(Entry::CloneUserAsRef | Entry::CloneNewUuid);
- cclone2->setGroup(root);
- Entry* cclone3 = clone4->clone(Entry::ClonePassAsRef | Entry::CloneNewUuid);
- cclone3->setGroup(root);
- Entry* cclone4 = clone4->clone(Entry::CloneUserAsRef | Entry::ClonePassAsRef | Entry::CloneNewUuid);
- cclone4->setGroup(root);
- QCOMPARE(cclone1->resolveMultiplePlaceholders(cclone1->username()), original->username());
- QCOMPARE(cclone1->resolveMultiplePlaceholders(cclone1->password()), original->password());
- QCOMPARE(cclone2->resolveMultiplePlaceholders(cclone2->username()), original->username());
- QCOMPARE(cclone2->resolveMultiplePlaceholders(cclone2->password()), original->password());
- QCOMPARE(cclone3->resolveMultiplePlaceholders(cclone3->username()), original->username());
- QCOMPARE(cclone3->resolveMultiplePlaceholders(cclone3->password()), original->password());
- QCOMPARE(cclone4->resolveMultiplePlaceholders(cclone4->username()), original->username());
- QCOMPARE(cclone4->resolveMultiplePlaceholders(cclone4->password()), original->password());
- // Change the original's attributes and make sure that the changes are tracked.
- QString oldUsername = original->username();
- QString oldPassword = original->password();
- original->setUsername("DifferentUsername");
- original->setPassword("DifferentPassword");
- QCOMPARE(clone1->resolveMultiplePlaceholders(clone1->username()), oldUsername);
- QCOMPARE(clone1->resolveMultiplePlaceholders(clone1->password()), oldPassword);
- QCOMPARE(clone2->resolveMultiplePlaceholders(clone2->username()), original->username());
- QCOMPARE(clone2->resolveMultiplePlaceholders(clone2->password()), oldPassword);
- QCOMPARE(clone3->resolveMultiplePlaceholders(clone3->username()), oldUsername);
- QCOMPARE(clone3->resolveMultiplePlaceholders(clone3->password()), original->password());
- QCOMPARE(clone4->resolveMultiplePlaceholders(clone4->username()), original->username());
- QCOMPARE(clone4->resolveMultiplePlaceholders(clone4->password()), original->password());
- QCOMPARE(cclone1->resolveMultiplePlaceholders(cclone1->username()), original->username());
- QCOMPARE(cclone1->resolveMultiplePlaceholders(cclone1->password()), original->password());
- QCOMPARE(cclone2->resolveMultiplePlaceholders(cclone2->username()), original->username());
- QCOMPARE(cclone2->resolveMultiplePlaceholders(cclone2->password()), original->password());
- QCOMPARE(cclone3->resolveMultiplePlaceholders(cclone3->username()), original->username());
- QCOMPARE(cclone3->resolveMultiplePlaceholders(cclone3->password()), original->password());
- QCOMPARE(cclone4->resolveMultiplePlaceholders(cclone4->username()), original->username());
- QCOMPARE(cclone4->resolveMultiplePlaceholders(cclone4->password()), original->password());
- }
- void TestEntry::testIsRecycled()
- {
- Entry* entry = new Entry();
- QVERIFY(!entry->isRecycled());
- Database db;
- Group* root = db.rootGroup();
- QVERIFY(root);
- entry->setGroup(root);
- QVERIFY(!entry->isRecycled());
- QVERIFY(db.metadata()->recycleBinEnabled());
- db.recycleEntry(entry);
- QVERIFY(entry->isRecycled());
- Group* group1 = new Group();
- group1->setParent(root);
- Entry* entry1 = new Entry();
- entry1->setGroup(group1);
- QVERIFY(!entry1->isRecycled());
- db.recycleGroup(group1);
- QVERIFY(entry1->isRecycled());
- }
- void TestEntry::testMove()
- {
- Database db;
- Group* root = db.rootGroup();
- QVERIFY(root);
- Entry* entry0 = new Entry();
- QVERIFY(entry0);
- entry0->setGroup(root);
- Entry* entry1 = new Entry();
- QVERIFY(entry1);
- entry1->setGroup(root);
- Entry* entry2 = new Entry();
- QVERIFY(entry2);
- entry2->setGroup(root);
- Entry* entry3 = new Entry();
- QVERIFY(entry3);
- entry3->setGroup(root);
- // default order, straight
- QCOMPARE(root->entries().at(0), entry0);
- QCOMPARE(root->entries().at(1), entry1);
- QCOMPARE(root->entries().at(2), entry2);
- QCOMPARE(root->entries().at(3), entry3);
- entry0->moveDown();
- QCOMPARE(root->entries().at(0), entry1);
- QCOMPARE(root->entries().at(1), entry0);
- QCOMPARE(root->entries().at(2), entry2);
- QCOMPARE(root->entries().at(3), entry3);
- entry0->moveDown();
- QCOMPARE(root->entries().at(0), entry1);
- QCOMPARE(root->entries().at(1), entry2);
- QCOMPARE(root->entries().at(2), entry0);
- QCOMPARE(root->entries().at(3), entry3);
- entry0->moveDown();
- QCOMPARE(root->entries().at(0), entry1);
- QCOMPARE(root->entries().at(1), entry2);
- QCOMPARE(root->entries().at(2), entry3);
- QCOMPARE(root->entries().at(3), entry0);
- // no effect
- entry0->moveDown();
- QCOMPARE(root->entries().at(0), entry1);
- QCOMPARE(root->entries().at(1), entry2);
- QCOMPARE(root->entries().at(2), entry3);
- QCOMPARE(root->entries().at(3), entry0);
- entry0->moveUp();
- QCOMPARE(root->entries().at(0), entry1);
- QCOMPARE(root->entries().at(1), entry2);
- QCOMPARE(root->entries().at(2), entry0);
- QCOMPARE(root->entries().at(3), entry3);
- entry0->moveUp();
- QCOMPARE(root->entries().at(0), entry1);
- QCOMPARE(root->entries().at(1), entry0);
- QCOMPARE(root->entries().at(2), entry2);
- QCOMPARE(root->entries().at(3), entry3);
- entry0->moveUp();
- QCOMPARE(root->entries().at(0), entry0);
- QCOMPARE(root->entries().at(1), entry1);
- QCOMPARE(root->entries().at(2), entry2);
- QCOMPARE(root->entries().at(3), entry3);
- // no effect
- entry0->moveUp();
- QCOMPARE(root->entries().at(0), entry0);
- QCOMPARE(root->entries().at(1), entry1);
- QCOMPARE(root->entries().at(2), entry2);
- QCOMPARE(root->entries().at(3), entry3);
- entry2->moveUp();
- QCOMPARE(root->entries().at(0), entry0);
- QCOMPARE(root->entries().at(1), entry2);
- QCOMPARE(root->entries().at(2), entry1);
- QCOMPARE(root->entries().at(3), entry3);
- entry0->moveDown();
- QCOMPARE(root->entries().at(0), entry2);
- QCOMPARE(root->entries().at(1), entry0);
- QCOMPARE(root->entries().at(2), entry1);
- QCOMPARE(root->entries().at(3), entry3);
- entry3->moveUp();
- QCOMPARE(root->entries().at(0), entry2);
- QCOMPARE(root->entries().at(1), entry0);
- QCOMPARE(root->entries().at(2), entry3);
- QCOMPARE(root->entries().at(3), entry1);
- entry3->moveUp();
- QCOMPARE(root->entries().at(0), entry2);
- QCOMPARE(root->entries().at(1), entry3);
- QCOMPARE(root->entries().at(2), entry0);
- QCOMPARE(root->entries().at(3), entry1);
- entry2->moveDown();
- QCOMPARE(root->entries().at(0), entry3);
- QCOMPARE(root->entries().at(1), entry2);
- QCOMPARE(root->entries().at(2), entry0);
- QCOMPARE(root->entries().at(3), entry1);
- entry1->moveUp();
- QCOMPARE(root->entries().at(0), entry3);
- QCOMPARE(root->entries().at(1), entry2);
- QCOMPARE(root->entries().at(2), entry1);
- QCOMPARE(root->entries().at(3), entry0);
- }
|