TestEntryModel.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * Copyright (C) 2010 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 "TestEntryModel.h"
  18. #include <QSignalSpy>
  19. #include <QTest>
  20. #include "core/Entry.h"
  21. #include "core/Group.h"
  22. #include "crypto/Crypto.h"
  23. #include "gui/DatabaseIcons.h"
  24. #include "gui/IconModels.h"
  25. #include "gui/SortFilterHideProxyModel.h"
  26. #include "gui/entry/AutoTypeAssociationsModel.h"
  27. #include "gui/entry/EntryAttachmentsModel.h"
  28. #include "gui/entry/EntryAttributesModel.h"
  29. #include "gui/entry/EntryModel.h"
  30. #include "modeltest.h"
  31. QTEST_GUILESS_MAIN(TestEntryModel)
  32. void TestEntryModel::initTestCase()
  33. {
  34. qRegisterMetaType<QModelIndex>("QModelIndex");
  35. QVERIFY(Crypto::init());
  36. }
  37. void TestEntryModel::test()
  38. {
  39. auto group1 = new Group();
  40. auto group2 = new Group();
  41. auto entry1 = new Entry();
  42. entry1->setGroup(group1);
  43. entry1->setTitle("testTitle1");
  44. auto entry2 = new Entry();
  45. entry2->setGroup(group1);
  46. entry2->setTitle("testTitle2");
  47. auto model = new EntryModel(this);
  48. QSignalSpy spyAboutToBeMoved(model, SIGNAL(rowsAboutToBeMoved(QModelIndex, int, int, QModelIndex, int)));
  49. QSignalSpy spyMoved(model, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)));
  50. auto modelTest = new ModelTest(model, this);
  51. model->setGroup(group1);
  52. QCOMPARE(model->rowCount(), 2);
  53. QSignalSpy spyDataChanged(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)));
  54. entry1->setTitle("changed");
  55. QCOMPARE(spyDataChanged.count(), 1);
  56. QModelIndex index1 = model->index(0, 1);
  57. QModelIndex index2 = model->index(1, 1);
  58. QCOMPARE(model->data(index1).toString(), entry1->title());
  59. QCOMPARE(model->data(index2).toString(), entry2->title());
  60. QSignalSpy spyAboutToAdd(model, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)));
  61. QSignalSpy spyAdded(model, SIGNAL(rowsInserted(QModelIndex, int, int)));
  62. QSignalSpy spyAboutToRemove(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)));
  63. QSignalSpy spyRemoved(model, SIGNAL(rowsRemoved(QModelIndex, int, int)));
  64. auto entry3 = new Entry();
  65. entry3->setGroup(group1);
  66. QCOMPARE(spyAboutToBeMoved.count(), 0);
  67. QCOMPARE(spyMoved.count(), 0);
  68. entry1->moveDown();
  69. QCOMPARE(spyAboutToBeMoved.count(), 1);
  70. QCOMPARE(spyMoved.count(), 1);
  71. entry1->moveDown();
  72. QCOMPARE(spyAboutToBeMoved.count(), 2);
  73. QCOMPARE(spyMoved.count(), 2);
  74. entry1->moveDown();
  75. QCOMPARE(spyAboutToBeMoved.count(), 2);
  76. QCOMPARE(spyMoved.count(), 2);
  77. entry3->moveUp();
  78. QCOMPARE(spyAboutToBeMoved.count(), 3);
  79. QCOMPARE(spyMoved.count(), 3);
  80. entry3->moveUp();
  81. QCOMPARE(spyAboutToBeMoved.count(), 3);
  82. QCOMPARE(spyMoved.count(), 3);
  83. QCOMPARE(spyAboutToAdd.count(), 1);
  84. QCOMPARE(spyAdded.count(), 1);
  85. QCOMPARE(spyAboutToRemove.count(), 0);
  86. QCOMPARE(spyRemoved.count(), 0);
  87. entry2->setGroup(group2);
  88. QCOMPARE(spyAboutToAdd.count(), 1);
  89. QCOMPARE(spyAdded.count(), 1);
  90. QCOMPARE(spyAboutToRemove.count(), 1);
  91. QCOMPARE(spyRemoved.count(), 1);
  92. QSignalSpy spyReset(model, SIGNAL(modelReset()));
  93. model->setGroup(group2);
  94. QCOMPARE(spyReset.count(), 1);
  95. delete group1;
  96. delete group2;
  97. delete modelTest;
  98. delete model;
  99. }
  100. void TestEntryModel::testAttachmentsModel()
  101. {
  102. auto entryAttachments = new EntryAttachments(this);
  103. auto model = new EntryAttachmentsModel(this);
  104. auto modelTest = new ModelTest(model, this);
  105. QCOMPARE(model->rowCount(), 0);
  106. model->setEntryAttachments(entryAttachments);
  107. QCOMPARE(model->rowCount(), 0);
  108. QSignalSpy spyDataChanged(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)));
  109. QSignalSpy spyAboutToAdd(model, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)));
  110. QSignalSpy spyAdded(model, SIGNAL(rowsInserted(QModelIndex, int, int)));
  111. QSignalSpy spyAboutToRemove(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)));
  112. QSignalSpy spyRemoved(model, SIGNAL(rowsRemoved(QModelIndex, int, int)));
  113. entryAttachments->set("first", QByteArray("123"));
  114. entryAttachments->set("2nd", QByteArray("456"));
  115. entryAttachments->set("2nd", QByteArray("7890"));
  116. const int firstRow = 0;
  117. QCOMPARE(model->data(model->index(firstRow, EntryAttachmentsModel::NameColumn)).toString(), QString("2nd"));
  118. QCOMPARE(model->data(model->index(firstRow, EntryAttachmentsModel::SizeColumn), Qt::EditRole).toInt(), 4);
  119. entryAttachments->remove("first");
  120. QCOMPARE(spyDataChanged.count(), 1);
  121. QCOMPARE(spyAboutToAdd.count(), 2);
  122. QCOMPARE(spyAdded.count(), 2);
  123. QCOMPARE(spyAboutToRemove.count(), 1);
  124. QCOMPARE(spyRemoved.count(), 1);
  125. QSignalSpy spyReset(model, SIGNAL(modelReset()));
  126. entryAttachments->clear();
  127. model->setEntryAttachments(nullptr);
  128. QCOMPARE(spyReset.count(), 2);
  129. QCOMPARE(model->rowCount(), 0);
  130. delete modelTest;
  131. delete model;
  132. delete entryAttachments;
  133. }
  134. void TestEntryModel::testAttributesModel()
  135. {
  136. auto entryAttributes = new EntryAttributes(this);
  137. auto model = new EntryAttributesModel(this);
  138. auto modelTest = new ModelTest(model, this);
  139. QCOMPARE(model->rowCount(), 0);
  140. model->setEntryAttributes(entryAttributes);
  141. QCOMPARE(model->rowCount(), 0);
  142. QSignalSpy spyDataChanged(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)));
  143. QSignalSpy spyAboutToAdd(model, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)));
  144. QSignalSpy spyAdded(model, SIGNAL(rowsInserted(QModelIndex, int, int)));
  145. QSignalSpy spyAboutToRemove(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)));
  146. QSignalSpy spyRemoved(model, SIGNAL(rowsRemoved(QModelIndex, int, int)));
  147. entryAttributes->set("first", "123");
  148. entryAttributes->set("2nd", "456");
  149. entryAttributes->set("2nd", "789");
  150. QCOMPARE(model->data(model->index(0, 0)).toString(), QString("2nd"));
  151. entryAttributes->remove("first");
  152. // make sure these don't generate messages
  153. entryAttributes->set("Title", "test");
  154. entryAttributes->set("Notes", "test");
  155. QCOMPARE(spyDataChanged.count(), 1);
  156. QCOMPARE(spyAboutToAdd.count(), 2);
  157. QCOMPARE(spyAdded.count(), 2);
  158. QCOMPARE(spyAboutToRemove.count(), 1);
  159. QCOMPARE(spyRemoved.count(), 1);
  160. // test attribute protection
  161. QString value = entryAttributes->value("2nd");
  162. entryAttributes->set("2nd", value, true);
  163. QVERIFY(entryAttributes->isProtected("2nd"));
  164. QCOMPARE(entryAttributes->value("2nd"), value);
  165. QSignalSpy spyReset(model, SIGNAL(modelReset()));
  166. entryAttributes->clear();
  167. model->setEntryAttributes(nullptr);
  168. QCOMPARE(spyReset.count(), 2);
  169. QCOMPARE(model->rowCount(), 0);
  170. delete modelTest;
  171. delete model;
  172. }
  173. void TestEntryModel::testDefaultIconModel()
  174. {
  175. auto model = new DefaultIconModel(this);
  176. auto modelTest = new ModelTest(model, this);
  177. QCOMPARE(model->rowCount(), databaseIcons()->count());
  178. delete modelTest;
  179. delete model;
  180. }
  181. void TestEntryModel::testCustomIconModel()
  182. {
  183. auto model = new CustomIconModel(this);
  184. auto modelTest = new ModelTest(model, this);
  185. QCOMPARE(model->rowCount(), 0);
  186. QHash<QUuid, QPixmap> icons;
  187. QList<QUuid> iconsOrder;
  188. QUuid iconUuid = QUuid::fromRfc4122(QByteArray(16, '2'));
  189. icons.insert(iconUuid, QPixmap());
  190. iconsOrder << iconUuid;
  191. QUuid iconUuid2 = QUuid::fromRfc4122(QByteArray(16, '1'));
  192. icons.insert(iconUuid2, QPixmap());
  193. iconsOrder << iconUuid2;
  194. model->setIcons(icons, iconsOrder);
  195. QCOMPARE(model->uuidFromIndex(model->index(0, 0)), iconUuid);
  196. QCOMPARE(model->uuidFromIndex(model->index(1, 0)), iconUuid2);
  197. delete modelTest;
  198. delete model;
  199. }
  200. void TestEntryModel::testAutoTypeAssociationsModel()
  201. {
  202. auto model = new AutoTypeAssociationsModel(this);
  203. auto modelTest = new ModelTest(model, this);
  204. QCOMPARE(model->rowCount(), 0);
  205. auto associations = new AutoTypeAssociations(this);
  206. model->setAutoTypeAssociations(associations);
  207. QCOMPARE(model->rowCount(), 0);
  208. AutoTypeAssociations::Association assoc;
  209. assoc.window = "1";
  210. assoc.sequence = "2";
  211. associations->add(assoc);
  212. QCOMPARE(model->rowCount(), 1);
  213. QCOMPARE(model->data(model->index(0, 0)).toString(), QString("1"));
  214. QCOMPARE(model->data(model->index(0, 1)).toString(), QString("2"));
  215. assoc.window = "3";
  216. assoc.sequence = "4";
  217. associations->update(0, assoc);
  218. QCOMPARE(model->data(model->index(0, 0)).toString(), QString("3"));
  219. QCOMPARE(model->data(model->index(0, 1)).toString(), QString("4"));
  220. associations->add(assoc);
  221. associations->remove(0);
  222. QCOMPARE(model->rowCount(), 1);
  223. delete modelTest;
  224. delete model;
  225. delete associations;
  226. }
  227. void TestEntryModel::testProxyModel()
  228. {
  229. auto modelSource = new EntryModel(this);
  230. auto modelProxy = new SortFilterHideProxyModel(this);
  231. modelProxy->setSourceModel(modelSource);
  232. auto modelTest = new ModelTest(modelProxy, this);
  233. auto db = new Database();
  234. auto entry = new Entry();
  235. entry->setTitle("Test Title");
  236. entry->setGroup(db->rootGroup());
  237. modelSource->setGroup(db->rootGroup());
  238. // Test hiding and showing a column
  239. auto columnCount = modelProxy->columnCount();
  240. QSignalSpy spyColumnRemove(modelProxy, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)));
  241. modelProxy->hideColumn(0, true);
  242. QCOMPARE(modelProxy->columnCount(), columnCount - 1);
  243. QVERIFY(!spyColumnRemove.isEmpty());
  244. int oldSpyColumnRemoveSize = spyColumnRemove.size();
  245. modelProxy->hideColumn(0, true);
  246. QCOMPARE(spyColumnRemove.size(), oldSpyColumnRemoveSize);
  247. modelProxy->hideColumn(100, true);
  248. QCOMPARE(spyColumnRemove.size(), oldSpyColumnRemoveSize);
  249. QList<Entry*> entryList;
  250. entryList << entry;
  251. modelSource->setEntries(entryList);
  252. QSignalSpy spyColumnInsert(modelProxy, SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)));
  253. modelProxy->hideColumn(0, false);
  254. QCOMPARE(modelProxy->columnCount(), columnCount);
  255. QVERIFY(!spyColumnInsert.isEmpty());
  256. int oldSpyColumnInsertSize = spyColumnInsert.size();
  257. modelProxy->hideColumn(0, false);
  258. QCOMPARE(spyColumnInsert.size(), oldSpyColumnInsertSize);
  259. delete modelTest;
  260. delete modelProxy;
  261. delete modelSource;
  262. delete db;
  263. }
  264. void TestEntryModel::testDatabaseDelete()
  265. {
  266. auto model = new EntryModel(this);
  267. auto modelTest = new ModelTest(model, this);
  268. auto db1 = new Database();
  269. auto group1 = new Group();
  270. group1->setParent(db1->rootGroup());
  271. auto entry1 = new Entry();
  272. entry1->setGroup(group1);
  273. auto db2 = new Database();
  274. auto entry2 = new Entry();
  275. entry2->setGroup(db2->rootGroup());
  276. model->setEntries(QList<Entry*>() << entry1 << entry2);
  277. QCOMPARE(model->rowCount(), 2);
  278. delete db1;
  279. QCOMPARE(model->rowCount(), 1);
  280. delete entry2;
  281. QCOMPARE(model->rowCount(), 0);
  282. delete db2;
  283. delete modelTest;
  284. delete model;
  285. }