Erik Grinaker is sharing code with you

Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.

Don't show this again

erikg / Revelation

Revelation is a password manager for the GNOME desktop, released under the GNU GPL license. It stores all your accounts and passwords in a single, secure place, and gives you access to it through a user-friendly graphical interface.

Clone this repository (size: 2.1 MB): HTTPS / SSH
hg clone https://bitbucket.org/erikg/revelation
hg clone ssh://hg@bitbucket.org/erikg/revelation

Revelation / test / datahandler_fpm.py

commit
cff0e6f7ef34
parent
e0a14b958359
branch
default
tags
revelation-0.4.0-pre2

bumped version number to 0.4.0-pre2

1
63404ea62808
#!/usr/bin/env python
2
63404ea62808
3
63404ea62808
#
4
b6047522c64d
# Revelation 0.4.0 - a password manager for GNOME 2
5
63404ea62808
# http://oss.codepoet.no/revelation/
6
b6047522c64d
# $Id$
7
63404ea62808
#
8
63404ea62808
# Unit tests for FPM datahandler module
9
63404ea62808
#
10
63404ea62808
#
11
07c1fb2b0c27
# Copyright (c) 2003-2005 Erik Grinaker
12
63404ea62808
#
13
63404ea62808
# This program is free software; you can redistribute it and/or
14
63404ea62808
# modify it under the terms of the GNU General Public License
15
63404ea62808
# as published by the Free Software Foundation; either version 2
16
63404ea62808
# of the License, or (at your option) any later version.
17
63404ea62808
#
18
63404ea62808
# This program is distributed in the hope that it will be useful,
19
63404ea62808
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
63404ea62808
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
63404ea62808
# GNU General Public License for more details.
22
63404ea62808
#
23
63404ea62808
# You should have received a copy of the GNU General Public License
24
63404ea62808
# along with this program; if not, write to the Free Software
25
63404ea62808
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26
63404ea62808
#
27
63404ea62808
28
63404ea62808
import unittest, xml.dom.minidom
29
63404ea62808
30
63404ea62808
from revelation import data, datahandler, entry, util
31
63404ea62808
32
63404ea62808
33
63404ea62808
class FPM(unittest.TestCase):
34
63404ea62808
	"FPM"
35
63404ea62808
36
63404ea62808
	def test_attrs(self):
37
63404ea62808
		"FPM has sane attributes"
38
63404ea62808
39
63404ea62808
		self.assertNotEqual(datahandler.FPM.name, "")
40
63404ea62808
		self.assertEqual(datahandler.FPM.importer, True)
41
63404ea62808
		self.assertEqual(datahandler.FPM.exporter, True)
42
63404ea62808
		self.assertEqual(datahandler.FPM.encryption, True)
43
63404ea62808
44
63404ea62808
45
63404ea62808
46
63404ea62808
class FPM_check(unittest.TestCase):
47
63404ea62808
	"FPM.check()"
48
63404ea62808
49
63404ea62808
50
63404ea62808
	def test_inv_baseattrs(self):
51
63404ea62808
		"FPM.check() raises FormatError on missing base attributes"
52
63404ea62808
53
63404ea62808
		xml = """
54
63404ea62808
<?xml version="1.0" ?>
55
63404ea62808
<FPM>
56
63404ea62808
</FPM>
57
63404ea62808
"""
58
63404ea62808
59
63404ea62808
		handler = datahandler.FPM()
60
63404ea62808
		self.assertRaises(datahandler.FormatError, handler.check, xml)
61
63404ea62808
62
63404ea62808
63
63404ea62808
64
63404ea62808
	def test_inv_root(self):
65
63404ea62808
		"FPM.check() raises FormatError on wrong root element"
66
63404ea62808
67
63404ea62808
		xml = """
68
63404ea62808
<?xml version="1.0" ?>
69
63404ea62808
<FPMDATA full_version="00.58.00" min_version="00.58.00" display_version="00.58.00">
70
63404ea62808
</FPMDATA>
71
63404ea62808
"""
72
63404ea62808
73
63404ea62808
		handler = datahandler.FPM()
74
63404ea62808
		self.assertRaises(datahandler.FormatError, handler.check, xml)
75
63404ea62808
76
63404ea62808
77
63404ea62808
	def test_inv_version(self):
78
63404ea62808
		"FPM.check() raises VersionError on invalid version"
79
63404ea62808
80
63404ea62808
		xml = """
81
63404ea62808
<?xml version="1.0" ?>
82
63404ea62808
<FPM full_version="00.60.00" min_version="00.60.00" display_version="00.60.00">
83
63404ea62808
</FPM>
84
63404ea62808
"""
85
63404ea62808
86
63404ea62808
		handler = datahandler.FPM()
87
63404ea62808
		self.assertRaises(datahandler.VersionError, handler.check, xml)
88
63404ea62808
89
63404ea62808
90
63404ea62808
	def test_inv_version_format(self):
91
63404ea62808
		"FPM.check() raises FormatError on invalid version format"
92
63404ea62808
93
63404ea62808
		xml = """
94
63404ea62808
<?xml version="1.0" ?>
95
63404ea62808
<FPM full_version="00.58.00" min_version="jeje123" display_version="00.58.00">
96
63404ea62808
</FPM>
97
63404ea62808
"""
98
63404ea62808
99
63404ea62808
		handler = datahandler.FPM()
100
63404ea62808
		self.assertRaises(datahandler.FormatError, handler.check, xml)
101
63404ea62808
102
63404ea62808
103
63404ea62808
	def test_inv_xml(self):
104
63404ea62808
		"FPM.check() raises FormatError on invalid XML"
105
63404ea62808
106
63404ea62808
		xml = """
107
63404ea62808
<?xml version="1.0" ?>
108
63404ea62808
<FPM full_version="00.58.00" min_version="00.58.00" display_version="00.58.00">
109
63404ea62808
</FPMDATA>
110
63404ea62808
"""
111
63404ea62808
112
63404ea62808
		handler = datahandler.FPM()
113
63404ea62808
		self.assertRaises(datahandler.FormatError, handler.check, xml)
114
63404ea62808
115
63404ea62808
116
63404ea62808
	def test_none(self):
117
63404ea62808
		"FPM.check() raises FormatError on None"
118
63404ea62808
119
63404ea62808
		handler = datahandler.FPM()
120
63404ea62808
		self.assertRaises(datahandler.FormatError, handler.check, None)
121
63404ea62808
122
63404ea62808
123
63404ea62808
	def test_valid(self):
124
63404ea62808
		"FPM.check() accepts valid data"
125
63404ea62808
126
63404ea62808
		xml = """
127
63404ea62808
<?xml version="1.0" ?>
128
63404ea62808
<FPM full_version="00.58.00" min_version="00.58.00" display_version="00.58.00">
129
63404ea62808
</FPM>
130
63404ea62808
"""
131
63404ea62808
132
63404ea62808
		handler = datahandler.FPM()
133
63404ea62808
		handler.check(xml)
134
63404ea62808
135
63404ea62808
136
63404ea62808
class FPM_detect(unittest.TestCase):
137
63404ea62808
	"FPM.detect()"
138
63404ea62808
139
63404ea62808
	def test_inv(self):
140
63404ea62808
		"FPM.detect() rejects invalid data"
141
63404ea62808
142
63404ea62808
		handler = datahandler.FPM()
143
63404ea62808
		self.assertEqual(handler.detect("dummydata"), False)
144
63404ea62808
145
63404ea62808
146
63404ea62808
	def test_inv_version(self):
147
63404ea62808
		"FPM.detect() rejects invalid version"
148
63404ea62808
149
63404ea62808
		xml = """
150
63404ea62808
<?xml version="1.0" ?>
151
63404ea62808
<FPM full_version="00.60.00" min_version="00.60.00" display_version="00.60.00">
152
63404ea62808
</FPM>
153
63404ea62808
"""
154
63404ea62808
155
63404ea62808
		handler = datahandler.FPM()
156
63404ea62808
		self.assertEqual(handler.detect(xml), False)
157
63404ea62808
158
63404ea62808
159
63404ea62808
	def test_none(self):
160
63404ea62808
		"FPM.detect() rejects None"
161
63404ea62808
162
63404ea62808
		handler = datahandler.FPM()
163
63404ea62808
		self.assertEqual(handler.detect(None), False)
164
63404ea62808
165
63404ea62808
166
63404ea62808
	def test_valid(self):
167
63404ea62808
		"FPM.detect() accepts valid data"
168
63404ea62808
169
63404ea62808
		xml = """
170
63404ea62808
<?xml version="1.0" ?>
171
63404ea62808
<FPM full_version="00.58.00" min_version="00.58.00" display_version="00.58.00">
172
63404ea62808
</FPM>
173
63404ea62808
"""
174
63404ea62808
175
63404ea62808
		handler = datahandler.FPM()
176
63404ea62808
		self.assertEqual(handler.detect(xml), True)
177
63404ea62808
178
63404ea62808
179
63404ea62808
180
63404ea62808
class FPM_export_data(unittest.TestCase):
181
63404ea62808
	"FPM.export_data()"
182
63404ea62808
183
63404ea62808
	def test_valid(self):
184
63404ea62808
		"FPM.export_data() generates valid data"
185
63404ea62808
186
63404ea62808
		# set up data
187
63404ea62808
		entrystore = data.EntryStore()
188
63404ea62808
189
63404ea62808
		e = entry.FolderEntry()
190
63404ea62808
		e.name = "Testfolder"
191
63404ea62808
		e.description = "Just a test folder"
192
63404ea62808
193
f98d1213af7a
		folderiter = entrystore.add_entry(e)
194
63404ea62808
195
63404ea62808
		e = entry.GenericEntry()
196
63404ea62808
		e.name = "Generic child"
197
63404ea62808
		e.description = "Child-entry"
198
63404ea62808
		e.get_field(entry.HostnameField).value = "www.slashdot.org"
199
63404ea62808
		e.get_field(entry.UsernameField).value = "erikg"
200
63404ea62808
		e.get_field(entry.PasswordField).value = "test123"
201
63404ea62808
202
f98d1213af7a
		entrystore.add_entry(e, folderiter)
203
63404ea62808
204
63404ea62808
		e = entry.WebEntry()
205
63404ea62808
		e.name = "A website entry"
206
63404ea62808
		e.get_field(entry.URLField).value = "http://www.kuro5hin.org/"
207
63404ea62808
		e.get_field(entry.UsernameField).value = "egrinake"
208
63404ea62808
		e.get_field(entry.PasswordField).value = "pwtest"
209
f98d1213af7a
		entrystore.add_entry(e)
210
63404ea62808
211
63404ea62808
212
63404ea62808
		# test the export
213
63404ea62808
		handler = datahandler.FPM()
214
63404ea62808
		fpmdata = handler.export_data(entrystore, "test")
215
63404ea62808
216
63404ea62808
		dom = xml.dom.minidom.parseString(fpmdata)
217
63404ea62808
		itemnodes = dom.getElementsByTagName("PasswordItem")
218
63404ea62808
219
63404ea62808
		entrydata = {}
220
63404ea62808
		for childnode in [ node for node in itemnodes[0].childNodes if node.nodeType == node.ELEMENT_NODE ]:
221
63404ea62808
			entrydata[childnode.nodeName] = util.dom_text(childnode)
222
63404ea62808
223
63404ea62808
		fe = entrystore.get_entry(folderiter)
224
63404ea62808
		e = entrystore.get_entry(entrystore.iter_nth_child(folderiter, 0))
225
63404ea62808
226
63404ea62808
		self.assertEqual(e.name, entrydata["title"])
227
63404ea62808
		self.assertEqual(e.description, entrydata["notes"])
228
63404ea62808
		self.assertEqual(fe.name, entrydata["category"])
229
63404ea62808
		self.assertEqual(e.get_field(entry.HostnameField).value, entrydata["url"])
230
63404ea62808
		self.assertEqual(e.get_field(entry.UsernameField).value, entrydata["user"])
231
63404ea62808
		self.assertEqual(e.get_field(entry.PasswordField).value, entrydata["password"])
232
63404ea62808
233
63404ea62808
234
63404ea62808
		entrydata = {}
235
63404ea62808
		for childnode in [ node for node in itemnodes[1].childNodes if node.nodeType == node.ELEMENT_NODE ]:
236
63404ea62808
			entrydata[childnode.nodeName] = util.dom_text(childnode)
237
63404ea62808
238
63404ea62808
		e = entrystore.get_entry(entrystore.iter_nth_child(None, 1))
239
63404ea62808
240
63404ea62808
		self.assertEqual(e.name, entrydata["title"])
241
63404ea62808
		self.assertEqual(e.description, entrydata["notes"])
242
63404ea62808
		self.assertEqual("", entrydata["category"])
243
63404ea62808
		self.assertEqual(e.get_field(entry.URLField).value, entrydata["url"])
244
63404ea62808
		self.assertEqual(e.get_field(entry.UsernameField).value, entrydata["user"])
245
63404ea62808
		self.assertEqual(e.get_field(entry.PasswordField).value, entrydata["password"])
246
63404ea62808
247
63404ea62808
248
63404ea62808
249
63404ea62808
250
63404ea62808
class FPM_import_data(unittest.TestCase):
251
63404ea62808
	"FPM.import_data()"
252
63404ea62808
253
63404ea62808
	def test_inv_password(self):
254
63404ea62808
		"FPM.import_data() raises PasswordError on invalid password"
255
63404ea62808
256
63404ea62808
		xml = """
257
63404ea62808
<?xml version="1.0" ?>
258
63404ea62808
<FPM full_version="00.58.00" min_version="00.58.00" display_version="0.58">
259
63404ea62808
	<KeyInfo salt="imljjkpg" vstring="ofnabdkjbmopgaha"/>
260
63404ea62808
</FPM>
261
63404ea62808
"""
262
63404ea62808
263
63404ea62808
		handler = datahandler.FPM()
264
63404ea62808
		self.assertRaises(datahandler.PasswordError, handler.import_data, xml, "wrongpw")
265
63404ea62808
266
63404ea62808
267
63404ea62808
	def test_nodata(self):
268
63404ea62808
		"FPM.import_data() handles empty data"
269
63404ea62808
270
63404ea62808
		xml = """
271
63404ea62808
<?xml version="1.0" ?>
272
63404ea62808
<FPM full_version="00.58.00" min_version="00.58.00" display_version="0.58">
273
63404ea62808
	<KeyInfo salt="imljjkpg" vstring="ofnabdkjbmopgaha"/>
274
63404ea62808
</FPM>
275
63404ea62808
"""
276
63404ea62808
277
63404ea62808
		handler = datahandler.FPM()
278
63404ea62808
		handler.import_data(xml, "test")
279
63404ea62808
280
63404ea62808
281
63404ea62808
	def test_none(self):
282
63404ea62808
		"FPM.import_data() raises FormatError on None"
283
63404ea62808
284
63404ea62808
		handler = datahandler.FPM()
285
63404ea62808
		self.assertRaises(datahandler.FormatError, handler.import_data, None, "test")
286
63404ea62808
287
63404ea62808
288
63404ea62808
	def test_valid(self):
289
63404ea62808
		"FPM.import_data() accepts valid data"
290
63404ea62808
291
63404ea62808
		xml = """
292
63404ea62808
<?xml version="1.0" ?>
293
63404ea62808
<FPM full_version="00.58.00" min_version="00.58.00" display_version="0.58">
294
63404ea62808
	<KeyInfo salt="ncppipdn" vstring="poadhodhplbegpjm"/>
295
63404ea62808
	<LauncherList>
296
63404ea62808
		<LauncerItem><title>Web</title><cmdline>gnome-moz-remote "$a"</cmdline><copy_user>2</copy_user><copy_password>1</copy_password></LauncerItem>
297
63404ea62808
		<LauncerItem><title>ssh</title><cmdline>gnome-terminal -e 'ssh $a -l $u'</cmdline><copy_user>0</copy_user><copy_password>1</copy_password></LauncerItem>
298
63404ea62808
		<LauncerItem><title>Generic Command</title><cmdline>$a</cmdline><copy_user>0</copy_user><copy_password>0</copy_password></LauncerItem>
299
63404ea62808
	</LauncherList>
300
63404ea62808
	<PasswordList>
301
63404ea62808
		<PasswordItem><title>noogeghgacbjkembbkcndhfmnpomakao</title><user>lidannbdlfpgbbhmhcfkjcnegceimapi</user><url>nhdlpgkdickpaoafapcflihmlfopckkapnaolgoglkfmkpjg</url><password>dnijaohfckjnddgpggjhfiienhgccmejnpbgddffgkiflhocilchedanbdecjfpnpmmjapijikapecnjfgaheppnjkhiacdmkndocanomelohfhadcmhcdddcjdmghaoicogbopbgchbnakiombpmbmlgkillcebkcpjpdcpdmalcgkccmmfbpeikhlfbacmlogopgdilpndajkbhhiflmbgblkonhpldfihmooajlodnogikgiehkaneeecfblaclikhedihkfhcpdalmaphohijmfaagliladeecchlbfbokfeikjbbpcgaegcjplpcalembmigjppbjlolbcempdpoibgiblhgmcbpmidbnickamieedfgigeenpmaoflmaddhoemmpbiplpgnnfamcebhompngcdpfonpkgnfkpgdognneongealocmfimfdnpcgjppmndhcfcnabjfmpehlfpfjanmjccfelbjfdlgldiimnahjjhfcmlgbjnpk</password><notes>iihkgjebgnghghhm</notes><category>gjnkbgnchgehiajb</category><launcher>dnajoaniehgnljed</launcher></PasswordItem>
302
63404ea62808
		<PasswordItem><title>kofckpmcobmpoiamdhhogkdinpkihfkh</title><user>paljgfjdncoelohf</user><url>iamoledhnphfppocmccppepcflkinibbhlfpbfgifpijdceeohkacpbdkjcpmlnj</url><password>jpcdkgikeoojckbahdjdnhfpebmbndmbcajnajpfgdpfjemjnmeleaenkmmnonpelajpempdacmgmflnpcccafgagacmnkkiknbdkcfmbelgpdemcpojgibjoiiaccncjhleebhfgodknfajemlmidcnicppfkhkmbacmfpgkheplcjaejgmkokilfcclenfjinmlaijnahjbhiafjkcjnfffknahgifjhcmdlmgjggjdcojnhoadjaeobjjgpgicopmkckkaonbccopcocdbemdocingpeiehaocdmkkclpklegabpobjalijehnmfklicldndpcenbklnobjcjeeigknodicmlffnejfgcbhedmogipbfbfobmcaeoodpgnojbjfcpjdljgmbdingphkjeibpcomgfdgknigejailonledhgnmopcpocaiammlldkfgankgjheioaaejffmohhefgiagkflaednjogjogknchnjgfjkidkhheclllh</password><notes>njpmfmbdaohdckpgapbgmkjpbpibfnkfakckalefcipcmfahhljcdkmdppdnbkaefcdlpcjjhhmlcgin</notes><category>kgalgbjejfamgdbo</category><launcher>phmnfgmbhmnjanbc</launcher></PasswordItem>
303
63404ea62808
	</PasswordList>
304
63404ea62808
</FPM>
305
63404ea62808
"""
306
63404ea62808
307
63404ea62808
		handler = datahandler.FPM()
308
63404ea62808
		entrystore = handler.import_data(xml, "test")
309
63404ea62808
310
63404ea62808
		folderiter = entrystore.iter_nth_child(None, 0)
311
63404ea62808
		folderentry = entrystore.get_entry(folderiter)
312
63404ea62808
313
63404ea62808
		self.assertEqual(type(folderentry), entry.FolderEntry)
314
63404ea62808
		self.assertEqual(folderentry.name, "web")
315
63404ea62808
		self.assertNotEqual(folderentry.updated, 0)
316
63404ea62808
317
63404ea62808
		e = entrystore.get_entry(entrystore.iter_nth_child(folderiter, 0))
318
63404ea62808
		self.assertEqual(type(e), entry.GenericEntry)
319
63404ea62808
		self.assertEqual(e.name, "kuro5hin")
320
63404ea62808
		self.assertEqual(e.description, "")
321
63404ea62808
		self.assertNotEqual(e.updated, 0)
322
63404ea62808
		self.assertEqual(e.get_field(entry.UsernameField).value, "egrinake")
323
63404ea62808
		self.assertEqual(e.get_field(entry.HostnameField).value, "www.kuro5hin.org")
324
63404ea62808
		self.assertEqual(e.get_field(entry.PasswordField).value, "jeje")
325
63404ea62808
326
63404ea62808
		e = entrystore.get_entry(entrystore.iter_nth_child(folderiter, 1))
327
63404ea62808
		self.assertEqual(type(e), entry.GenericEntry)
328
63404ea62808
		self.assertEqual(e.name, "slashdot")
329
63404ea62808
		self.assertEqual(e.description, "Username and password for /.")
330
63404ea62808
		self.assertNotEqual(e.updated, 0)
331
63404ea62808
		self.assertEqual(e.get_field(entry.UsernameField).value, "erikg")
332
63404ea62808
		self.assertEqual(e.get_field(entry.HostnameField).value, "http://www.slashdot.org/")
333
63404ea62808
		self.assertEqual(e.get_field(entry.PasswordField).value, "test")
334
63404ea62808
335
63404ea62808
336
63404ea62808
337
63404ea62808
if __name__ == "__main__":
338
63404ea62808
	unittest.main()