TestModified.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  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. #include "TestModified.h"
  18. #include "mock/MockClock.h"
  19. #include <QSignalSpy>
  20. #include <QTest>
  21. #include "core/Group.h"
  22. #include "core/Metadata.h"
  23. #include "crypto/Crypto.h"
  24. QTEST_GUILESS_MAIN(TestModified)
  25. namespace
  26. {
  27. MockClock* m_clock = nullptr;
  28. }
  29. void TestModified::initTestCase()
  30. {
  31. QVERIFY(Crypto::init());
  32. }
  33. void TestModified::init()
  34. {
  35. Q_ASSERT(m_clock == nullptr);
  36. m_clock = new MockClock(2010, 5, 5, 10, 30, 10);
  37. MockClock::setup(m_clock);
  38. }
  39. void TestModified::cleanup()
  40. {
  41. MockClock::teardown();
  42. m_clock = nullptr;
  43. }
  44. void TestModified::testSignals()
  45. {
  46. int spyCount = 0;
  47. int spyCount2 = 0;
  48. auto compositeKey = QSharedPointer<CompositeKey>::create();
  49. QScopedPointer<Database> db(new Database());
  50. auto* root = db->rootGroup();
  51. QSignalSpy spyModified(db.data(), SIGNAL(modified()));
  52. db->setKey(compositeKey);
  53. ++spyCount;
  54. QTRY_COMPARE(spyModified.count(), spyCount);
  55. auto* group1 = new Group();
  56. group1->setParent(root);
  57. ++spyCount;
  58. QTRY_COMPARE(spyModified.count(), spyCount);
  59. auto* group2 = new Group();
  60. group2->setParent(root);
  61. ++spyCount;
  62. QTRY_COMPARE(spyModified.count(), spyCount);
  63. group2->setParent(root, 0);
  64. ++spyCount;
  65. QTRY_COMPARE(spyModified.count(), spyCount);
  66. auto* entry1 = new Entry();
  67. entry1->setGroup(group1);
  68. ++spyCount;
  69. QTRY_COMPARE(spyModified.count(), spyCount);
  70. QScopedPointer<Database> db2(new Database());
  71. auto* root2 = db2->rootGroup();
  72. QSignalSpy spyModified2(db2.data(), SIGNAL(modified()));
  73. group1->setParent(root2);
  74. ++spyCount;
  75. QTRY_COMPARE(spyModified.count(), spyCount);
  76. ++spyCount2;
  77. QTRY_COMPARE(spyModified2.count(), spyCount2);
  78. entry1->setTitle("test");
  79. QTRY_COMPARE(spyModified.count(), spyCount);
  80. ++spyCount2;
  81. QTRY_COMPARE(spyModified2.count(), spyCount2);
  82. auto* entry2 = new Entry();
  83. entry2->setGroup(group2);
  84. ++spyCount;
  85. QTRY_COMPARE(spyModified.count(), spyCount);
  86. QTRY_COMPARE(spyModified2.count(), spyCount2);
  87. entry2->setGroup(root2);
  88. ++spyCount;
  89. QTRY_COMPARE(spyModified.count(), spyCount);
  90. ++spyCount2;
  91. QTRY_COMPARE(spyModified2.count(), spyCount2);
  92. entry2->setTitle("test2");
  93. QTRY_COMPARE(spyModified.count(), spyCount);
  94. ++spyCount2;
  95. QTRY_COMPARE(spyModified2.count(), spyCount2);
  96. auto* group3 = new Group();
  97. group3->setParent(root);
  98. ++spyCount;
  99. QTRY_COMPARE(spyModified.count(), spyCount);
  100. auto* group4 = new Group();
  101. group4->setParent(group3);
  102. ++spyCount;
  103. QTRY_COMPARE(spyModified.count(), spyCount);
  104. delete group4;
  105. ++spyCount;
  106. QTRY_COMPARE(spyModified.count(), spyCount);
  107. delete entry2;
  108. ++spyCount2;
  109. QTRY_COMPARE(spyModified2.count(), spyCount2);
  110. QTRY_COMPARE(spyModified.count(), spyCount);
  111. QTRY_COMPARE(spyModified2.count(), spyCount2);
  112. }
  113. void TestModified::testGroupSets()
  114. {
  115. int spyCount = 0;
  116. QScopedPointer<Database> db(new Database());
  117. auto* root = db->rootGroup();
  118. auto* group = new Group();
  119. group->setParent(root);
  120. QSignalSpy spyModified(db.data(), SIGNAL(modified()));
  121. root->setUuid(QUuid::createUuid());
  122. ++spyCount;
  123. QTRY_COMPARE(spyModified.count(), spyCount);
  124. root->setUuid(root->uuid());
  125. QTRY_COMPARE(spyModified.count(), spyCount);
  126. root->setName("test");
  127. ++spyCount;
  128. QTRY_COMPARE(spyModified.count(), spyCount);
  129. root->setName(root->name());
  130. QTRY_COMPARE(spyModified.count(), spyCount);
  131. root->setNotes("test");
  132. ++spyCount;
  133. QTRY_COMPARE(spyModified.count(), spyCount);
  134. root->setNotes(root->notes());
  135. QTRY_COMPARE(spyModified.count(), spyCount);
  136. root->setIcon(1);
  137. ++spyCount;
  138. QTRY_COMPARE(spyModified.count(), spyCount);
  139. root->setIcon(root->iconNumber());
  140. QTRY_COMPARE(spyModified.count(), spyCount);
  141. root->setIcon(QUuid::createUuid());
  142. ++spyCount;
  143. QTRY_COMPARE(spyModified.count(), spyCount);
  144. root->setIcon(root->iconUuid());
  145. QTRY_COMPARE(spyModified.count(), spyCount);
  146. group->setUuid(QUuid::createUuid());
  147. ++spyCount;
  148. QTRY_COMPARE(spyModified.count(), spyCount);
  149. group->setUuid(group->uuid());
  150. QTRY_COMPARE(spyModified.count(), spyCount);
  151. group->setName("test");
  152. ++spyCount;
  153. QTRY_COMPARE(spyModified.count(), spyCount);
  154. group->setName(group->name());
  155. QTRY_COMPARE(spyModified.count(), spyCount);
  156. group->setNotes("test");
  157. ++spyCount;
  158. QTRY_COMPARE(spyModified.count(), spyCount);
  159. group->setNotes(group->notes());
  160. QTRY_COMPARE(spyModified.count(), spyCount);
  161. group->setIcon(1);
  162. ++spyCount;
  163. QTRY_COMPARE(spyModified.count(), spyCount);
  164. group->setIcon(group->iconNumber());
  165. QTRY_COMPARE(spyModified.count(), spyCount);
  166. group->setIcon(QUuid::createUuid());
  167. ++spyCount;
  168. QTRY_COMPARE(spyModified.count(), spyCount);
  169. group->setIcon(group->iconUuid());
  170. QTRY_COMPARE(spyModified.count(), spyCount);
  171. }
  172. void TestModified::testEntrySets()
  173. {
  174. int spyCount = 0;
  175. QScopedPointer<Database> db(new Database());
  176. auto* root = db->rootGroup();
  177. auto* group = new Group();
  178. group->setParent(root);
  179. auto* entry = new Entry();
  180. entry->setGroup(group);
  181. QSignalSpy spyModified(db.data(), SIGNAL(modified()));
  182. entry->setUuid(QUuid::createUuid());
  183. ++spyCount;
  184. QTRY_COMPARE(spyModified.count(), spyCount);
  185. entry->setUuid(entry->uuid());
  186. QTRY_COMPARE(spyModified.count(), spyCount);
  187. entry->setTitle("test");
  188. ++spyCount;
  189. QTRY_COMPARE(spyModified.count(), spyCount);
  190. entry->setTitle(entry->title());
  191. QTRY_COMPARE(spyModified.count(), spyCount);
  192. entry->setUrl("test");
  193. ++spyCount;
  194. QTRY_COMPARE(spyModified.count(), spyCount);
  195. entry->setUrl(entry->url());
  196. QTRY_COMPARE(spyModified.count(), spyCount);
  197. entry->setUsername("test");
  198. ++spyCount;
  199. QTRY_COMPARE(spyModified.count(), spyCount);
  200. entry->setUsername(entry->username());
  201. QTRY_COMPARE(spyModified.count(), spyCount);
  202. entry->setPassword("test");
  203. ++spyCount;
  204. QTRY_COMPARE(spyModified.count(), spyCount);
  205. entry->setPassword(entry->password());
  206. QTRY_COMPARE(spyModified.count(), spyCount);
  207. entry->setNotes("test");
  208. ++spyCount;
  209. QTRY_COMPARE(spyModified.count(), spyCount);
  210. entry->setNotes(entry->notes());
  211. QTRY_COMPARE(spyModified.count(), spyCount);
  212. entry->setIcon(1);
  213. ++spyCount;
  214. QTRY_COMPARE(spyModified.count(), spyCount);
  215. entry->setIcon(entry->iconNumber());
  216. QTRY_COMPARE(spyModified.count(), spyCount);
  217. entry->setIcon(QUuid::createUuid());
  218. ++spyCount;
  219. QTRY_COMPARE(spyModified.count(), spyCount);
  220. entry->setIcon(entry->iconUuid());
  221. QTRY_COMPARE(spyModified.count(), spyCount);
  222. entry->setTags("test");
  223. ++spyCount;
  224. QTRY_COMPARE(spyModified.count(), spyCount);
  225. entry->setTags(entry->tags());
  226. QTRY_COMPARE(spyModified.count(), spyCount);
  227. entry->setExpires(true);
  228. ++spyCount;
  229. QTRY_COMPARE(spyModified.count(), spyCount);
  230. entry->setExpires(entry->timeInfo().expires());
  231. QTRY_COMPARE(spyModified.count(), spyCount);
  232. entry->setExpiryTime(Clock::currentDateTimeUtc().addYears(1));
  233. ++spyCount;
  234. QTRY_COMPARE(spyModified.count(), spyCount);
  235. entry->setExpiryTime(entry->timeInfo().expiryTime());
  236. QTRY_COMPARE(spyModified.count(), spyCount);
  237. entry->setAutoTypeEnabled(false);
  238. ++spyCount;
  239. QTRY_COMPARE(spyModified.count(), spyCount);
  240. entry->setAutoTypeEnabled(entry->autoTypeEnabled());
  241. QTRY_COMPARE(spyModified.count(), spyCount);
  242. entry->setAutoTypeObfuscation(1);
  243. ++spyCount;
  244. QTRY_COMPARE(spyModified.count(), spyCount);
  245. entry->setAutoTypeObfuscation(entry->autoTypeObfuscation());
  246. QTRY_COMPARE(spyModified.count(), spyCount);
  247. entry->setDefaultAutoTypeSequence("test");
  248. ++spyCount;
  249. QTRY_COMPARE(spyModified.count(), spyCount);
  250. entry->setDefaultAutoTypeSequence(entry->defaultAutoTypeSequence());
  251. QTRY_COMPARE(spyModified.count(), spyCount);
  252. entry->setForegroundColor(QString("#FF0000"));
  253. ++spyCount;
  254. QTRY_COMPARE(spyModified.count(), spyCount);
  255. entry->setForegroundColor(entry->foregroundColor());
  256. QTRY_COMPARE(spyModified.count(), spyCount);
  257. entry->setBackgroundColor(QString("#FF0000"));
  258. ++spyCount;
  259. QTRY_COMPARE(spyModified.count(), spyCount);
  260. entry->setBackgroundColor(entry->backgroundColor());
  261. QTRY_COMPARE(spyModified.count(), spyCount);
  262. entry->setOverrideUrl("test");
  263. ++spyCount;
  264. QTRY_COMPARE(spyModified.count(), spyCount);
  265. entry->setOverrideUrl(entry->overrideUrl());
  266. QTRY_COMPARE(spyModified.count(), spyCount);
  267. entry->attributes()->set("test key", "test value", false);
  268. ++spyCount;
  269. QTRY_COMPARE(spyModified.count(), spyCount);
  270. entry->attributes()->set("test key", entry->attributes()->value("test key"), false);
  271. QTRY_COMPARE(spyModified.count(), spyCount);
  272. entry->attributes()->set("test key", entry->attributes()->value("test key"), true);
  273. ++spyCount;
  274. QTRY_COMPARE(spyModified.count(), spyCount);
  275. entry->attributes()->set("test key", "new test value", true);
  276. ++spyCount;
  277. QTRY_COMPARE(spyModified.count(), spyCount);
  278. entry->attributes()->set("test key2", "test value2", true);
  279. ++spyCount;
  280. QTRY_COMPARE(spyModified.count(), spyCount);
  281. entry->attributes()->set("test key2", entry->attributes()->value("test key2"), true);
  282. QTRY_COMPARE(spyModified.count(), spyCount);
  283. }
  284. void TestModified::testHistoryItems()
  285. {
  286. QScopedPointer<Entry> entry(new Entry());
  287. QDateTime created = entry->timeInfo().creationTime();
  288. entry->setUuid(QUuid::createUuid());
  289. entry->setTitle("a");
  290. entry->setTags("a");
  291. QScopedPointer<EntryAttributes> attributes(new EntryAttributes());
  292. attributes->copyCustomKeysFrom(entry->attributes());
  293. int historyItemsSize = 0;
  294. entry->beginUpdate();
  295. entry->setTitle("a");
  296. entry->setTags("a");
  297. entry->setOverrideUrl("");
  298. entry->endUpdate();
  299. QCOMPARE(entry->historyItems().size(), historyItemsSize);
  300. QDateTime modified = entry->timeInfo().lastModificationTime();
  301. m_clock->advanceSecond(10);
  302. entry->beginUpdate();
  303. entry->setTitle("b");
  304. entry->endUpdate();
  305. QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
  306. auto* historyEntry = entry->historyItems().at(historyItemsSize - 1);
  307. QCOMPARE(historyEntry->title(), QString("a"));
  308. QCOMPARE(historyEntry->uuid(), entry->uuid());
  309. QCOMPARE(historyEntry->tags(), entry->tags());
  310. QCOMPARE(historyEntry->overrideUrl(), entry->overrideUrl());
  311. QCOMPARE(historyEntry->timeInfo().creationTime(), created);
  312. QCOMPARE(historyEntry->timeInfo().lastModificationTime(), modified);
  313. QCOMPARE(historyEntry->historyItems().size(), 0);
  314. entry->beginUpdate();
  315. entry->setTags("b");
  316. entry->endUpdate();
  317. QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
  318. QCOMPARE(entry->historyItems().at(historyItemsSize - 1)->tags(), QString("a"));
  319. entry->beginUpdate();
  320. entry->attachments()->set("test", QByteArray("value"));
  321. entry->endUpdate();
  322. QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
  323. QCOMPARE(entry->historyItems().at(historyItemsSize - 1)->attachments()->keys().size(), 0);
  324. attributes->set("k", "myvalue");
  325. entry->beginUpdate();
  326. entry->attributes()->copyCustomKeysFrom(attributes.data());
  327. entry->endUpdate();
  328. QCOMPARE(entry->historyItems().size(), ++historyItemsSize);
  329. QVERIFY(!entry->historyItems().at(historyItemsSize - 1)->attributes()->keys().contains("k"));
  330. QScopedPointer<Database> db(new Database());
  331. auto* root = db->rootGroup();
  332. db->metadata()->setHistoryMaxItems(3);
  333. db->metadata()->setHistoryMaxSize(-1);
  334. auto* entry2 = new Entry();
  335. entry2->setGroup(root);
  336. entry2->beginUpdate();
  337. entry2->setTitle("1");
  338. entry2->endUpdate();
  339. entry2->beginUpdate();
  340. entry2->setTitle("2");
  341. entry2->endUpdate();
  342. entry2->beginUpdate();
  343. entry2->setTitle("3");
  344. entry2->endUpdate();
  345. QCOMPARE(entry2->historyItems().size(), 3);
  346. entry2->beginUpdate();
  347. entry2->setTitle("4");
  348. entry2->endUpdate();
  349. QCOMPARE(entry2->historyItems().size(), 3);
  350. db->metadata()->setHistoryMaxItems(1);
  351. entry2->beginUpdate();
  352. entry2->setTitle("5");
  353. entry2->endUpdate();
  354. QCOMPARE(entry2->historyItems().size(), 1);
  355. auto* historyEntry2 = entry2->historyItems().at(0);
  356. QCOMPARE(historyEntry2->title(), QString("4"));
  357. db->metadata()->setHistoryMaxItems(-1);
  358. for (int i = 0; i < 20; i++) {
  359. entry2->beginUpdate();
  360. entry2->setTitle("6");
  361. entry2->endUpdate();
  362. entry2->beginUpdate();
  363. entry2->setTitle("6b");
  364. entry2->endUpdate();
  365. }
  366. QCOMPARE(entry2->historyItems().size(), 41);
  367. db->metadata()->setHistoryMaxItems(0);
  368. entry2->beginUpdate();
  369. entry2->setTitle("7");
  370. entry2->endUpdate();
  371. QCOMPARE(entry2->historyItems().size(), 0);
  372. const int historyMaxSize = 19000;
  373. db->metadata()->setHistoryMaxItems(-1);
  374. db->metadata()->setHistoryMaxSize(historyMaxSize);
  375. const QString key("test");
  376. entry2->beginUpdate();
  377. entry2->attachments()->set(key, QByteArray(18000, 'X'));
  378. entry2->endUpdate();
  379. QCOMPARE(entry2->attachments()->attachmentsSize(), 18000 + key.size());
  380. QCOMPARE(entry2->historyItems().size(), 1);
  381. historyEntry2 = entry2->historyItems().at(0);
  382. QCOMPARE(historyEntry2->title(), QString("7"));
  383. entry2->beginUpdate();
  384. entry2->setTitle("8");
  385. entry2->endUpdate();
  386. QCOMPARE(entry2->historyItems().size(), 2);
  387. entry2->beginUpdate();
  388. entry2->attachments()->remove(key);
  389. entry2->endUpdate();
  390. QCOMPARE(entry2->attachments()->attachmentsSize(), 0);
  391. QCOMPARE(entry2->historyItems().size(), 1);
  392. entry2->beginUpdate();
  393. entry2->attachments()->set("test2", QByteArray(6000, 'a'));
  394. entry2->endUpdate();
  395. QCOMPARE(entry2->attachments()->attachmentsSize(), 6000 + key.size() + 1);
  396. QCOMPARE(entry2->historyItems().size(), 2);
  397. entry2->beginUpdate();
  398. entry2->attachments()->set("test3", QByteArray(6000, 'b'));
  399. entry2->endUpdate();
  400. QCOMPARE(entry2->attachments()->attachmentsSize(), 12000 + (key.size() + 1) * 2);
  401. QCOMPARE(entry2->historyItems().size(), 2);
  402. entry2->beginUpdate();
  403. entry2->attachments()->set("test4", QByteArray(6000, 'c'));
  404. entry2->endUpdate();
  405. QCOMPARE(entry2->attachments()->attachmentsSize(), 18000 + (key.size() + 1) * 3);
  406. QCOMPARE(entry2->historyItems().size(), 3);
  407. entry2->beginUpdate();
  408. entry2->attachments()->set("test5", QByteArray(6000, 'd'));
  409. entry2->endUpdate();
  410. QCOMPARE(entry2->attachments()->attachmentsSize(), 24000 + (key.size() + 1) * 4);
  411. QCOMPARE(entry2->historyItems().size(), 1);
  412. }
  413. void TestModified::testHistoryMaxSize()
  414. {
  415. QScopedPointer<Database> db(new Database());
  416. const QString key("test");
  417. auto entry1 = new Entry();
  418. entry1->setGroup(db->rootGroup());
  419. QCOMPARE(entry1->historyItems().size(), 0);
  420. const int reservedSize1 = entry1->attributes()->attributesSize();
  421. db->metadata()->setHistoryMaxItems(-1);
  422. db->metadata()->setHistoryMaxSize(18000 + key.size() * 3 + reservedSize1 * 4);
  423. entry1->beginUpdate();
  424. entry1->attachments()->set(key, QByteArray(6000, 'a'));
  425. entry1->endUpdate();
  426. QCOMPARE(entry1->attachments()->attachmentsSize(), 6000 + key.size());
  427. QCOMPARE(entry1->historyItems().size(), 1);
  428. entry1->beginUpdate();
  429. entry1->attachments()->set(key, QByteArray(6000, 'b'));
  430. entry1->endUpdate();
  431. QCOMPARE(entry1->attachments()->attachmentsSize(), 6000 + key.size());
  432. QCOMPARE(entry1->historyItems().size(), 2);
  433. entry1->beginUpdate();
  434. entry1->attachments()->set(key, QByteArray(6000, 'c'));
  435. entry1->endUpdate();
  436. QCOMPARE(entry1->attachments()->attachmentsSize(), 6000 + key.size());
  437. QCOMPARE(entry1->historyItems().size(), 3);
  438. entry1->beginUpdate();
  439. entry1->attachments()->set(key, QByteArray(6000, 'd'));
  440. entry1->endUpdate();
  441. QCOMPARE(entry1->attachments()->attachmentsSize(), 6000 + key.size());
  442. QCOMPARE(entry1->historyItems().size(), 4);
  443. auto entry2 = new Entry();
  444. entry2->setGroup(db->rootGroup());
  445. QCOMPARE(entry2->historyItems().size(), 0);
  446. const int historyMaxSize = 17000;
  447. const int reservedSize2 = entry2->attributes()->attributesSize();
  448. db->metadata()->setHistoryMaxSize(historyMaxSize);
  449. entry2->beginUpdate();
  450. entry2->attachments()->set(key, QByteArray(historyMaxSize - key.size() - reservedSize2 + 1, 'a'));
  451. entry2->endUpdate();
  452. QCOMPARE(entry2->attachments()->attachmentsSize(), historyMaxSize - reservedSize2 + 1);
  453. QCOMPARE(entry2->historyItems().size(), 1);
  454. // history size overflow
  455. entry2->beginUpdate();
  456. entry2->attachments()->set(key, QByteArray(historyMaxSize - key.size() - reservedSize2 + 1, 'b'));
  457. entry2->endUpdate();
  458. QCOMPARE(entry2->historyItems().size(), 0);
  459. entry2->beginUpdate();
  460. entry2->attachments()->remove(key);
  461. entry2->endUpdate();
  462. QCOMPARE(entry2->attachments()->attachmentsSize(), 0);
  463. QCOMPARE(entry2->historyItems().size(), 0);
  464. entry2->beginUpdate();
  465. entry2->attachments()->set(key, QByteArray(historyMaxSize - key.size() - reservedSize2 + 1, 'a'));
  466. entry2->endUpdate();
  467. QCOMPARE(entry2->attachments()->attachmentsSize(), historyMaxSize - reservedSize2 + 1);
  468. QCOMPARE(entry2->historyItems().size(), 1);
  469. // history size overflow
  470. entry2->beginUpdate();
  471. entry2->attachments()->set(key, QByteArray(historyMaxSize - key.size() - reservedSize2 + 1, 'b'));
  472. entry2->endUpdate();
  473. QCOMPARE(entry2->historyItems().size(), 0);
  474. entry2->beginUpdate();
  475. entry2->attachments()->remove(key);
  476. entry2->endUpdate();
  477. QCOMPARE(entry2->attachments()->attachmentsSize(), 0);
  478. QCOMPARE(entry2->historyItems().size(), 0);
  479. entry2->beginUpdate();
  480. entry2->setTags(QByteArray(historyMaxSize - reservedSize2 + 1, 'a'));
  481. entry2->endUpdate();
  482. QCOMPARE(entry2->tags().size(), historyMaxSize - reservedSize2 + 1);
  483. QCOMPARE(entry2->historyItems().size(), 1);
  484. // history size overflow
  485. entry2->beginUpdate();
  486. entry2->setTags(QByteArray(historyMaxSize - reservedSize2 + 1, 'b'));
  487. entry2->endUpdate();
  488. QCOMPARE(entry2->historyItems().size(), 0);
  489. entry2->beginUpdate();
  490. entry2->setTags("");
  491. entry2->endUpdate();
  492. QCOMPARE(entry2->historyItems().size(), 0);
  493. entry2->beginUpdate();
  494. entry2->attributes()->set(key, QByteArray(historyMaxSize - key.size() - reservedSize2 + 1, 'a'));
  495. entry2->endUpdate();
  496. QCOMPARE(entry2->attributes()->attributesSize(), historyMaxSize + 1);
  497. QCOMPARE(entry2->historyItems().size(), 1);
  498. // history size overflow
  499. entry2->beginUpdate();
  500. entry2->attributes()->set(key, QByteArray(historyMaxSize - key.size() - reservedSize2 + 1, 'b'));
  501. entry2->endUpdate();
  502. QCOMPARE(entry2->attributes()->attributesSize(), historyMaxSize + 1);
  503. QCOMPARE(entry2->historyItems().size(), 0);
  504. entry2->beginUpdate();
  505. entry2->attributes()->remove(key);
  506. entry2->endUpdate();
  507. QCOMPARE(entry2->attributes()->attributesSize(), reservedSize2);
  508. QCOMPARE(entry2->historyItems().size(), 0);
  509. entry2->beginUpdate();
  510. AutoTypeAssociations::Association association;
  511. association.window = key;
  512. association.sequence = QByteArray(historyMaxSize - key.size() - reservedSize2 + 1, 'a');
  513. entry2->autoTypeAssociations()->add(association);
  514. entry2->endUpdate();
  515. QCOMPARE(entry2->autoTypeAssociations()->associationsSize(), historyMaxSize - reservedSize2 + 1);
  516. QCOMPARE(entry2->historyItems().size(), 1);
  517. entry2->beginUpdate();
  518. entry2->autoTypeAssociations()->remove(0);
  519. entry2->endUpdate();
  520. QCOMPARE(entry2->autoTypeAssociations()->associationsSize(), 0);
  521. QCOMPARE(entry2->historyItems().size(), 0);
  522. }
  523. void TestModified::testCustomData()
  524. {
  525. int spyCount = 0;
  526. QScopedPointer<Database> db(new Database());
  527. auto* root = db->rootGroup();
  528. auto* group = new Group();
  529. group->setParent(root);
  530. auto* entry = new Entry();
  531. entry->setGroup(group);
  532. QSignalSpy spyModified(db.data(), SIGNAL(modified()));
  533. db->metadata()->customData()->set("Key", "Value");
  534. ++spyCount;
  535. QTRY_COMPARE(spyModified.count(), spyCount);
  536. db->metadata()->customData()->set("Key", "Value");
  537. QTRY_COMPARE(spyModified.count(), spyCount);
  538. entry->customData()->set("Key", "Value");
  539. ++spyCount;
  540. QTRY_COMPARE(spyModified.count(), spyCount);
  541. entry->customData()->set("Key", "Value");
  542. QTRY_COMPARE(spyModified.count(), spyCount);
  543. group->customData()->set("Key", "Value");
  544. ++spyCount;
  545. QTRY_COMPARE(spyModified.count(), spyCount);
  546. group->customData()->set("Key", "Value");
  547. QTRY_COMPARE(spyModified.count(), spyCount);
  548. }
  549. void TestModified::testBlockModifiedSignal()
  550. {
  551. QScopedPointer<Database> db(new Database());
  552. auto entry = db->rootGroup()->addEntryWithPath("/abc");
  553. QSignalSpy spyDbModified(db.data(), SIGNAL(modified()));
  554. QSignalSpy spyMetadataModified(db->metadata(), SIGNAL(modified()));
  555. QSignalSpy spyCustomDataModified(db->metadata()->customData(), SIGNAL(modified()));
  556. QSignalSpy spyGroupModified(db->rootGroup(), SIGNAL(modified()));
  557. QSignalSpy spyGroupCustomDataModified(db->rootGroup()->customData(), SIGNAL(modified()));
  558. QSignalSpy spyEntryModified(entry, SIGNAL(modified()));
  559. QSignalSpy spyEntryCustomDataModified(entry->customData(), SIGNAL(modified()));
  560. QSignalSpy spyEntryAttributesModified(entry->attributes(), SIGNAL(modified()));
  561. QSignalSpy spyEntryAttachmentModified(entry->attachments(), SIGNAL(modified()));
  562. QSignalSpy spyEntryAutoTypeAssociationsModified(entry->autoTypeAssociations(), SIGNAL(modified()));
  563. QVERIFY(spyDbModified.isValid());
  564. QVERIFY(spyMetadataModified.isValid());
  565. QVERIFY(spyCustomDataModified.isValid());
  566. QVERIFY(spyGroupModified.isValid());
  567. QVERIFY(spyGroupCustomDataModified.isValid());
  568. QVERIFY(spyEntryModified.isValid());
  569. QVERIFY(spyEntryCustomDataModified.isValid());
  570. QVERIFY(spyEntryAttributesModified.isValid());
  571. QVERIFY(spyEntryAttachmentModified.isValid());
  572. QVERIFY(spyEntryAutoTypeAssociationsModified.isValid());
  573. db->setEmitModified(false);
  574. auto* group1 = new Group();
  575. group1->setParent(db->rootGroup());
  576. db->metadata()->setName("Modified Database");
  577. db->metadata()->customData()->set("Key", "Value");
  578. group1->customData()->set("abc", "dd");
  579. entry->setTitle("Another Title");
  580. entry->customData()->set("entryabc", "dd");
  581. entry->attributes()->set("aaa", "dd");
  582. entry->attachments()->set("aaa", {});
  583. entry->autoTypeAssociations()->add({"", ""});
  584. db.reset();
  585. QCOMPARE(spyDbModified.count(), 0);
  586. QCOMPARE(spyMetadataModified.count(), 0);
  587. QCOMPARE(spyCustomDataModified.count(), 0);
  588. QCOMPARE(spyGroupModified.count(), 0);
  589. QCOMPARE(spyGroupCustomDataModified.count(), 0);
  590. QCOMPARE(spyEntryModified.count(), 0);
  591. QCOMPARE(spyEntryCustomDataModified.count(), 0);
  592. QCOMPARE(spyEntryAttributesModified.count(), 0);
  593. QCOMPARE(spyEntryAttachmentModified.count(), 0);
  594. QCOMPARE(spyEntryAutoTypeAssociationsModified.count(), 0);
  595. }