keepassxc

Форк
0
/
TestEntrySearcher.cpp 
396 строк · 12.7 Кб
1
/*
2
 *  Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
3
 *
4
 *  This program is free software: you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation, either version 2 or (at your option)
7
 *  version 3 of the License.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 */
17

18
#include "TestEntrySearcher.h"
19
#include "core/Group.h"
20
#include "core/Tools.h"
21

22
#include <QTest>
23

24
QTEST_GUILESS_MAIN(TestEntrySearcher)
25

26
void TestEntrySearcher::init()
27
{
28
    m_rootGroup = new Group();
29
    m_entrySearcher = EntrySearcher();
30
}
31

32
void TestEntrySearcher::cleanup()
33
{
34
    delete m_rootGroup;
35
}
36

37
void TestEntrySearcher::testSearch()
38
{
39
    /**
40
     * Root
41
     * - group1 (search disabled)
42
     *   - group11
43
     * - group2
44
     *   - group21
45
     *     - group211
46
     *       - group2111
47
     */
48
    auto group1 = new Group();
49
    auto group2 = new Group();
50
    auto group3 = new Group();
51

52
    group1->setParent(m_rootGroup);
53
    group2->setParent(m_rootGroup);
54
    group3->setParent(m_rootGroup);
55

56
    auto group11 = new Group();
57

58
    group11->setParent(group1);
59

60
    auto group21 = new Group();
61
    auto group211 = new Group();
62
    auto group2111 = new Group();
63

64
    group21->setParent(group2);
65
    group211->setParent(group21);
66
    group2111->setParent(group211);
67

68
    group1->setSearchingEnabled(Group::Disable);
69

70
    auto eRoot = new Entry();
71
    eRoot->setTitle("test search term test");
72
    eRoot->setGroup(m_rootGroup);
73

74
    auto eRoot2 = new Entry();
75
    eRoot2->setNotes("test term test");
76
    eRoot2->setGroup(m_rootGroup);
77

78
    // Searching is disabled for these
79
    auto e1 = new Entry();
80
    e1->setUsername("test search term test");
81
    e1->setGroup(group1);
82

83
    auto e11 = new Entry();
84
    e11->setNotes("test search term test");
85
    e11->setGroup(group11);
86
    // End searching disabled
87

88
    auto e2111 = new Entry();
89
    e2111->setTitle("test search term test");
90
    e2111->setGroup(group2111);
91

92
    auto e2111b = new Entry();
93
    e2111b->setNotes("test search test");
94
    e2111b->setUsername("user123");
95
    e2111b->setPassword("testpass");
96
    e2111b->setGroup(group2111);
97

98
    auto e3 = new Entry();
99
    e3->setUrl("test search term test");
100
    e3->setGroup(group3);
101

102
    auto e3b = new Entry();
103
    e3b->setTitle("test search test 123");
104
    e3b->setUsername("test@email.com");
105
    e3b->setPassword("realpass");
106
    e3b->setGroup(group3);
107

108
    // Simple search term testing
109
    m_searchResult = m_entrySearcher.search("search", m_rootGroup);
110
    QCOMPARE(m_searchResult.count(), 5);
111

112
    m_searchResult = m_entrySearcher.search("search term", m_rootGroup);
113
    QCOMPARE(m_searchResult.count(), 3);
114

115
    m_searchResult = m_entrySearcher.search("123", m_rootGroup);
116
    QCOMPARE(m_searchResult.count(), 2);
117

118
    m_searchResult = m_entrySearcher.search("search term", group211);
119
    QCOMPARE(m_searchResult.count(), 1);
120

121
    // Test advanced search terms
122
    m_searchResult = m_entrySearcher.search("title:123", m_rootGroup);
123
    QCOMPARE(m_searchResult.count(), 1);
124

125
    m_searchResult = m_entrySearcher.search("t:123", m_rootGroup);
126
    QCOMPARE(m_searchResult.count(), 1);
127

128
    m_searchResult = m_entrySearcher.search("password:testpass", m_rootGroup);
129
    QCOMPARE(m_searchResult.count(), 1);
130

131
    m_searchResult = m_entrySearcher.search("pw:testpass", m_rootGroup);
132
    QCOMPARE(m_searchResult.count(), 1);
133

134
    m_searchResult = m_entrySearcher.search("!user:email.com", m_rootGroup);
135
    QCOMPARE(m_searchResult.count(), 5);
136

137
    m_searchResult = m_entrySearcher.search("!u:email.com", m_rootGroup);
138
    QCOMPARE(m_searchResult.count(), 5);
139

140
    m_searchResult = m_entrySearcher.search("*user:\".*@.*\\.com\"", m_rootGroup);
141
    QCOMPARE(m_searchResult.count(), 1);
142

143
    m_searchResult = m_entrySearcher.search("+user:email", m_rootGroup);
144
    QCOMPARE(m_searchResult.count(), 0);
145

146
    // Terms are logical AND together
147
    m_searchResult = m_entrySearcher.search("password:pass user:user", m_rootGroup);
148
    QCOMPARE(m_searchResult.count(), 1);
149

150
    // Parent group has search disabled
151
    m_searchResult = m_entrySearcher.search("search term", group11);
152
    QCOMPARE(m_searchResult.count(), 0);
153
}
154

155
void TestEntrySearcher::testAndConcatenationInSearch()
156
{
157
    auto entry = new Entry();
158
    entry->setNotes("abc def ghi");
159
    entry->setTitle("jkl");
160
    entry->setGroup(m_rootGroup);
161

162
    m_searchResult = m_entrySearcher.search("", m_rootGroup);
163
    QCOMPARE(m_searchResult.count(), 1);
164

165
    m_searchResult = m_entrySearcher.search("def", m_rootGroup);
166
    QCOMPARE(m_searchResult.count(), 1);
167

168
    m_searchResult = m_entrySearcher.search("  abc    ghi  ", m_rootGroup);
169
    QCOMPARE(m_searchResult.count(), 1);
170

171
    m_searchResult = m_entrySearcher.search("ghi ef", m_rootGroup);
172
    QCOMPARE(m_searchResult.count(), 1);
173

174
    m_searchResult = m_entrySearcher.search("abc ef xyz", m_rootGroup);
175
    QCOMPARE(m_searchResult.count(), 0);
176

177
    m_searchResult = m_entrySearcher.search("abc kl", m_rootGroup);
178
    QCOMPARE(m_searchResult.count(), 1);
179
}
180

181
void TestEntrySearcher::testAllAttributesAreSearched()
182
{
183
    auto entry = new Entry();
184
    entry->setGroup(m_rootGroup);
185

186
    entry->setTitle("testTitle");
187
    entry->setUsername("testUsername");
188
    entry->setUrl("testUrl");
189
    entry->setNotes("testNote");
190

191
    // Default is to AND all terms together
192
    m_searchResult = m_entrySearcher.search("testTitle testUsername testUrl testNote", m_rootGroup);
193
    QCOMPARE(m_searchResult.count(), 1);
194
}
195

196
void TestEntrySearcher::testSearchTermParser()
197
{
198
    // Test standard search terms
199
    m_entrySearcher.parseSearchTerms("-test \"quoted \\\"string\\\"\"  user:user pass:\"test me\" noquote  ");
200
    auto terms = m_entrySearcher.m_searchTerms;
201

202
    QCOMPARE(terms.length(), 5);
203

204
    QCOMPARE(terms[0].field, EntrySearcher::Field::Undefined);
205
    QCOMPARE(terms[0].word, QString("test"));
206
    QCOMPARE(terms[0].exclude, true);
207

208
    QCOMPARE(terms[1].field, EntrySearcher::Field::Undefined);
209
    QCOMPARE(terms[1].word, QString("quoted \"string\""));
210
    QCOMPARE(terms[1].exclude, false);
211

212
    QCOMPARE(terms[2].field, EntrySearcher::Field::Username);
213
    QCOMPARE(terms[2].word, QString("user"));
214

215
    QCOMPARE(terms[3].field, EntrySearcher::Field::Password);
216
    QCOMPARE(terms[3].word, QString("test me"));
217

218
    QCOMPARE(terms[4].field, EntrySearcher::Field::Undefined);
219
    QCOMPARE(terms[4].word, QString("noquote"));
220

221
    // Test wildcard and regex search terms
222
    m_entrySearcher.parseSearchTerms("+url:*.google.com *user:\\d+\\w{2}");
223
    terms = m_entrySearcher.m_searchTerms;
224

225
    QCOMPARE(terms.length(), 2);
226

227
    QCOMPARE(terms[0].field, EntrySearcher::Field::Url);
228
    QCOMPARE(terms[0].regex.pattern(), QString("^(?:.*\\.google\\.com)$"));
229

230
    QCOMPARE(terms[1].field, EntrySearcher::Field::Username);
231
    QCOMPARE(terms[1].regex.pattern(), QString("\\d+\\w{2}"));
232

233
    // Test custom attribute search terms
234
    m_entrySearcher.parseSearchTerms("+_abc:efg _def:\"ddd\"");
235
    terms = m_entrySearcher.m_searchTerms;
236

237
    QCOMPARE(terms.length(), 2);
238

239
    QCOMPARE(terms[0].field, EntrySearcher::Field::AttributeValue);
240
    QCOMPARE(terms[0].word, QString("abc"));
241
    QCOMPARE(terms[0].regex.pattern(), QString("^(?:efg)$"));
242

243
    QCOMPARE(terms[1].field, EntrySearcher::Field::AttributeValue);
244
    QCOMPARE(terms[1].word, QString("def"));
245
    QCOMPARE(terms[1].regex.pattern(), QString("ddd"));
246
}
247

248
void TestEntrySearcher::testCustomAttributesAreSearched()
249
{
250
    QScopedPointer<Entry> e1(new Entry());
251
    e1->setGroup(m_rootGroup);
252

253
    e1->attributes()->set("testAttribute", "testE1");
254
    e1->attributes()->set("testProtected", "testP", true);
255

256
    QScopedPointer<Entry> e2(new Entry());
257
    e2->setGroup(m_rootGroup);
258
    e2->attributes()->set("testAttribute", "testE2");
259
    e2->attributes()->set("testProtected", "testP2", true);
260

261
    // search for custom entries
262
    m_searchResult = m_entrySearcher.search("_testAttribute:test", m_rootGroup);
263
    QCOMPARE(m_searchResult.count(), 2);
264

265
    // protected attributes are ignored
266
    m_entrySearcher = EntrySearcher(false, true);
267
    m_searchResult = m_entrySearcher.search("_testAttribute:test _testProtected:testP2", m_rootGroup);
268
    QCOMPARE(m_searchResult.count(), 2);
269
}
270

271
void TestEntrySearcher::testGroup()
272
{
273
    /**
274
     * Root
275
     * - group1 (1 entry)
276
     *   - subgroup1 (2 entries)
277
     * - group2
278
     *   - subgroup2 (1 entry)
279
     */
280
    auto group1 = new Group();
281
    auto group2 = new Group();
282

283
    group1->setParent(m_rootGroup);
284
    group1->setName("group1");
285
    group2->setParent(m_rootGroup);
286
    group2->setName("group2");
287

288
    auto subgroup1 = new Group();
289
    subgroup1->setName("subgroup1");
290
    subgroup1->setParent(group1);
291

292
    auto subgroup2 = new Group();
293
    subgroup2->setName("subgroup2");
294
    subgroup2->setParent(group2);
295

296
    auto eGroup1 = new Entry();
297
    eGroup1->setTitle("Entry Group 1");
298
    eGroup1->setGroup(group1);
299

300
    auto eSub1 = new Entry();
301
    eSub1->setTitle("test search term test");
302
    eSub1->setGroup(subgroup1);
303

304
    auto eSub2 = new Entry();
305
    eSub2->setNotes("test test");
306
    eSub2->setGroup(subgroup1);
307

308
    auto eSub3 = new Entry();
309
    eSub3->setNotes("test term test");
310
    eSub3->setGroup(subgroup2);
311

312
    m_searchResult = m_entrySearcher.search("group:subgroup", m_rootGroup);
313
    QCOMPARE(m_searchResult.count(), 3);
314

315
    m_searchResult = m_entrySearcher.search("g:subgroup1", m_rootGroup);
316
    QCOMPARE(m_searchResult.count(), 2);
317

318
    m_searchResult = m_entrySearcher.search("g:subgroup1 search", m_rootGroup);
319
    QCOMPARE(m_searchResult.count(), 1);
320

321
    m_searchResult = m_entrySearcher.search("g:*1/sub*1", m_rootGroup);
322
    QCOMPARE(m_searchResult.count(), 2);
323

324
    m_searchResult = m_entrySearcher.search("g:/group1 search", m_rootGroup);
325
    QCOMPARE(m_searchResult.count(), 1);
326
}
327

328
void TestEntrySearcher::testSkipProtected()
329
{
330
    QScopedPointer<Entry> e1(new Entry());
331
    e1->setGroup(m_rootGroup);
332

333
    e1->attributes()->set("testAttribute", "testE1");
334
    e1->attributes()->set("testProtected", "apple", true);
335

336
    QScopedPointer<Entry> e2(new Entry());
337
    e2->setGroup(m_rootGroup);
338
    e2->attributes()->set("testAttribute", "testE2");
339
    e2->attributes()->set("testProtected", "banana", true);
340

341
    const QList<Entry*> expectE1{e1.data()};
342
    const QList<Entry*> expectE2{e2.data()};
343
    const QList<Entry*> expectBoth{e1.data(), e2.data()};
344

345
    // when not skipping protected, empty term matches everything
346
    m_searchResult = m_entrySearcher.search("", m_rootGroup);
347
    QCOMPARE(m_searchResult, expectBoth);
348

349
    // now test the searcher with skipProtected = true
350
    m_entrySearcher = EntrySearcher(false, true);
351

352
    // when skipping protected, empty term matches nothing
353
    m_searchResult = m_entrySearcher.search("", m_rootGroup);
354
    QCOMPARE(m_searchResult, {});
355

356
    // having a protected entry in terms should not affect the results in anyways
357
    m_searchResult = m_entrySearcher.search("_testProtected:apple", m_rootGroup);
358
    QCOMPARE(m_searchResult, {});
359
    m_searchResult = m_entrySearcher.search("_testProtected:apple _testAttribute:testE2", m_rootGroup);
360
    QCOMPARE(m_searchResult, expectE2);
361
    m_searchResult = m_entrySearcher.search("_testProtected:apple _testAttribute:testE1", m_rootGroup);
362
    QCOMPARE(m_searchResult, expectE1);
363
    m_searchResult =
364
        m_entrySearcher.search("_testProtected:apple _testAttribute:testE1 _testAttribute:testE2", m_rootGroup);
365
    QCOMPARE(m_searchResult, {});
366

367
    // also move the protected term around to exercise the short-circuit logic
368
    m_searchResult = m_entrySearcher.search("_testAttribute:testE2 _testProtected:apple", m_rootGroup);
369
    QCOMPARE(m_searchResult, expectE2);
370
    m_searchResult = m_entrySearcher.search("_testAttribute:testE1 _testProtected:apple", m_rootGroup);
371
    QCOMPARE(m_searchResult, expectE1);
372
    m_searchResult =
373
        m_entrySearcher.search("_testAttribute:testE1 _testProtected:apple _testAttribute:testE2", m_rootGroup);
374
    QCOMPARE(m_searchResult, {});
375
}
376

377
void TestEntrySearcher::testUUIDSearch()
378
{
379
    auto entry1 = new Entry();
380
    entry1->setGroup(m_rootGroup);
381
    entry1->setTitle("testTitle");
382
    auto uuid1 = QUuid::createUuid();
383
    entry1->setUuid(uuid1);
384

385
    auto entry2 = new Entry();
386
    entry2->setGroup(m_rootGroup);
387
    entry2->setTitle("testTitle2");
388
    auto uuid2 = QUuid::createUuid();
389
    entry2->setUuid(uuid2);
390

391
    m_searchResult = m_entrySearcher.search("uuid:", m_rootGroup);
392
    QCOMPARE(m_searchResult.count(), 2);
393

394
    m_searchResult = m_entrySearcher.search("uuid:" + Tools::uuidToHex(uuid1), m_rootGroup);
395
    QCOMPARE(m_searchResult.count(), 1);
396
}
397

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.