123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- /*
- * Copyright (C) 2014 Florian Geyer <blueice@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 "TestEntrySearcher.h"
- #include "core/Group.h"
- #include "core/Tools.h"
- #include <QTest>
- QTEST_GUILESS_MAIN(TestEntrySearcher)
- void TestEntrySearcher::init()
- {
- m_rootGroup = new Group();
- m_entrySearcher = EntrySearcher();
- }
- void TestEntrySearcher::cleanup()
- {
- delete m_rootGroup;
- }
- void TestEntrySearcher::testSearch()
- {
- /**
- * Root
- * - group1 (search disabled)
- * - group11
- * - group2
- * - group21
- * - group211
- * - group2111
- */
- auto group1 = new Group();
- auto group2 = new Group();
- auto group3 = new Group();
- group1->setParent(m_rootGroup);
- group2->setParent(m_rootGroup);
- group3->setParent(m_rootGroup);
- auto group11 = new Group();
- group11->setParent(group1);
- auto group21 = new Group();
- auto group211 = new Group();
- auto group2111 = new Group();
- group21->setParent(group2);
- group211->setParent(group21);
- group2111->setParent(group211);
- group1->setSearchingEnabled(Group::Disable);
- auto eRoot = new Entry();
- eRoot->setTitle("test search term test");
- eRoot->setGroup(m_rootGroup);
- auto eRoot2 = new Entry();
- eRoot2->setNotes("test term test");
- eRoot2->setGroup(m_rootGroup);
- // Searching is disabled for these
- auto e1 = new Entry();
- e1->setUsername("test search term test");
- e1->setGroup(group1);
- auto e11 = new Entry();
- e11->setNotes("test search term test");
- e11->setGroup(group11);
- // End searching disabled
- auto e2111 = new Entry();
- e2111->setTitle("test search term test");
- e2111->setGroup(group2111);
- auto e2111b = new Entry();
- e2111b->setNotes("test search test");
- e2111b->setUsername("user123");
- e2111b->setPassword("testpass");
- e2111b->setGroup(group2111);
- auto e3 = new Entry();
- e3->setUrl("test search term test");
- e3->setGroup(group3);
- auto e3b = new Entry();
- e3b->setTitle("test search test 123");
- e3b->setUsername("test@email.com");
- e3b->setPassword("realpass");
- e3b->setGroup(group3);
- // Simple search term testing
- m_searchResult = m_entrySearcher.search("search", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 5);
- m_searchResult = m_entrySearcher.search("search term", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 3);
- m_searchResult = m_entrySearcher.search("123", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 2);
- m_searchResult = m_entrySearcher.search("search term", group211);
- QCOMPARE(m_searchResult.count(), 1);
- // Test advanced search terms
- m_searchResult = m_entrySearcher.search("title:123", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("t:123", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("password:testpass", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("pw:testpass", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("!user:email.com", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 5);
- m_searchResult = m_entrySearcher.search("!u:email.com", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 5);
- m_searchResult = m_entrySearcher.search("*user:\".*@.*\\.com\"", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("+user:email", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 0);
- // Terms are logical AND together
- m_searchResult = m_entrySearcher.search("password:pass user:user", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- // Parent group has search disabled
- m_searchResult = m_entrySearcher.search("search term", group11);
- QCOMPARE(m_searchResult.count(), 0);
- }
- void TestEntrySearcher::testAndConcatenationInSearch()
- {
- auto entry = new Entry();
- entry->setNotes("abc def ghi");
- entry->setTitle("jkl");
- entry->setGroup(m_rootGroup);
- m_searchResult = m_entrySearcher.search("", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("def", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search(" abc ghi ", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("ghi ef", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("abc ef xyz", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 0);
- m_searchResult = m_entrySearcher.search("abc kl", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- }
- void TestEntrySearcher::testAllAttributesAreSearched()
- {
- auto entry = new Entry();
- entry->setGroup(m_rootGroup);
- entry->setTitle("testTitle");
- entry->setUsername("testUsername");
- entry->setUrl("testUrl");
- entry->setNotes("testNote");
- // Default is to AND all terms together
- m_searchResult = m_entrySearcher.search("testTitle testUsername testUrl testNote", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- }
- void TestEntrySearcher::testSearchTermParser()
- {
- // Test standard search terms
- m_entrySearcher.parseSearchTerms("-test \"quoted \\\"string\\\"\" user:user pass:\"test me\" noquote ");
- auto terms = m_entrySearcher.m_searchTerms;
- QCOMPARE(terms.length(), 5);
- QCOMPARE(terms[0].field, EntrySearcher::Field::Undefined);
- QCOMPARE(terms[0].word, QString("test"));
- QCOMPARE(terms[0].exclude, true);
- QCOMPARE(terms[1].field, EntrySearcher::Field::Undefined);
- QCOMPARE(terms[1].word, QString("quoted \"string\""));
- QCOMPARE(terms[1].exclude, false);
- QCOMPARE(terms[2].field, EntrySearcher::Field::Username);
- QCOMPARE(terms[2].word, QString("user"));
- QCOMPARE(terms[3].field, EntrySearcher::Field::Password);
- QCOMPARE(terms[3].word, QString("test me"));
- QCOMPARE(terms[4].field, EntrySearcher::Field::Undefined);
- QCOMPARE(terms[4].word, QString("noquote"));
- // Test wildcard and regex search terms
- m_entrySearcher.parseSearchTerms("+url:*.google.com *user:\\d+\\w{2}");
- terms = m_entrySearcher.m_searchTerms;
- QCOMPARE(terms.length(), 2);
- QCOMPARE(terms[0].field, EntrySearcher::Field::Url);
- QCOMPARE(terms[0].regex.pattern(), QString("^(?:.*\\.google\\.com)$"));
- QCOMPARE(terms[1].field, EntrySearcher::Field::Username);
- QCOMPARE(terms[1].regex.pattern(), QString("\\d+\\w{2}"));
- // Test custom attribute search terms
- m_entrySearcher.parseSearchTerms("+_abc:efg _def:\"ddd\"");
- terms = m_entrySearcher.m_searchTerms;
- QCOMPARE(terms.length(), 2);
- QCOMPARE(terms[0].field, EntrySearcher::Field::AttributeValue);
- QCOMPARE(terms[0].word, QString("abc"));
- QCOMPARE(terms[0].regex.pattern(), QString("^(?:efg)$"));
- QCOMPARE(terms[1].field, EntrySearcher::Field::AttributeValue);
- QCOMPARE(terms[1].word, QString("def"));
- QCOMPARE(terms[1].regex.pattern(), QString("ddd"));
- }
- void TestEntrySearcher::testCustomAttributesAreSearched()
- {
- QScopedPointer<Entry> e1(new Entry());
- e1->setGroup(m_rootGroup);
- e1->attributes()->set("testAttribute", "testE1");
- e1->attributes()->set("testProtected", "testP", true);
- QScopedPointer<Entry> e2(new Entry());
- e2->setGroup(m_rootGroup);
- e2->attributes()->set("testAttribute", "testE2");
- e2->attributes()->set("testProtected", "testP2", true);
- // search for custom entries
- m_searchResult = m_entrySearcher.search("_testAttribute:test", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 2);
- // protected attributes are ignored
- m_entrySearcher = EntrySearcher(false, true);
- m_searchResult = m_entrySearcher.search("_testAttribute:test _testProtected:testP2", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 2);
- }
- void TestEntrySearcher::testGroup()
- {
- /**
- * Root
- * - group1 (1 entry)
- * - subgroup1 (2 entries)
- * - group2
- * - subgroup2 (1 entry)
- */
- auto group1 = new Group();
- auto group2 = new Group();
- group1->setParent(m_rootGroup);
- group1->setName("group1");
- group2->setParent(m_rootGroup);
- group2->setName("group2");
- auto subgroup1 = new Group();
- subgroup1->setName("subgroup1");
- subgroup1->setParent(group1);
- auto subgroup2 = new Group();
- subgroup2->setName("subgroup2");
- subgroup2->setParent(group2);
- auto eGroup1 = new Entry();
- eGroup1->setTitle("Entry Group 1");
- eGroup1->setGroup(group1);
- auto eSub1 = new Entry();
- eSub1->setTitle("test search term test");
- eSub1->setGroup(subgroup1);
- auto eSub2 = new Entry();
- eSub2->setNotes("test test");
- eSub2->setGroup(subgroup1);
- auto eSub3 = new Entry();
- eSub3->setNotes("test term test");
- eSub3->setGroup(subgroup2);
- m_searchResult = m_entrySearcher.search("group:subgroup", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 3);
- m_searchResult = m_entrySearcher.search("g:subgroup1", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 2);
- m_searchResult = m_entrySearcher.search("g:subgroup1 search", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- m_searchResult = m_entrySearcher.search("g:*1/sub*1", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 2);
- m_searchResult = m_entrySearcher.search("g:/group1 search", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- }
- void TestEntrySearcher::testSkipProtected()
- {
- QScopedPointer<Entry> e1(new Entry());
- e1->setGroup(m_rootGroup);
- e1->attributes()->set("testAttribute", "testE1");
- e1->attributes()->set("testProtected", "apple", true);
- QScopedPointer<Entry> e2(new Entry());
- e2->setGroup(m_rootGroup);
- e2->attributes()->set("testAttribute", "testE2");
- e2->attributes()->set("testProtected", "banana", true);
- const QList<Entry*> expectE1{e1.data()};
- const QList<Entry*> expectE2{e2.data()};
- const QList<Entry*> expectBoth{e1.data(), e2.data()};
- // when not skipping protected, empty term matches everything
- m_searchResult = m_entrySearcher.search("", m_rootGroup);
- QCOMPARE(m_searchResult, expectBoth);
- // now test the searcher with skipProtected = true
- m_entrySearcher = EntrySearcher(false, true);
- // when skipping protected, empty term matches nothing
- m_searchResult = m_entrySearcher.search("", m_rootGroup);
- QCOMPARE(m_searchResult, {});
- // having a protected entry in terms should not affect the results in anyways
- m_searchResult = m_entrySearcher.search("_testProtected:apple", m_rootGroup);
- QCOMPARE(m_searchResult, {});
- m_searchResult = m_entrySearcher.search("_testProtected:apple _testAttribute:testE2", m_rootGroup);
- QCOMPARE(m_searchResult, expectE2);
- m_searchResult = m_entrySearcher.search("_testProtected:apple _testAttribute:testE1", m_rootGroup);
- QCOMPARE(m_searchResult, expectE1);
- m_searchResult =
- m_entrySearcher.search("_testProtected:apple _testAttribute:testE1 _testAttribute:testE2", m_rootGroup);
- QCOMPARE(m_searchResult, {});
- // also move the protected term around to exercise the short-circuit logic
- m_searchResult = m_entrySearcher.search("_testAttribute:testE2 _testProtected:apple", m_rootGroup);
- QCOMPARE(m_searchResult, expectE2);
- m_searchResult = m_entrySearcher.search("_testAttribute:testE1 _testProtected:apple", m_rootGroup);
- QCOMPARE(m_searchResult, expectE1);
- m_searchResult =
- m_entrySearcher.search("_testAttribute:testE1 _testProtected:apple _testAttribute:testE2", m_rootGroup);
- QCOMPARE(m_searchResult, {});
- }
- void TestEntrySearcher::testUUIDSearch()
- {
- auto entry1 = new Entry();
- entry1->setGroup(m_rootGroup);
- entry1->setTitle("testTitle");
- auto uuid1 = QUuid::createUuid();
- entry1->setUuid(uuid1);
- auto entry2 = new Entry();
- entry2->setGroup(m_rootGroup);
- entry2->setTitle("testTitle2");
- auto uuid2 = QUuid::createUuid();
- entry2->setUuid(uuid2);
- m_searchResult = m_entrySearcher.search("uuid:", m_rootGroup);
- QCOMPARE(m_searchResult.count(), 2);
- m_searchResult = m_entrySearcher.search("uuid:" + Tools::uuidToHex(uuid1), m_rootGroup);
- QCOMPARE(m_searchResult.count(), 1);
- }
|