db_tests.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. from pwman.util.callback import Callback
  2. from pwman.util.generator import leetlist
  3. import os
  4. import os.path
  5. import sys
  6. class DummyCallback(Callback):
  7. def getinput(self, question):
  8. return '12345'
  9. def getsecret(self, question):
  10. return '12345'
  11. class DummyCallback2(Callback):
  12. def getinput(self, question):
  13. return 'newsecret'
  14. def getsecret(self, question):
  15. return 'newsecret'
  16. if 'darwin' in sys.platform: # pragma: no cover
  17. from pwman.ui.mac import PwmanCliMacNew as PwmanCliNew
  18. OSX = True
  19. elif 'win' in sys.platform: # pragma: no cover
  20. from pwman.ui.win import PwmanCliWinNew as PwmanCliNew
  21. OSX = False
  22. else:
  23. from pwman.ui.cli import PwmanCliNew
  24. OSX = False
  25. import pwman.util.config as config
  26. import pwman.data.factory
  27. from pwman.data.nodes import NewNode
  28. from pwman.data.tags import Tag, TagNew
  29. from pwman.util.crypto import CryptoEngine, CryptoBadKeyException
  30. from pwman import which, default_config
  31. from pwman.ui.cli import get_pass_conf
  32. from pwman.ui.tools import CMDLoop, CliMenuItem
  33. import unittest
  34. from pwman.data import factory
  35. _saveconfig = False
  36. default_config['Database'] = {'type': 'SQLite',
  37. 'filename':
  38. os.path.join(os.path.dirname(__file__),
  39. "test.pwman.db")
  40. }
  41. class SetupTester(object):
  42. def __init__(self):
  43. config.set_defaults(default_config)
  44. if not OSX:
  45. self.xselpath = which("xsel")
  46. config.set_value("Global", "xsel", self.xselpath)
  47. else:
  48. self.xselpath = "xsel"
  49. def clean(self):
  50. if os.path.exists(config.get_value('Database', 'filename')):
  51. os.remove(config.get_value('Database', 'filename'))
  52. if os.path.exists(os.path.join(os.path.dirname(__file__),
  53. 'testing_config')):
  54. os.remove(os.path.join(os.path.dirname(__file__),
  55. 'testing_config'))
  56. def create(self):
  57. dbver = 0.4
  58. dbtype = config.get_value("Database", "type")
  59. db = pwman.data.factory.create(dbtype, dbver)
  60. self.cli = PwmanCliNew(db, self.xselpath, DummyCallback)
  61. class DBTests(unittest.TestCase):
  62. """test everything related to db"""
  63. def setUp(self):
  64. "test that the right db instance was created"
  65. dbver = 0.4
  66. self.dbtype = config.get_value("Database", "type")
  67. self.db = pwman.data.factory.create(self.dbtype, dbver)
  68. self.tester = SetupTester()
  69. self.tester.create()
  70. def test_db_created(self):
  71. "test that the right db instance was created"
  72. # self.db = pwman.data.factory.create(dbtype, dbver)
  73. self.assertIn(self.dbtype, self.db.__class__.__name__)
  74. def test_db_opened(self):
  75. "db was successfuly opened"
  76. # it will have a file name associated
  77. self.assertTrue(hasattr(self.db, '_filename'))
  78. def test_create_node(self):
  79. "test that a node can be successfuly created"
  80. # this method does not test do_new
  81. # which is a UI method, rather we test
  82. # _db.addnodes
  83. username = 'tester'
  84. password = 'Password'
  85. url = 'example.org'
  86. notes = 'some notes'
  87. node = NewNode(username, password, url, notes)
  88. tags = [Tag(tn) for tn in ['testing1', 'testing2']]
  89. node.tags = tags
  90. self.db.open()
  91. self.db.addnodes([node])
  92. idx_created = node._id
  93. new_node = self.db.getnodes([idx_created])[0]
  94. for key, attr in {'password': password, 'username': username,
  95. 'url': url, 'notes': notes}.iteritems():
  96. self.assertEquals(attr, getattr(new_node, key))
  97. self.db.close()
  98. def test_tags(self):
  99. enc = CryptoEngine.get()
  100. got_tags = self.tester.cli._tags(enc)
  101. self.assertEqual(2, len(got_tags))
  102. def test_change_pass(self):
  103. self.tester.cli.callback = DummyCallback2
  104. self.assertRaises(CryptoBadKeyException,
  105. self.tester.cli._db.changepassword)
  106. class CLITests(unittest.TestCase):
  107. """
  108. test command line functionallity
  109. """
  110. def setUp(self):
  111. "test that the right db instance was created"
  112. dbver = 0.4
  113. self.dbtype = config.get_value("Database", "type")
  114. self.db = pwman.data.factory.create(self.dbtype, dbver)
  115. self.tester = SetupTester()
  116. self.tester.create()
  117. def test_input(self):
  118. name = self.tester.cli.get_username(reader=lambda: u'alice')
  119. self.assertEqual(name, u'alice')
  120. def test_password(self):
  121. password = self.tester.cli.get_password(None,
  122. reader=lambda x: u'hatman')
  123. self.assertEqual(password, u'hatman')
  124. def test_random_password(self):
  125. password = self.tester.cli.get_password(None, length=7)
  126. self.assertEqual(len(password), 7)
  127. def test_random_leet_password(self):
  128. password = self.tester.cli.get_password(None, leetify=True, length=7)
  129. l_num = 0
  130. for v in leetlist.values():
  131. if v in password:
  132. l_num += 1
  133. self.assertTrue(l_num > 0)
  134. def test_leet_password(self):
  135. password = self.tester.cli.get_password(None, leetify=True,
  136. reader=lambda x: u'HAtman')
  137. print password
  138. self.assertRegexpMatches(password, ("(H|h)?(A|a|4)?(T|t|\+)?(m|M|\|"
  139. "\/\|)?(A|a|4)?(N|n|\|\\|)?"))
  140. def test_get_url(self):
  141. url = self.tester.cli.get_url(reader=lambda: u'example.com')
  142. self.assertEqual(url, u'example.com')
  143. def test_get_notes(self):
  144. notes = self.tester.cli.get_notes(reader=lambda:
  145. u'test 123\n test 456')
  146. self.assertEqual(notes, u'test 123\n test 456')
  147. def test_get_tags(self):
  148. tags = self.tester.cli.get_tags(reader=lambda: u'looking glass')
  149. for t in tags:
  150. self.assertIsInstance(t, TagNew)
  151. for t, n in zip(tags, 'looking glass'.split()):
  152. self.assertEqual(t.name.strip(), n)
  153. # creating all the components of the node does
  154. # the node is still not added !
  155. def test_add_new_entry(self):
  156. node = NewNode('alice', 'dough!', 'example.com',
  157. 'lorem impsum')
  158. tags = self.tester.cli.get_tags(reader=lambda: u'looking glass')
  159. node.tags = tags
  160. self.tester.cli._db.addnodes([node])
  161. self.tester.cli._db._cur.execute(
  162. "SELECT ID FROM NODES ORDER BY ID ASC", [])
  163. rows = self.tester.cli._db._cur.fetchall()
  164. # by now the db should have 2 new nodes
  165. # the first one was added by test_create_node in DBTests
  166. # the second was added just now.
  167. # This will pass only when running all the tests than ...
  168. self.assertEqual(len(rows), 2)
  169. def test_get_ids(self):
  170. #used by do_cp or do_open,
  171. # this spits many time could not understand your input
  172. self.assertEqual([1], self.tester.cli.get_ids('1'))
  173. self.assertListEqual([1, 2, 3, 4, 5], self.tester.cli.get_ids('1-5'))
  174. self.assertListEqual([], self.tester.cli.get_ids('5-1'))
  175. self.assertListEqual([], self.tester.cli.get_ids('5x-1'))
  176. self.assertListEqual([], self.tester.cli.get_ids('5x'))
  177. self.assertListEqual([], self.tester.cli.get_ids('5\\'))
  178. def test_edit(self):
  179. node = self.tester.cli._db.getnodes([2])[0]
  180. menu = CMDLoop()
  181. menu.add(CliMenuItem("Username", self.tester.cli.get_username,
  182. node.username,
  183. node.username))
  184. menu.add(CliMenuItem("Password", self.tester.cli.get_password,
  185. node.password,
  186. node.password))
  187. menu.add(CliMenuItem("Url", self.tester.cli.get_url,
  188. node.url,
  189. node.url))
  190. menunotes = CliMenuItem("Notes",
  191. self.tester.cli.get_notes(reader=lambda:
  192. u'bla bla'),
  193. node.notes,
  194. node.notes)
  195. menu.add(menunotes)
  196. menu.add(CliMenuItem("Tags", self.tester.cli.get_tags,
  197. node.tags,
  198. node.tags))
  199. import StringIO
  200. s = StringIO.StringIO("4\nX")
  201. sys.stdin = s
  202. menu.run(node)
  203. def test_get_pass_conf(self):
  204. numerics, leet, s_chars = get_pass_conf()
  205. self.assertFalse(numerics)
  206. self.assertFalse(leet)
  207. self.assertFalse(s_chars)
  208. def test_do_exit(self):
  209. self.assertTrue(self.tester.cli.do_exit(''))
  210. class FactoryTest(unittest.TestCase):
  211. def test_factory_check_db_ver(self):
  212. self.assertEquals(factory.check_db_version('SQLite'), u"'0.4'")
  213. class ConfigTest(unittest.TestCase):
  214. def setUp(self):
  215. "test that the right db instance was created"
  216. dbver = 0.4
  217. self.dbtype = config.get_value("Database", "type")
  218. self.db = pwman.data.factory.create(self.dbtype, dbver)
  219. self.tester = SetupTester()
  220. self.tester.create()
  221. def test_config_write(self):
  222. _filename = os.path.join(os.path.dirname(__file__),
  223. 'testing_config')
  224. config._file = _filename
  225. config.save(_filename)
  226. self.assertTrue(_filename)
  227. os.remove(_filename)
  228. def test_config_write_with_none(self):
  229. _filename = os.path.join(os.path.dirname(__file__),
  230. 'testing_config')
  231. config._file = _filename
  232. config.save()
  233. self.assertTrue(os.path.exists(_filename))
  234. os.remove(_filename)
  235. def test_write_no_permission(self):
  236. # this test will pass if you run as root ...
  237. # assuming you are not doing something like that
  238. self.assertRaises(config.ConfigException, config.save,
  239. '/root/test_config')
  240. def test_add_default(self):
  241. config.add_defaults({'Section1': {'name': 'value'}})
  242. self.assertIn('Section1', config._defaults)
  243. def test_get_conf(self):
  244. cnf = config.get_conf()
  245. cnf_keys = cnf.keys()
  246. self.assertTrue('Encryption' in cnf_keys)
  247. self.assertTrue('Readline' in cnf_keys)
  248. self.assertTrue('Global' in cnf_keys)
  249. self.assertTrue('Database' in cnf_keys)
  250. def test_load_conf(self):
  251. self.assertRaises(config.ConfigException, config.load, 'NoSuchFile')
  252. # Everything should be ok
  253. config.save('TestConfig.ini')
  254. config.load('TestConfig.ini')
  255. # let's corrupt the file
  256. cfg = open('TestConfig.ini', 'w')
  257. cfg.write('Corruption')
  258. cfg.close()
  259. self.assertRaises(config.ConfigException, config.load,
  260. 'TestConfig.ini')
  261. os.remove('TestConfig.ini')