diff options
Diffstat (limited to 'tests/TestEntry.cpp')
-rw-r--r-- | tests/TestEntry.cpp | 415 |
1 files changed, 389 insertions, 26 deletions
diff --git a/tests/TestEntry.cpp b/tests/TestEntry.cpp index 84ad03181..94100c0a6 100644 --- a/tests/TestEntry.cpp +++ b/tests/TestEntry.cpp @@ -1,4 +1,5 @@ /* + * 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 @@ -15,12 +16,10 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "TestEntry.h" -#include "config-keepassx-tests.h" - -#include <QTest> +#include <QScopedPointer> -#include "core/Entry.h" +#include "TestEntry.h" +#include "TestGlobal.h" #include "crypto/Crypto.h" QTEST_GUILESS_MAIN(TestEntry) @@ -32,7 +31,7 @@ void TestEntry::initTestCase() void TestEntry::testHistoryItemDeletion() { - Entry* entry = new Entry(); + QScopedPointer<Entry> entry(new Entry()); QPointer<Entry> historyEntry = new Entry(); entry->addHistoryItem(historyEntry); @@ -43,12 +42,11 @@ void TestEntry::testHistoryItemDeletion() entry->removeHistoryItems(historyEntriesToRemove); QCOMPARE(entry->historyItems().size(), 0); QVERIFY(historyEntry.isNull()); - - delete entry; } + void TestEntry::testCopyDataFrom() { - Entry* entry = new Entry(); + QScopedPointer<Entry> entry(new Entry()); entry->setTitle("testtitle"); entry->attributes()->set("attr1", "abc"); @@ -65,9 +63,8 @@ void TestEntry::testCopyDataFrom() assoc.sequence = "4"; entry->autoTypeAssociations()->add(assoc); - Entry* entry2 = new Entry(); - entry2->copyDataFrom(entry); - delete entry; + QScopedPointer<Entry> entry2(new Entry()); + entry2->copyDataFrom(entry.data()); QCOMPARE(entry2->title(), QString("testtitle")); QCOMPARE(entry2->attributes()->value("attr1"), QString("abc")); @@ -80,13 +77,11 @@ void TestEntry::testCopyDataFrom() QCOMPARE(entry2->autoTypeAssociations()->size(), 2); QCOMPARE(entry2->autoTypeAssociations()->get(0).window, QString("1")); QCOMPARE(entry2->autoTypeAssociations()->get(1).window, QString("3")); - - delete entry2; } void TestEntry::testClone() { - Entry* entryOrg = new Entry(); + QScopedPointer<Entry> entryOrg(new Entry()); entryOrg->setUuid(Uuid::random()); entryOrg->setTitle("Original Title"); entryOrg->beginUpdate(); @@ -99,42 +94,58 @@ void TestEntry::testClone() entryOrgTime.setCreationTime(dateTime); entryOrg->setTimeInfo(entryOrgTime); - Entry* entryCloneNone = entryOrg->clone(Entry::CloneNoFlags); + 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()); - delete entryCloneNone; - Entry* entryCloneNewUuid = entryOrg->clone(Entry::CloneNewUuid); + 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()); - delete entryCloneNewUuid; - Entry* entryCloneResetTime = entryOrg->clone(Entry::CloneResetTimeInfo); + 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()); - delete entryCloneResetTime; - Entry* entryCloneHistory = entryOrg->clone(Entry::CloneIncludeHistory); + QScopedPointer<Entry> entryCloneHistory(entryOrg->clone(Entry::CloneIncludeHistory)); QCOMPARE(entryCloneHistory->uuid(), entryOrg->uuid()); QCOMPARE(entryCloneHistory->title(), QString("New Title")); QCOMPARE(entryCloneHistory->historyItems().size(), 1); QCOMPARE(entryCloneHistory->historyItems().at(0)->title(), QString("Original Title")); QCOMPARE(entryCloneHistory->timeInfo().creationTime(), entryOrg->timeInfo().creationTime()); - delete entryCloneHistory; - delete entryOrg; + 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()); } void TestEntry::testResolveUrl() { - Entry* entry = new Entry(); + QScopedPointer<Entry> entry(new Entry()); QString testUrl("www.google.com"); QString testCmd("cmd://firefox " + testUrl); QString testComplexCmd("cmd://firefox --start-now --url 'http://" + testUrl + "' --quit"); @@ -155,6 +166,358 @@ void TestEntry::testResolveUrl() 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(Uuid::random()); + 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(Uuid::random()); + entry2->setTitle("Entry2Title"); + entry2->setUsername("{S:CustomUserNameAttribute}"); + entry2->setPassword(QString("{REF:P@I:%1}").arg(entry1->uuid().toHex())); + 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(Uuid::random()); + entry3->setTitle(QString("{REF:T@I:%1}").arg(entry2->uuid().toHex())); + entry3->setUsername(QString("{REF:U@I:%1}").arg(entry2->uuid().toHex())); + entry3->setPassword(QString("{REF:P@I:%1}").arg(entry2->uuid().toHex())); + entry3->setUrl(QString("{REF:A@I:%1}").arg(entry2->uuid().toHex())); + + 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(Uuid::random()); + entry4->setTitle(QString("{REF:T@I:%1}").arg(entry3->uuid().toHex())); + entry4->setUsername(QString("{REF:U@I:%1}").arg(entry3->uuid().toHex())); + entry4->setPassword(QString("{REF:P@I:%1}").arg(entry3->uuid().toHex())); + entry4->setUrl(QString("{REF:A@I:%1}").arg(entry3->uuid().toHex())); + + 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(Uuid::random()); + 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(Uuid::random()); + entry6->setTitle(QString("{REF:T@I:%1}").arg(entry3->uuid().toHex())); + 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}")); +} + +void TestEntry::testResolveReferencePlaceholders() +{ + Database db; + auto* root = db.rootGroup(); + + auto* entry1 = new Entry(); + entry1->setGroup(root); + entry1->setUuid(Uuid::random()); + 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(Uuid::random()); + 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(Uuid::random()); + 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(Uuid::random()); + + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@I:%1}").arg(entry1->uuid().toHex())), 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->uuid().toHex())), 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->uuid().toHex())), 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->uuid().toHex())), entry3->attributes()->value("AttributeTitle")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:U@I:%1}").arg(entry3->uuid().toHex())), entry3->attributes()->value("AttributeUsername")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:P@I:%1}").arg(entry3->uuid().toHex())), entry3->attributes()->value("AttributePassword")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:A@I:%1}").arg(entry3->uuid().toHex())), entry3->attributes()->value("AttributeUrl")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:N@I:%1}").arg(entry3->uuid().toHex())), entry3->attributes()->value("AttributeNotes")); + + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:T@I:%1}").arg(entry3->uuid().toHex().toUpper())), entry3->attributes()->value("AttributeTitle")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:U@I:%1}").arg(entry3->uuid().toHex().toUpper())), entry3->attributes()->value("AttributeUsername")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:P@I:%1}").arg(entry3->uuid().toHex().toUpper())), entry3->attributes()->value("AttributePassword")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:A@I:%1}").arg(entry3->uuid().toHex().toUpper())), entry3->attributes()->value("AttributeUrl")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:N@I:%1}").arg(entry3->uuid().toHex().toUpper())), entry3->attributes()->value("AttributeNotes")); + + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:t@i:%1}").arg(entry3->uuid().toHex().toLower())), entry3->attributes()->value("AttributeTitle")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:u@i:%1}").arg(entry3->uuid().toHex().toLower())), entry3->attributes()->value("AttributeUsername")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:p@i:%1}").arg(entry3->uuid().toHex().toLower())), entry3->attributes()->value("AttributePassword")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:a@i:%1}").arg(entry3->uuid().toHex().toLower())), entry3->attributes()->value("AttributeUrl")); + QCOMPARE(tstEntry->resolveMultiplePlaceholders(QString("{REF:n@i:%1}").arg(entry3->uuid().toHex().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(Uuid::random()); + + auto* referencedEntryUsername = new Entry(); + referencedEntryUsername->setGroup(root); + referencedEntryUsername->setUsername("myUser"); + referencedEntryUsername->setUuid(Uuid::random()); + + auto* referencedEntryPassword = new Entry(); + referencedEntryPassword->setGroup(root); + referencedEntryPassword->setPassword("myPassword"); + referencedEntryPassword->setUuid(Uuid::random()); + + auto* referencedEntryUrl = new Entry(); + referencedEntryUrl->setGroup(root); + referencedEntryUrl->setUrl("myUrl"); + referencedEntryUrl->setUuid(Uuid::random()); + + auto* referencedEntryNotes = new Entry(); + referencedEntryNotes->setGroup(root); + referencedEntryNotes->setNotes("myNotes"); + referencedEntryNotes->setUuid(Uuid::random()); + + 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, QString(referencedEntry->uuid().toHex())); + } +} + +void TestEntry::testResolveClonedEntry() +{ + Database db; + auto* root = db.rootGroup(); + + auto* original = new Entry(); + original->setGroup(root); + original->setUuid(Uuid::random()); + 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()); - delete entry; + 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()); } |