1 /*
2  *  Copyright (C) 2012 Felix Geyer <debfx@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 "TestModified.h"
19 
20 #include <QSignalSpy>
21 #include <QTest>
22 
23 #include "core/Database.h"
24 #include "core/Group.h"
25 #include "core/Metadata.h"
26 #include "core/Tools.h"
27 #include "crypto/Crypto.h"
28 
QTEST_GUILESS_MAIN(TestModified)29 QTEST_GUILESS_MAIN(TestModified)
30 
31 void TestModified::initTestCase()
32 {
33     QVERIFY(Crypto::init());
34 }
35 
testSignals()36 void TestModified::testSignals()
37 {
38     int spyCount = 0;
39     int spyCount2 = 0;
40 
41     CompositeKey compositeKey;
42 
43     Database* db = new Database();
44     Group* root = db->rootGroup();
45     QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
46 
47     db->setKey(compositeKey);
48     QCOMPARE(spyModified.count(), ++spyCount);
49 
50     Group* g1 = new Group();
51     g1->setParent(root);
52     QCOMPARE(spyModified.count(), ++spyCount);
53 
54     Group* g2 = new Group();
55     g2->setParent(root);
56     QCOMPARE(spyModified.count(), ++spyCount);
57 
58     g2->setParent(root, 0);
59     QCOMPARE(spyModified.count(), ++spyCount);
60 
61     Entry* entry1 = new Entry();
62     entry1->setGroup(g1);
63     QCOMPARE(spyModified.count(), ++spyCount);
64 
65     Database* db2 = new Database();
66     Group* root2 = db2->rootGroup();
67     QSignalSpy spyModified2(db2, SIGNAL(modifiedImmediate()));
68 
69     g1->setParent(root2);
70     QCOMPARE(spyModified.count(), ++spyCount);
71     QCOMPARE(spyModified2.count(), ++spyCount2);
72 
73     entry1->setTitle("test");
74     QCOMPARE(spyModified.count(), spyCount);
75     QCOMPARE(spyModified2.count(), ++spyCount2);
76 
77     Entry* entry2 = new Entry();
78     entry2->setGroup(g2);
79     QCOMPARE(spyModified.count(), ++spyCount);
80     QCOMPARE(spyModified2.count(), spyCount2);
81 
82     entry2->setGroup(root2);
83     QCOMPARE(spyModified.count(), ++spyCount);
84     QCOMPARE(spyModified2.count(), ++spyCount2);
85 
86     entry2->setTitle("test2");
87     QCOMPARE(spyModified.count(), spyCount);
88     QCOMPARE(spyModified2.count(), ++spyCount2);
89 
90     Group* g3 = new Group();
91     g3->setParent(root);
92     QCOMPARE(spyModified.count(), ++spyCount);
93 
94     Group* g4 = new Group();
95     g4->setParent(g3);
96     QCOMPARE(spyModified.count(), ++spyCount);
97 
98     delete g4;
99     QCOMPARE(spyModified.count(), ++spyCount);
100 
101     delete entry2;
102     QCOMPARE(spyModified2.count(), ++spyCount2);
103 
104     QCOMPARE(spyModified.count(), spyCount);
105     QCOMPARE(spyModified2.count(), spyCount2);
106 
107     delete db;
108     delete db2;
109 }
110 
testGroupSets()111 void TestModified::testGroupSets()
112 {
113     int spyCount = 0;
114     Database* db = new Database();
115     Group* root = db->rootGroup();
116 
117     Group* g = new Group();
118     g->setParent(root);
119 
120     QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
121 
122     root->setUuid(Uuid::random());
123     QCOMPARE(spyModified.count(), ++spyCount);
124     root->setUuid(root->uuid());
125     QCOMPARE(spyModified.count(), spyCount);
126 
127     root->setName("test");
128     QCOMPARE(spyModified.count(), ++spyCount);
129     root->setName(root->name());
130     QCOMPARE(spyModified.count(), spyCount);
131 
132     root->setNotes("test");
133     QCOMPARE(spyModified.count(), ++spyCount);
134     root->setNotes(root->notes());
135     QCOMPARE(spyModified.count(), spyCount);
136 
137     root->setIcon(1);
138     QCOMPARE(spyModified.count(), ++spyCount);
139     root->setIcon(root->iconNumber());
140     QCOMPARE(spyModified.count(), spyCount);
141 
142     root->setIcon(Uuid::random());
143     QCOMPARE(spyModified.count(), ++spyCount);
144     root->setIcon(root->iconUuid());
145     QCOMPARE(spyModified.count(), spyCount);
146 
147 
148     g->setUuid(Uuid::random());
149     QCOMPARE(spyModified.count(), ++spyCount);
150     g->setUuid(g->uuid());
151     QCOMPARE(spyModified.count(), spyCount);
152 
153     g->setName("test");
154     QCOMPARE(spyModified.count(), ++spyCount);
155     g->setName(g->name());
156     QCOMPARE(spyModified.count(), spyCount);
157 
158     g->setNotes("test");
159     QCOMPARE(spyModified.count(), ++spyCount);
160     g->setNotes(g->notes());
161     QCOMPARE(spyModified.count(), spyCount);
162 
163     g->setIcon(1);
164     QCOMPARE(spyModified.count(), ++spyCount);
165     g->setIcon(g->iconNumber());
166     QCOMPARE(spyModified.count(), spyCount);
167 
168     g->setIcon(Uuid::random());
169     QCOMPARE(spyModified.count(), ++spyCount);
170     g->setIcon(g->iconUuid());
171     QCOMPARE(spyModified.count(), spyCount);
172 
173     delete db;
174 }
175 
testEntrySets()176 void TestModified::testEntrySets()
177 {
178     int spyCount = 0;
179     Database* db = new Database();
180     Group* root = db->rootGroup();
181 
182     Group* g = new Group();
183     g->setParent(root);
184     Entry* entry = new Entry();
185     entry->setGroup(g);
186 
187     QSignalSpy spyModified(db, SIGNAL(modifiedImmediate()));
188 
189     entry->setUuid(Uuid::random());
190     QCOMPARE(spyModified.count(), ++spyCount);
191     entry->setUuid(entry->uuid());
192     QCOMPARE(spyModified.count(), spyCount);
193 
194     entry->setTitle("test");
195     QCOMPARE(spyModified.count(), ++spyCount);
196     entry->setTitle(entry->title());
197     QCOMPARE(spyModified.count(), spyCount);
198 
199     entry->setUrl("test");
200     QCOMPARE(spyModified.count(), ++spyCount);
201     entry->setUrl(entry->url());
202     QCOMPARE(spyModified.count(), spyCount);
203 
204     entry->setUsername("test");
205     QCOMPARE(spyModified.count(), ++spyCount);
206     entry->setUsername(entry->username());
207     QCOMPARE(spyModified.count(), spyCount);
208 
209     entry->setPassword("test");
210     QCOMPARE(spyModified.count(), ++spyCount);
211     entry->setPassword(entry->password());
212     QCOMPARE(spyModified.count(), spyCount);
213 
214     entry->setNotes("test");
215     QCOMPARE(spyModified.count(), ++spyCount);
216     entry->setNotes(entry->notes());
217     QCOMPARE(spyModified.count(), spyCount);
218 
219     entry->setIcon(1);
220     QCOMPARE(spyModified.count(), ++spyCount);
221     entry->setIcon(entry->iconNumber());
222     QCOMPARE(spyModified.count(), spyCount);
223 
224     entry->setIcon(Uuid::random());
225     QCOMPARE(spyModified.count(), ++spyCount);
226     entry->setIcon(entry->iconUuid());
227     QCOMPARE(spyModified.count(), spyCount);
228 
229     entry->setTags("test");
230     QCOMPARE(spyModified.count(), ++spyCount);
231     entry->setTags(entry->tags());
232     QCOMPARE(spyModified.count(), spyCount);
233 
234     entry->setExpires(true);
235     QCOMPARE(spyModified.count(), ++spyCount);
236     entry->setExpires(entry->timeInfo().expires());
237     QCOMPARE(spyModified.count(), spyCount);
238 
239     entry->setExpiryTime(QDateTime::currentDateTimeUtc().addYears(1));
240     QCOMPARE(spyModified.count(), ++spyCount);
241     entry->setExpiryTime(entry->timeInfo().expiryTime());
242     QCOMPARE(spyModified.count(), spyCount);
243 
244     entry->setAutoTypeEnabled(false);
245     QCOMPARE(spyModified.count(), ++spyCount);
246     entry->setAutoTypeEnabled(entry->autoTypeEnabled());
247     QCOMPARE(spyModified.count(), spyCount);
248 
249     entry->setAutoTypeObfuscation(1);
250     QCOMPARE(spyModified.count(), ++spyCount);
251     entry->setAutoTypeObfuscation(entry->autoTypeObfuscation());
252     QCOMPARE(spyModified.count(), spyCount);
253 
254     entry->setDefaultAutoTypeSequence("test");
255     QCOMPARE(spyModified.count(), ++spyCount);
256     entry->setDefaultAutoTypeSequence(entry->defaultAutoTypeSequence());
257     QCOMPARE(spyModified.count(), spyCount);
258 
259     entry->setForegroundColor(Qt::red);
260     QCOMPARE(spyModified.count(), ++spyCount);
261     entry->setForegroundColor(entry->foregroundColor());
262     QCOMPARE(spyModified.count(), spyCount);
263 
264     entry->setBackgroundColor(Qt::red);
265     QCOMPARE(spyModified.count(), ++spyCount);
266     entry->setBackgroundColor(entry->backgroundColor());
267     QCOMPARE(spyModified.count(), spyCount);
268 
269     entry->setOverrideUrl("test");
270     QCOMPARE(spyModified.count(), ++spyCount);
271     entry->setOverrideUrl(entry->overrideUrl());
272     QCOMPARE(spyModified.count(), spyCount);
273 
274     entry->attributes()->set("test key", "test value", false);
275     QCOMPARE(spyModified.count(), ++spyCount);
276     entry->attributes()->set("test key", entry->attributes()->value("test key"), false);
277     QCOMPARE(spyModified.count(), spyCount);
278     entry->attributes()->set("test key", entry->attributes()->value("test key"), true);
279     QCOMPARE(spyModified.count(), ++spyCount);
280     entry->attributes()->set("test key", "new test value", true);
281     QCOMPARE(spyModified.count(), ++spyCount);
282 
283     entry->attributes()->set("test key2", "test value2", true);
284     QCOMPARE(spyModified.count(), ++spyCount);
285     entry->attributes()->set("test key2", entry->attributes()->value("test key2"), true);
286     QCOMPARE(spyModified.count(), spyCount);
287 
288     delete db;
289 }
290 
testHistoryItem()291 void TestModified::testHistoryItem()
292 {
293     Entry* entry = new Entry();
294     QDateTime created = entry->timeInfo().creationTime();
295     entry->setUuid(Uuid::random());
296     entry->setTitle("a");
297     entry->setTags("a");
298     EntryAttributes* attributes = new EntryAttributes();
299     attributes->copyCustomKeysFrom(entry->attributes());
300 
301     Entry* historyEntry;
302 
303     int historyItemsSize = 0;
304 
305     entry->beginUpdate();
306     entry->setTitle("a");
307     entry->setTags("a");
308     entry->setOverrideUrl("");
309     entry->endUpdate();
310     QCOMPARE(entry->historyItems().size(), historyItemsSize);
311 
312     QDateTime modified = entry->timeInfo().lastModificationTime();
313     QTest::qSleep(10);
314     entry->beginUpdate();
315     entry->setTitle("b");
316     entry->endUpdate();
317     QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
318     historyEntry = entry->historyItems().at(historyItemsSize - 1);
319     QCOMPARE(historyEntry->title(), QString("a"));
320     QCOMPARE(historyEntry->uuid(), entry->uuid());
321     QCOMPARE(historyEntry->tags(), entry->tags());
322     QCOMPARE(historyEntry->overrideUrl(), entry->overrideUrl());
323     QCOMPARE(historyEntry->timeInfo().creationTime(), created);
324     QCOMPARE(historyEntry->timeInfo().lastModificationTime(), modified);
325     QCOMPARE(historyEntry->historyItems().size(), 0);
326 
327     entry->beginUpdate();
328     entry->setTags("b");
329     entry->endUpdate();
330     QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
331     QCOMPARE(entry->historyItems().at(historyItemsSize - 1)->tags(), QString("a"));
332 
333     entry->beginUpdate();
334     entry->attachments()->set("test", QByteArray("value"));
335     entry->endUpdate();
336     QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
337     QCOMPARE(entry->historyItems().at(historyItemsSize - 1)->attachments()->keys().size(), 0);
338 
339     attributes->set("k", "myvalue");
340     entry->beginUpdate();
341     entry->attributes()->copyCustomKeysFrom(attributes);
342     entry->endUpdate();
343     QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
344     QVERIFY(!entry->historyItems().at(historyItemsSize - 1)->attributes()->keys().contains("k"));
345 
346     delete attributes;
347     delete entry;
348 
349     Database* db = new Database();
350     Group* root = db->rootGroup();
351     db->metadata()->setHistoryMaxItems(3);
352     db->metadata()->setHistoryMaxSize(-1);
353 
354     Entry* historyEntry2;
355     Entry* entry2 = new Entry();
356     entry2->setGroup(root);
357     entry2->beginUpdate();
358     entry2->setTitle("1");
359     entry2->endUpdate();
360 
361     entry2->beginUpdate();
362     entry2->setTitle("2");
363     entry2->endUpdate();
364     entry2->beginUpdate();
365     entry2->setTitle("3");
366     entry2->endUpdate();
367     QCOMPARE(entry2->historyItems().size(), 3);
368 
369     entry2->beginUpdate();
370     entry2->setTitle("4");
371     entry2->endUpdate();
372     QCOMPARE(entry2->historyItems().size(), 3);
373 
374     db->metadata()->setHistoryMaxItems(1);
375 
376     entry2->beginUpdate();
377     entry2->setTitle("5");
378     entry2->endUpdate();
379     QCOMPARE(entry2->historyItems().size(), 1);
380 
381     historyEntry2 = entry2->historyItems().at(0);
382     QCOMPARE(historyEntry2->title(), QString("4"));
383 
384     db->metadata()->setHistoryMaxItems(-1);
385 
386     for (int i = 0; i < 20; i++) {
387         entry2->beginUpdate();
388         entry2->setTitle("6");
389         entry2->endUpdate();
390         entry2->beginUpdate();
391         entry2->setTitle("6b");
392         entry2->endUpdate();
393     }
394     QCOMPARE(entry2->historyItems().size(), 41);
395 
396     db->metadata()->setHistoryMaxItems(0);
397 
398     entry2->beginUpdate();
399     entry2->setTitle("7");
400     entry2->endUpdate();
401     QCOMPARE(entry2->historyItems().size(), 0);
402 
403     db->metadata()->setHistoryMaxItems(-1);
404     db->metadata()->setHistoryMaxSize(17000);
405 
406     entry2->beginUpdate();
407     entry2->attachments()->set("test", QByteArray(18000, 'X'));
408     entry2->endUpdate();
409     QCOMPARE(entry2->historyItems().size(), 1);
410 
411     historyEntry2 = entry2->historyItems().at(0);
412     QCOMPARE(historyEntry2->title(), QString("7"));
413 
414     entry2->beginUpdate();
415     entry2->setTitle("8");
416     entry2->endUpdate();
417     QCOMPARE(entry2->historyItems().size(), 2);
418 
419     entry2->beginUpdate();
420     entry2->attachments()->remove("test");
421     entry2->endUpdate();
422     QCOMPARE(entry2->historyItems().size(), 0);
423 
424     entry2->beginUpdate();
425     entry2->attachments()->set("test2", QByteArray(6000, 'a'));
426     entry2->endUpdate();
427     QCOMPARE(entry2->historyItems().size(), 1);
428 
429     entry2->beginUpdate();
430     entry2->attachments()->set("test3", QByteArray(6000, 'b'));
431     entry2->endUpdate();
432     QCOMPARE(entry2->historyItems().size(), 2);
433 
434     entry2->beginUpdate();
435     entry2->attachments()->set("test4", QByteArray(6000, 'c'));
436     entry2->endUpdate();
437     QCOMPARE(entry2->historyItems().size(), 3);
438 
439     entry2->beginUpdate();
440     entry2->attachments()->set("test5", QByteArray(6000, 'd'));
441     entry2->endUpdate();
442     QCOMPARE(entry2->historyItems().size(), 4);
443 
444     Entry* entry3 = new Entry();
445     entry3->setGroup(root);
446     QCOMPARE(entry3->historyItems().size(), 0);
447 
448     entry3->beginUpdate();
449     entry3->attachments()->set("test", QByteArray(6000, 'a'));
450     entry3->endUpdate();
451     QCOMPARE(entry3->historyItems().size(), 1);
452 
453     entry3->beginUpdate();
454     entry3->attachments()->set("test", QByteArray(6000, 'b'));
455     entry3->endUpdate();
456     QCOMPARE(entry3->historyItems().size(), 2);
457 
458     entry3->beginUpdate();
459     entry3->attachments()->set("test", QByteArray(6000, 'c'));
460     entry3->endUpdate();
461     QCOMPARE(entry3->historyItems().size(), 3);
462 
463     entry3->beginUpdate();
464     entry3->attachments()->set("test", QByteArray(6000, 'd'));
465     entry3->endUpdate();
466     QCOMPARE(entry3->historyItems().size(), 2);
467 
468     delete db;
469 }
470