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_rvl.py

commit
c612387bf775
parent
d1c13e095736
branch
default
tags
revelation-0.4.0

fixed typo in python path checks

1
500cdfa073b3
#!/usr/bin/env python
2
500cdfa073b3
3
500cdfa073b3
#
4
b6047522c64d
# Revelation 0.4.0 - a password manager for GNOME 2
5
500cdfa073b3
# http://oss.codepoet.no/revelation/
6
b6047522c64d
# $Id$
7
500cdfa073b3
#
8
500cdfa073b3
# Unit tests for Revelation DataHandler module
9
500cdfa073b3
#
10
500cdfa073b3
#
11
07c1fb2b0c27
# Copyright (c) 2003-2005 Erik Grinaker
12
500cdfa073b3
#
13
500cdfa073b3
# This program is free software; you can redistribute it and/or
14
500cdfa073b3
# modify it under the terms of the GNU General Public License
15
500cdfa073b3
# as published by the Free Software Foundation; either version 2
16
500cdfa073b3
# of the License, or (at your option) any later version.
17
500cdfa073b3
#
18
500cdfa073b3
# This program is distributed in the hope that it will be useful,
19
500cdfa073b3
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
500cdfa073b3
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
500cdfa073b3
# GNU General Public License for more details.
22
500cdfa073b3
#
23
500cdfa073b3
# You should have received a copy of the GNU General Public License
24
500cdfa073b3
# along with this program; if not, write to the Free Software
25
500cdfa073b3
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26
500cdfa073b3
#
27
500cdfa073b3
28
500cdfa073b3
import unittest, re, xml.dom.minidom
29
500cdfa073b3
30
500cdfa073b3
from revelation import data, datahandler, entry
31
500cdfa073b3
32
500cdfa073b3
33
500cdfa073b3
34
500cdfa073b3
class RevelationXML(unittest.TestCase):
35
500cdfa073b3
	"RevelationXML"
36
500cdfa073b3
37
500cdfa073b3
	def test_attrs(self):
38
500cdfa073b3
		"RevelationXML has sane attributes"
39
500cdfa073b3
40
500cdfa073b3
		self.assertNotEqual(datahandler.RevelationXML.name, "")
41
500cdfa073b3
		self.assertEqual(datahandler.RevelationXML.importer, True)
42
500cdfa073b3
		self.assertEqual(datahandler.RevelationXML.exporter, True)
43
500cdfa073b3
		self.assertEqual(datahandler.RevelationXML.encryption, False)
44
500cdfa073b3
45
500cdfa073b3
46
500cdfa073b3
47
500cdfa073b3
class RevelationXML_check(unittest.TestCase):
48
500cdfa073b3
	"RevelationXML.check()"
49
500cdfa073b3
50
500cdfa073b3
	def test_inv_dataversion(self):
51
500cdfa073b3
		"RevelationXML.check() raises VersionError on invalid version"
52
500cdfa073b3
53
500cdfa073b3
		handler = datahandler.RevelationXML()
54
500cdfa073b3
55
500cdfa073b3
		xml = """
56
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
57
500cdfa073b3
<revelationdata dataversion="2">
58
500cdfa073b3
</revelationdata>
59
500cdfa073b3
"""
60
500cdfa073b3
61
500cdfa073b3
		self.assertRaises(datahandler.VersionError, handler.check, xml)
62
500cdfa073b3
63
500cdfa073b3
64
500cdfa073b3
	def test_inv_docelement(self):
65
500cdfa073b3
		"RevelationXML.check() rejects invalid document element"
66
500cdfa073b3
67
500cdfa073b3
		handler = datahandler.RevelationXML()
68
500cdfa073b3
69
500cdfa073b3
		xml = """
70
500cdfa073b3
<?xml version="1.0" ?>
71
500cdfa073b3
<revelation>
72
500cdfa073b3
</revelation>
73
500cdfa073b3
"""
74
500cdfa073b3
75
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.check, xml)
76
500cdfa073b3
77
500cdfa073b3
78
500cdfa073b3
	def test_inv_xmlheader(self):
79
500cdfa073b3
		"RevelationXML.check() rejects invalid header"
80
500cdfa073b3
81
500cdfa073b3
		handler = datahandler.RevelationXML()
82
500cdfa073b3
83
500cdfa073b3
		xml = """
84
500cdfa073b3
<xml version="1.0" ?>
85
500cdfa073b3
<revelationdata dataversion="1">
86
500cdfa073b3
</revelationdata>
87
500cdfa073b3
"""
88
500cdfa073b3
89
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.check, xml)
90
500cdfa073b3
91
500cdfa073b3
92
500cdfa073b3
	def test_none(self):
93
500cdfa073b3
		"RevelationXML.check() handles None"
94
500cdfa073b3
95
500cdfa073b3
		handler = datahandler.RevelationXML()
96
500cdfa073b3
97
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.check, None)
98
500cdfa073b3
99
500cdfa073b3
100
500cdfa073b3
	def test_valid(self):
101
500cdfa073b3
		"RevelationXML.check() accepts valid input"
102
500cdfa073b3
103
500cdfa073b3
		handler = datahandler.RevelationXML()
104
500cdfa073b3
105
500cdfa073b3
		xml = """
106
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
107
500cdfa073b3
<revelationdata dataversion="1">
108
500cdfa073b3
</revelationdata>
109
500cdfa073b3
"""
110
500cdfa073b3
111
500cdfa073b3
		self.assertEqual(handler.check(xml), None)
112
500cdfa073b3
113
500cdfa073b3
114
500cdfa073b3
115
500cdfa073b3
class RevelationXML_detect(unittest.TestCase):
116
500cdfa073b3
	"RevelationXML.detect()"
117
500cdfa073b3
118
500cdfa073b3
	def test_inv(self):
119
500cdfa073b3
		"RevelationXML.detect() rejects invalid input"
120
500cdfa073b3
121
500cdfa073b3
		handler = datahandler.RevelationXML()
122
500cdfa073b3
123
500cdfa073b3
		self.assertEqual(handler.detect("dummydata"), False)
124
500cdfa073b3
125
500cdfa073b3
126
500cdfa073b3
	def test_inv_version(self):
127
500cdfa073b3
		"RevelationXML.detect() rejects invalid version"
128
500cdfa073b3
129
500cdfa073b3
		handler = datahandler.RevelationXML()
130
500cdfa073b3
131
500cdfa073b3
		xml = """
132
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
133
500cdfa073b3
<revelationdata dataversion="2">
134
500cdfa073b3
</revelationdata>
135
500cdfa073b3
136
500cdfa073b3
"""
137
500cdfa073b3
138
500cdfa073b3
		self.assertEquals(handler.detect(xml), False)
139
500cdfa073b3
140
500cdfa073b3
141
500cdfa073b3
	def test_none(self):
142
500cdfa073b3
		"RevelationXML.detect() handles None"
143
500cdfa073b3
144
500cdfa073b3
		handler = datahandler.RevelationXML()
145
500cdfa073b3
146
500cdfa073b3
		self.assertEquals(handler.detect(None), False)
147
500cdfa073b3
148
500cdfa073b3
149
500cdfa073b3
	def test_valid(self):
150
500cdfa073b3
		"RevelationXML.detect() detects valid input"
151
500cdfa073b3
152
500cdfa073b3
		handler = datahandler.RevelationXML()
153
500cdfa073b3
154
500cdfa073b3
		xml = """
155
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
156
500cdfa073b3
<revelationdata dataversion="1">
157
500cdfa073b3
</revelationdata>
158
500cdfa073b3
"""
159
500cdfa073b3
160
500cdfa073b3
		self.assertEqual(handler.detect(xml), True)
161
500cdfa073b3
162
500cdfa073b3
163
500cdfa073b3
164
500cdfa073b3
class RevelationXML_export_data(unittest.TestCase):
165
500cdfa073b3
	"RevelationXML.export_data()"
166
500cdfa073b3
167
500cdfa073b3
	def test_entrydata(self):
168
500cdfa073b3
		"RevelationXML.export_data() exports all entry data"
169
500cdfa073b3
170
500cdfa073b3
		handler = datahandler.RevelationXML()
171
500cdfa073b3
		entrystore = data.EntryStore()
172
500cdfa073b3
173
500cdfa073b3
		e = entry.GenericEntry()
174
500cdfa073b3
		e.name = "Generic entry"
175
500cdfa073b3
		e.description = "A test entry"
176
500cdfa073b3
		e.updated = 1098822251
177
500cdfa073b3
		e.get_field(entry.HostnameField).value = "localhost"
178
500cdfa073b3
		e.get_field(entry.UsernameField).value = "erikg"
179
500cdfa073b3
		e.get_field(entry.PasswordField).value = "pwtest"
180
500cdfa073b3
181
f98d1213af7a
		entrystore.add_entry(e)
182
500cdfa073b3
183
500cdfa073b3
		entrystore2 = handler.import_data(handler.export_data(entrystore))
184
500cdfa073b3
185
500cdfa073b3
		e2 = entrystore2.get_entry(entrystore2.iter_nth_child(None, 0))
186
500cdfa073b3
187
500cdfa073b3
		self.assertEquals(e.name, e2.name)
188
500cdfa073b3
		self.assertEquals(e.description, e2.description)
189
500cdfa073b3
		self.assertEquals(e.updated, e2.updated)
190
500cdfa073b3
		self.assertEquals(e.get_field(entry.HostnameField).value, e2.get_field(entry.HostnameField).value)
191
500cdfa073b3
		self.assertEquals(e.get_field(entry.UsernameField).value, e2.get_field(entry.UsernameField).value)
192
500cdfa073b3
		self.assertEquals(e.get_field(entry.PasswordField).value, e2.get_field(entry.PasswordField).value)
193
500cdfa073b3
194
500cdfa073b3
195
500cdfa073b3
	def test_validxml(self):
196
500cdfa073b3
		"RevelationXML.export_data() generates well-formed XML"
197
500cdfa073b3
198
500cdfa073b3
		handler = datahandler.RevelationXML()
199
500cdfa073b3
		entrystore = data.EntryStore()
200
500cdfa073b3
201
500cdfa073b3
		e = entry.FolderEntry()
202
500cdfa073b3
		e.name = "Folder"
203
f98d1213af7a
		folderiter = entrystore.add_entry(e)
204
500cdfa073b3
205
500cdfa073b3
		e = entry.GenericEntry()
206
500cdfa073b3
		e.name = "Generic entry"
207
500cdfa073b3
		e.description = "A test entry"
208
500cdfa073b3
		e.updated = 1098822251
209
500cdfa073b3
		e.get_field(entry.HostnameField).value = "localhost"
210
500cdfa073b3
		e.get_field(entry.UsernameField).value = "erikg"
211
500cdfa073b3
		e.get_field(entry.PasswordField).value = "pwtest"
212
f98d1213af7a
		entrystore.add_entry(e, folderiter)
213
f98d1213af7a
		entrystore.add_entry(e)
214
500cdfa073b3
215
500cdfa073b3
		xmldata = handler.export_data(entrystore)
216
500cdfa073b3
		xml.dom.minidom.parseString(xmldata)
217
500cdfa073b3
		
218
500cdfa073b3
219
500cdfa073b3
220
500cdfa073b3
class RevelationXML_import_data(unittest.TestCase):
221
500cdfa073b3
	"RevelationXML.import_data()"
222
500cdfa073b3
223
500cdfa073b3
	def test_emptyentry(self):
224
500cdfa073b3
		"RevelationXML.import_data() handles empty entries"
225
500cdfa073b3
	
226
500cdfa073b3
		handler = datahandler.RevelationXML()
227
500cdfa073b3
228
500cdfa073b3
		xml = """
229
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
230
500cdfa073b3
<revelationdata dataversion="1">
231
500cdfa073b3
	<entry type="generic" />
232
500cdfa073b3
</revelationdata>
233
500cdfa073b3
"""
234
500cdfa073b3
235
500cdfa073b3
		entrystore = handler.import_data(xml)
236
500cdfa073b3
		e = entrystore.get_entry(entrystore.iter_nth_child(None, 0))
237
500cdfa073b3
238
500cdfa073b3
		self.assertNotEqual(e, None)
239
500cdfa073b3
		self.assertEqual(e.name, "")
240
500cdfa073b3
		self.assertEqual(e.description, "")
241
500cdfa073b3
		self.assertNotEqual(e.updated, 0)
242
500cdfa073b3
		self.assertEqual(type(e), entry.GenericEntry)
243
500cdfa073b3
		self.assertEqual(e.get_field(entry.HostnameField).value, "")
244
500cdfa073b3
		self.assertEqual(e.get_field(entry.UsernameField).value, "")
245
500cdfa073b3
		self.assertEqual(e.get_field(entry.PasswordField).value, "")
246
500cdfa073b3
247
500cdfa073b3
248
500cdfa073b3
249
500cdfa073b3
	def test_entrydata(self):
250
500cdfa073b3
		"RevelationXML.import_data() loads all entry data"
251
500cdfa073b3
252
500cdfa073b3
		handler = datahandler.RevelationXML()
253
500cdfa073b3
254
500cdfa073b3
		xml = """
255
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
256
500cdfa073b3
<revelationdata dataversion="1">
257
500cdfa073b3
	<entry type="generic">
258
500cdfa073b3
		<name>Generic entry</name>
259
500cdfa073b3
		<description>A test entry</description>
260
500cdfa073b3
		<updated>1098738771</updated>
261
500cdfa073b3
		<field id="generic-hostname">localhost</field>
262
500cdfa073b3
		<field id="generic-username">erikg</field>
263
500cdfa073b3
		<field id="generic-password">pwtest</field>
264
500cdfa073b3
	</entry>
265
500cdfa073b3
</revelationdata>
266
500cdfa073b3
"""
267
500cdfa073b3
268
500cdfa073b3
		entrystore = handler.import_data(xml)
269
500cdfa073b3
		e = entrystore.get_entry(entrystore.iter_nth_child(None, 0))
270
500cdfa073b3
271
500cdfa073b3
		self.assertEqual(e.name, "Generic entry")
272
500cdfa073b3
		self.assertEqual(e.description, "A test entry")
273
500cdfa073b3
		self.assertEqual(e.updated, 1098738771)
274
500cdfa073b3
		self.assertEqual(type(e), entry.GenericEntry)
275
500cdfa073b3
		self.assertEqual(e.get_field(entry.HostnameField).value, "localhost")
276
500cdfa073b3
		self.assertEqual(e.get_field(entry.UsernameField).value, "erikg")
277
500cdfa073b3
		self.assertEqual(e.get_field(entry.PasswordField).value, "pwtest")
278
500cdfa073b3
279
500cdfa073b3
280
500cdfa073b3
	def test_entrydata(self):
281
500cdfa073b3
		"RevelationXML.import_data() handles all entry types"
282
500cdfa073b3
283
500cdfa073b3
		handler = datahandler.RevelationXML()
284
500cdfa073b3
285
500cdfa073b3
		typedata = {
286
500cdfa073b3
			"folder"	: [],
287
500cdfa073b3
			"creditcard"	: [ "creditcard-cardtype", "creditcard-cardnumber", "creditcard-expirydate", "creditcard-ccv", "generic-pin" ],
288
500cdfa073b3
			"cryptokey"	: [ "generic-hostname", "generic-certificate", "generic-keyfile", "generic-password" ],
289
500cdfa073b3
			"database"	: [ "generic-hostname", "generic-username", "generic-password", "generic-database" ],
290
500cdfa073b3
			"door"		: [ "generic-location", "generic-code" ],
291
500cdfa073b3
			"email"		: [ "generic-email", "generic-hostname", "generic-username", "generic-password" ],
292
500cdfa073b3
			"ftp"		: [ "generic-hostname", "generic-port", "generic-username", "generic-password" ],
293
500cdfa073b3
			"generic"	: [ "generic-hostname", "generic-username", "generic-password" ],
294
500cdfa073b3
			"phone"		: [ "phone-phonenumber", "generic-pin" ],
295
500cdfa073b3
			"shell"		: [ "generic-hostname", "generic-domain", "generic-username", "generic-password" ],
296
500cdfa073b3
			"website"	: [ "generic-url", "generic-username", "generic-password" ]
297
500cdfa073b3
		}
298
500cdfa073b3
299
500cdfa073b3
		xml = """<?xml version="1.0" ?><revelationdata dataversion="1">"""
300
500cdfa073b3
301
500cdfa073b3
		for typename, fieldlist in typedata.items():
302
500cdfa073b3
			xml += "<entry type=\"" + typename + "\">"
303
500cdfa073b3
304
500cdfa073b3
			for field in fieldlist:
305
500cdfa073b3
				xml += "<field id=\"" + field + "\"></field>"
306
500cdfa073b3
307
500cdfa073b3
			xml += "</entry>"
308
500cdfa073b3
309
500cdfa073b3
		xml += "</revelationdata>"
310
500cdfa073b3
311
500cdfa073b3
		handler.import_data(xml)
312
500cdfa073b3
313
500cdfa073b3
314
500cdfa073b3
315
500cdfa073b3
	def test_inv_entryfield(self):
316
500cdfa073b3
		"RevelationXML.import_data() raises DataError on invalid entry field"
317
500cdfa073b3
318
500cdfa073b3
		handler = datahandler.RevelationXML()
319
500cdfa073b3
320
500cdfa073b3
		xml = """
321
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
322
500cdfa073b3
<revelationdata dataversion="1">
323
500cdfa073b3
	<entry type="generic">
324
500cdfa073b3
		<name>Generic entry</name>
325
500cdfa073b3
		<description>A test entry</description>
326
500cdfa073b3
		<updated>1098738771</updated>
327
500cdfa073b3
		<field id="creditcard-cardnumber">invalid field type</field>
328
500cdfa073b3
		<field id="generic-username">erikg</field>
329
500cdfa073b3
		<field id="generic-password">pwtest</field>
330
500cdfa073b3
	</entry>
331
500cdfa073b3
</revelationdata>
332
500cdfa073b3
"""
333
500cdfa073b3
334
500cdfa073b3
		self.assertRaises(datahandler.DataError, handler.import_data, xml)
335
500cdfa073b3
336
500cdfa073b3
337
500cdfa073b3
338
500cdfa073b3
	def test_inv_entrytype(self):
339
500cdfa073b3
		"RevelationXML.import_data() raises DataError on invalid entry type"
340
500cdfa073b3
341
500cdfa073b3
		handler = datahandler.RevelationXML()
342
500cdfa073b3
343
500cdfa073b3
		xml = """
344
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
345
500cdfa073b3
<revelationdata dataversion="1">
346
500cdfa073b3
	<entry type="invalid">
347
500cdfa073b3
		<name>Generic entry</name>
348
500cdfa073b3
		<description>A test entry</description>
349
500cdfa073b3
		<updated>1098738771</updated>
350
500cdfa073b3
		<field id="generic-hostname">localhost</field>
351
500cdfa073b3
		<field id="generic-username">erikg</field>
352
500cdfa073b3
		<field id="generic-password">pwtest</field>
353
500cdfa073b3
	</entry>
354
500cdfa073b3
</revelationdata>
355
500cdfa073b3
"""
356
500cdfa073b3
357
500cdfa073b3
		self.assertRaises(datahandler.DataError, handler.import_data, xml)
358
500cdfa073b3
359
500cdfa073b3
360
500cdfa073b3
	def test_inv_fieldtype(self):
361
500cdfa073b3
		"RevelationXML.import_data() raises DataError on invalid field type"
362
500cdfa073b3
363
500cdfa073b3
		handler = datahandler.RevelationXML()
364
500cdfa073b3
365
500cdfa073b3
		xml = """
366
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
367
500cdfa073b3
<revelationdata dataversion="1">
368
500cdfa073b3
	<entry type="generic">
369
500cdfa073b3
		<name>Generic entry</name>
370
500cdfa073b3
		<description>A test entry</description>
371
500cdfa073b3
		<updated>1098738771</updated>
372
500cdfa073b3
		<field id="invalid">localhost</field>
373
500cdfa073b3
		<field id="generic-username">erikg</field>
374
500cdfa073b3
		<field id="generic-password">pwtest</field>
375
500cdfa073b3
	</entry>
376
500cdfa073b3
</revelationdata>
377
500cdfa073b3
"""
378
500cdfa073b3
379
500cdfa073b3
		self.assertRaises(datahandler.DataError, handler.import_data, xml)
380
500cdfa073b3
381
500cdfa073b3
382
500cdfa073b3
	def test_inv_node(self):
383
500cdfa073b3
		"RevelationXML.import_data() raises FormatError on unknown nodes"
384
500cdfa073b3
385
500cdfa073b3
		handler = datahandler.RevelationXML()
386
500cdfa073b3
387
500cdfa073b3
		xml = """
388
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
389
500cdfa073b3
<revelationdata dataversion="1">
390
500cdfa073b3
	<dummy />
391
500cdfa073b3
</revelationdata>
392
500cdfa073b3
"""
393
500cdfa073b3
394
500cdfa073b3
		xml2 = """
395
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
396
500cdfa073b3
<revelationdata dataversion="1">
397
500cdfa073b3
	<entry type="generic">
398
500cdfa073b3
		<dummy />
399
500cdfa073b3
	</entry>
400
500cdfa073b3
</revelationdata>
401
500cdfa073b3
"""
402
500cdfa073b3
403
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.import_data, xml)
404
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.import_data, xml2)
405
500cdfa073b3
406
500cdfa073b3
407
500cdfa073b3
	def test_missing_entrytype(self):
408
500cdfa073b3
		"RevelationXML.import_data() raises FormatError on missing entrytype"
409
500cdfa073b3
410
500cdfa073b3
		handler = datahandler.RevelationXML()
411
500cdfa073b3
412
500cdfa073b3
		xml = """
413
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
414
500cdfa073b3
<revelationdata dataversion="1">
415
500cdfa073b3
	<entry>
416
500cdfa073b3
		<name>Generic entry</name>
417
500cdfa073b3
		<description>A test entry</description>
418
500cdfa073b3
		<updated>1098738771</updated>
419
500cdfa073b3
		<field id="generic-hostname">localhost</field>
420
500cdfa073b3
		<field id="generic-username">erikg</field>
421
500cdfa073b3
		<field id="generic-password">pwtest</field>
422
500cdfa073b3
	</entry>
423
500cdfa073b3
</revelationdata>
424
500cdfa073b3
"""
425
500cdfa073b3
426
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.import_data, xml)
427
500cdfa073b3
428
500cdfa073b3
	def test_missing_fieldid(self):
429
500cdfa073b3
		"RevelationXML.import_data() raises FormatError on missing fieldid"
430
500cdfa073b3
431
500cdfa073b3
		handler = datahandler.RevelationXML()
432
500cdfa073b3
433
500cdfa073b3
		xml = """
434
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
435
500cdfa073b3
<revelationdata dataversion="1">
436
500cdfa073b3
	<entry type="generic">
437
500cdfa073b3
		<name>Generic entry</name>
438
500cdfa073b3
		<description>A test entry</description>
439
500cdfa073b3
		<updated>1098738771</updated>
440
500cdfa073b3
		<field>localhost</field>
441
500cdfa073b3
		<field id="generic-username">erikg</field>
442
500cdfa073b3
		<field id="generic-password">pwtest</field>
443
500cdfa073b3
	</entry>
444
500cdfa073b3
</revelationdata>
445
500cdfa073b3
"""
446
500cdfa073b3
447
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.import_data, xml)
448
500cdfa073b3
449
500cdfa073b3
450
500cdfa073b3
	def test_parentfolder(self):
451
500cdfa073b3
		"RevelationXML.import_data() raises DataError when non-folder has children"
452
500cdfa073b3
453
500cdfa073b3
		handler = datahandler.RevelationXML()
454
500cdfa073b3
455
500cdfa073b3
		xml = """
456
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
457
500cdfa073b3
<revelationdata dataversion="1">
458
500cdfa073b3
	<entry type="generic">
459
500cdfa073b3
		<name>Non-folder</name>
460
500cdfa073b3
		<description>An invalid parent</description>
461
500cdfa073b3
		<updated>1098738862</updated>
462
500cdfa073b3
463
500cdfa073b3
		<entry type="generic">
464
500cdfa073b3
			<name>Generic entry</name>
465
500cdfa073b3
			<description>A test entry</description>
466
500cdfa073b3
			<updated>1098738771</updated>
467
500cdfa073b3
			<field id="generic-hostname">localhost</field>
468
500cdfa073b3
			<field id="generic-username">erikg</field>
469
500cdfa073b3
			<field id="generic-password">pwtest</field>
470
500cdfa073b3
		</entry>
471
500cdfa073b3
	</entry>
472
500cdfa073b3
</revelationdata>
473
500cdfa073b3
"""
474
500cdfa073b3
475
500cdfa073b3
		self.assertRaises(datahandler.DataError, handler.import_data, xml)
476
500cdfa073b3
477
500cdfa073b3
478
500cdfa073b3
	def test_inv_updated(self):
479
500cdfa073b3
		"RevelationXML.import_data() raises DataError on invalid updatetime"
480
500cdfa073b3
481
500cdfa073b3
		handler = datahandler.RevelationXML()
482
500cdfa073b3
483
500cdfa073b3
		xml = """
484
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
485
500cdfa073b3
<revelationdata dataversion="1">
486
500cdfa073b3
	<entry type="generic">
487
500cdfa073b3
		<name>Generic entry</name>
488
500cdfa073b3
		<description>A test entry</description>
489
500cdfa073b3
		<updated>dummy123</updated>
490
500cdfa073b3
		<field id="generic-hostname">localhost</field>
491
500cdfa073b3
		<field id="generic-username">erikg</field>
492
500cdfa073b3
		<field id="generic-password">pwtest</field>
493
500cdfa073b3
	</entry>
494
500cdfa073b3
</revelationdata>
495
500cdfa073b3
"""
496
500cdfa073b3
497
500cdfa073b3
		self.assertRaises(datahandler.DataError, handler.import_data, xml)
498
500cdfa073b3
499
500cdfa073b3
500
500cdfa073b3
	def test_valid(self):
501
500cdfa073b3
		"RevelationXML.import_data() accepts valid input"
502
500cdfa073b3
503
500cdfa073b3
		handler = datahandler.RevelationXML()
504
500cdfa073b3
505
500cdfa073b3
		xml = """
506
500cdfa073b3
<?xml version="1.0" encoding="iso-8859-1" ?>
507
500cdfa073b3
<revelationdata dataversion="1">
508
500cdfa073b3
	<entry type="folder">
509
500cdfa073b3
		<name>Folder</name>
510
500cdfa073b3
		<description>A test folder</description>
511
500cdfa073b3
		<updated>1098738862</updated>
512
500cdfa073b3
513
500cdfa073b3
		<entry type="generic">
514
500cdfa073b3
			<name>Generic entry</name>
515
500cdfa073b3
			<description>A test entry</description>
516
500cdfa073b3
			<updated>1098738771</updated>
517
500cdfa073b3
			<field id="generic-hostname">localhost</field>
518
500cdfa073b3
			<field id="generic-username">erikg</field>
519
500cdfa073b3
			<field id="generic-password">pwtest</field>
520
500cdfa073b3
		</entry>
521
500cdfa073b3
	</entry>
522
500cdfa073b3
</revelationdata>
523
500cdfa073b3
"""
524
500cdfa073b3
525
500cdfa073b3
		self.assertEqual(type(handler.import_data(xml)), data.EntryStore)
526
500cdfa073b3
527
500cdfa073b3
528
500cdfa073b3
529
500cdfa073b3
class Revelation(unittest.TestCase):
530
500cdfa073b3
	"Revelation"
531
500cdfa073b3
532
500cdfa073b3
	def test_attrs(self):
533
500cdfa073b3
		"Revelation has sane attributes"
534
500cdfa073b3
535
500cdfa073b3
		self.assertNotEqual(datahandler.Revelation.name, "")
536
500cdfa073b3
		self.assertEqual(datahandler.Revelation.importer, True)
537
500cdfa073b3
		self.assertEqual(datahandler.Revelation.exporter, True)
538
500cdfa073b3
		self.assertEqual(datahandler.Revelation.encryption, True)
539
500cdfa073b3
540
500cdfa073b3
541
500cdfa073b3
542
500cdfa073b3
class Revelation_check(unittest.TestCase):
543
500cdfa073b3
	"Revelation.check()"
544
500cdfa073b3
545
500cdfa073b3
	def test_invalid(self):
546
500cdfa073b3
		"Revelation.check() raises FormatError on invalid data"
547
500cdfa073b3
548
500cdfa073b3
		handler = datahandler.Revelation()
549
500cdfa073b3
550
500cdfa073b3
		data = "xxx\x00\x01\x00\x00\x04\x00\x00\x00\x00" + ("\0" * 32)
551
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.check, data)
552
500cdfa073b3
553
500cdfa073b3
		data = "rvl\x00\x01\x00\x00\x00\x00jej" + ("\0" * 32)
554
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.check, data)
555
500cdfa073b3
556
500cdfa073b3
557
500cdfa073b3
	def test_none(self):
558
500cdfa073b3
		"Revelation.check() raises FormatError on None"
559
500cdfa073b3
560
500cdfa073b3
		handler = datahandler.Revelation()
561
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.check, None)
562
500cdfa073b3
563
500cdfa073b3
564
500cdfa073b3
	def test_short(self):
565
500cdfa073b3
		"Revelation.check() raises FormatError on short data"
566
500cdfa073b3
567
500cdfa073b3
		handler = datahandler.Revelation()
568
500cdfa073b3
		data = "rvl\x00\x01\x00\x00\x04\x00\x00\x00\x00"
569
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.check, data)
570
500cdfa073b3
571
500cdfa073b3
572
500cdfa073b3
	def test_valid(self):
573
500cdfa073b3
		"Revelation.check() handles valid data"
574
500cdfa073b3
575
500cdfa073b3
		handler = datahandler.Revelation()
576
500cdfa073b3
		data = "rvl\x00\x01\x00\x00\x04\x00\x00\x00\x00" + ("\0" * 32)
577
500cdfa073b3
578
500cdfa073b3
		handler.check(data)
579
500cdfa073b3
580
500cdfa073b3
581
500cdfa073b3
582
500cdfa073b3
	def test_version(self):
583
500cdfa073b3
		"Revelation.check() raises VersionError on unknown version"
584
500cdfa073b3
585
500cdfa073b3
		handler = datahandler.Revelation()
586
500cdfa073b3
		data = "rvl\x00\x02\x00\x00\x04\x00\x00\x00\x00" + ("\0" * 32)
587
500cdfa073b3
		self.assertRaises(datahandler.VersionError, handler.check, data)
588
500cdfa073b3
589
500cdfa073b3
590
500cdfa073b3
591
500cdfa073b3
class Revelation_detect(unittest.TestCase):
592
500cdfa073b3
	"Revelation.detect()"
593
500cdfa073b3
594
500cdfa073b3
	def test_invalid(self):
595
500cdfa073b3
		"Revelation.detect() rejects invalid data"
596
500cdfa073b3
597
500cdfa073b3
		handler = datahandler.Revelation()
598
500cdfa073b3
599
500cdfa073b3
		data = "xxx\x00\x01\x00\x00\x04\x00\x00\x00\x00" + ("\0" * 32)
600
500cdfa073b3
		self.assertEquals(handler.detect(data), False)
601
500cdfa073b3
602
500cdfa073b3
		data = "rvl\x00\x01\x00\x00\x00\x00jej" + ("\0" * 32)
603
500cdfa073b3
		self.assertEquals(handler.detect(data), False)
604
500cdfa073b3
605
500cdfa073b3
606
500cdfa073b3
	def test_none(self):
607
500cdfa073b3
		"Revelation.detect() rejects None"
608
500cdfa073b3
609
500cdfa073b3
		handler = datahandler.Revelation()
610
500cdfa073b3
		self.assertEquals(handler.detect(None), False)
611
500cdfa073b3
612
500cdfa073b3
613
500cdfa073b3
	def test_short(self):
614
500cdfa073b3
		"Revelation.detect() rejects short data"
615
500cdfa073b3
616
500cdfa073b3
		handler = datahandler.Revelation()
617
500cdfa073b3
		data = "rvl\x00\x01\x00\x00\x04\x00\x00\x00\x00"
618
500cdfa073b3
		self.assertEquals(handler.detect(data), False)
619
500cdfa073b3
620
500cdfa073b3
621
500cdfa073b3
	def test_valid(self):
622
500cdfa073b3
		"Revelation.detect() handles valid data"
623
500cdfa073b3
624
500cdfa073b3
		handler = datahandler.Revelation()
625
500cdfa073b3
		data = "rvl\x00\x01\x00\x00\x04\x00\x00\x00\x00" + ("\0" * 32)
626
500cdfa073b3
		self.assertEquals(handler.detect(data), True)
627
500cdfa073b3
628
500cdfa073b3
629
500cdfa073b3
	def test_version(self):
630
500cdfa073b3
		"Revelation.detect() rejects unknown versions"
631
500cdfa073b3
632
500cdfa073b3
		handler = datahandler.Revelation()
633
500cdfa073b3
		data = "rvl\x00\x02\x00\x00\x04\x00\x00\x00\x00" + ("\0" * 32)
634
500cdfa073b3
		self.assertEquals(handler.detect(data), False)
635
500cdfa073b3
636
500cdfa073b3
637
500cdfa073b3
class Revelation_export_data(unittest.TestCase):
638
500cdfa073b3
	"Revelation.export_data()"
639
500cdfa073b3
640
500cdfa073b3
	def setUp(self):
641
500cdfa073b3
642
500cdfa073b3
		# set up a common password
643
500cdfa073b3
		self.password = "test123"
644
500cdfa073b3
645
500cdfa073b3
		# set up an entrystore for tests
646
500cdfa073b3
		self.entrystore = data.EntryStore()
647
500cdfa073b3
648
500cdfa073b3
		e = entry.FolderEntry()
649
500cdfa073b3
		e.name = "Testfolder"
650
500cdfa073b3
		e.description = "Just a test folder"
651
500cdfa073b3
652
f98d1213af7a
		folderiter = self.entrystore.add_entry(e)
653
500cdfa073b3
654
500cdfa073b3
		e = entry.GenericEntry()
655
500cdfa073b3
		e.name = "Generic child"
656
500cdfa073b3
		e.description = "Child-entry"
657
500cdfa073b3
658
f98d1213af7a
		self.entrystore.add_entry(e, folderiter)
659
500cdfa073b3
660
500cdfa073b3
		e = entry.GenericEntry()
661
500cdfa073b3
		e.name = "Another test-entry"
662
f98d1213af7a
		self.entrystore.add_entry(e)
663
500cdfa073b3
664
500cdfa073b3
665
500cdfa073b3
	def test_header(self):
666
500cdfa073b3
		"Revelation.export_data() generates a valid header"
667
500cdfa073b3
668
500cdfa073b3
		handler = datahandler.Revelation()
669
500cdfa073b3
		data = handler.export_data(self.entrystore, self.password)
670
500cdfa073b3
671
500cdfa073b3
		match = re.match("""
672
500cdfa073b3
			^		# start of line
673
500cdfa073b3
			rvl\x00		# magic string
674
500cdfa073b3
			(.)		# data version
675
500cdfa073b3
			\x00		# separator
676
500cdfa073b3
			(.{3})		# app version
677
500cdfa073b3
			\x00\x00\x00	# separator
678
500cdfa073b3
		""", data, re.VERBOSE)
679
500cdfa073b3
680
500cdfa073b3
		self.assertNotEqual(match, None)
681
500cdfa073b3
		self.assertEqual(ord(match.group(1)), 1)
682
500cdfa073b3
		self.assertEqual(ord(match.group(2)[0]) < 10, True)
683
500cdfa073b3
		self.assertEqual(ord(match.group(2)[1]) < 10, True)
684
500cdfa073b3
		self.assertEqual(ord(match.group(2)[2]) < 10, True)
685
500cdfa073b3
686
500cdfa073b3
687
500cdfa073b3
	def test_length(self):
688
500cdfa073b3
		"Revelation.export_data() generates data of correct length"
689
500cdfa073b3
690
500cdfa073b3
		handler = datahandler.Revelation()
691
500cdfa073b3
		data = handler.export_data(self.entrystore, self.password)
692
500cdfa073b3
693
500cdfa073b3
		self.assertEqual(len(data) >= 28, True)
694
500cdfa073b3
		self.assertEqual((len(data) - 12) % 16, 0)
695
500cdfa073b3
696
500cdfa073b3
697
500cdfa073b3
	def test_password_none(self):
698
500cdfa073b3
		"Revelation.export_data() raises PasswordError on None password"
699
500cdfa073b3
700
500cdfa073b3
		handler = datahandler.Revelation()
701
500cdfa073b3
702
500cdfa073b3
		self.assertRaises(datahandler.PasswordError, handler.export_data, self.entrystore, None)
703
500cdfa073b3
704
500cdfa073b3
705
500cdfa073b3
	def test_random(self):
706
500cdfa073b3
		"Revelation.export_data() gives different results each run"
707
500cdfa073b3
708
500cdfa073b3
		handler = datahandler.Revelation()
709
500cdfa073b3
710
500cdfa073b3
		self.assertNotEqual(
711
500cdfa073b3
			handler.export_data(self.entrystore, self.password),
712
500cdfa073b3
			handler.export_data(self.entrystore, self.password)
713
500cdfa073b3
		)
714
500cdfa073b3
715
500cdfa073b3
716
500cdfa073b3
	def test_valid(self):
717
500cdfa073b3
		"Revelation.export_data() generates valid data"
718
500cdfa073b3
719
500cdfa073b3
		handler = datahandler.Revelation()
720
500cdfa073b3
		encdata = handler.export_data(self.entrystore, self.password)
721
500cdfa073b3
		entrystore = handler.import_data(encdata, self.password)
722
500cdfa073b3
723
500cdfa073b3
		self.assertEqual(type(entrystore), type(self.entrystore))
724
500cdfa073b3
725
500cdfa073b3
		e1 = self.entrystore.get_entry(self.entrystore.iter_nth_child(None, 1))
726
500cdfa073b3
		e2 = entrystore.get_entry(entrystore.iter_nth_child(None, 1))
727
500cdfa073b3
728
500cdfa073b3
		self.assertEqual(type(e1), type(e2))
729
500cdfa073b3
		self.assertEqual(e1.name, e2.name)
730
500cdfa073b3
		self.assertEqual(e1.description, e2.description)
731
500cdfa073b3
		self.assertEqual(e1.updated, e2.updated)
732
500cdfa073b3
733
500cdfa073b3
		for f1, f2 in zip(e1.fields, e2.fields):
734
500cdfa073b3
			self.assertEqual(f1.value, f2.value)
735
500cdfa073b3
736
500cdfa073b3
737
500cdfa073b3
738
500cdfa073b3
class Revelation_import_data(unittest.TestCase):
739
500cdfa073b3
	"Revelation.import_data()"
740
500cdfa073b3
741
500cdfa073b3
	def setUp(self):
742
500cdfa073b3
743
500cdfa073b3
		# set up a common password
744
500cdfa073b3
		self.password = "test123"
745
500cdfa073b3
746
500cdfa073b3
		# set up an entrystore for tests
747
500cdfa073b3
		self.entrystore = data.EntryStore()
748
500cdfa073b3
749
500cdfa073b3
		e = entry.FolderEntry()
750
500cdfa073b3
		e.name = "Testfolder"
751
500cdfa073b3
		e.description = "Just a test folder"
752
500cdfa073b3
753
f98d1213af7a
		folderiter = self.entrystore.add_entry(e)
754
500cdfa073b3
755
500cdfa073b3
		e = entry.GenericEntry()
756
500cdfa073b3
		e.name = "Generic child"
757
500cdfa073b3
		e.description = "Child-entry"
758
500cdfa073b3
759
f98d1213af7a
		self.entrystore.add_entry(e, folderiter)
760
500cdfa073b3
761
500cdfa073b3
		e = entry.GenericEntry()
762
500cdfa073b3
		e.name = "Another test-entry"
763
f98d1213af7a
		self.entrystore.add_entry(e)
764
500cdfa073b3
765
500cdfa073b3
		handler = datahandler.Revelation()
766
500cdfa073b3
		self.data = handler.export_data(self.entrystore, self.password)
767
500cdfa073b3
768
500cdfa073b3
769
500cdfa073b3
	def test_inv_header(self):
770
500cdfa073b3
		"Revelation.import_data() raises FormatError on invalid header"
771
500cdfa073b3
772
500cdfa073b3
		handler = datahandler.Revelation()
773
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.import_data, "123" + self.data[3:], self.password)
774
500cdfa073b3
775
500cdfa073b3
776
500cdfa073b3
	def test_inv_length(self):
777
500cdfa073b3
		"Revelation.import_data() raises FormatError on invalid length"
778
500cdfa073b3
779
500cdfa073b3
		handler = datahandler.Revelation()
780
500cdfa073b3
		self.assertRaises(datahandler.FormatError, handler.import_data, self.data + "123", self.password)
781
500cdfa073b3
782
500cdfa073b3
783
500cdfa073b3
	def test_inv_password(self):
784
500cdfa073b3
		"Revelation.import_data() raises PasswordError on invalid password"
785
500cdfa073b3
786
500cdfa073b3
		handler = datahandler.Revelation()
787
500cdfa073b3
		self.assertRaises(datahandler.PasswordError, handler.import_data, self.data, "dummypassword")
788
500cdfa073b3
789
500cdfa073b3
790
500cdfa073b3
	def test_inv_version(self):
791
500cdfa073b3
		"Revelation.import_data() raises VersionError on invalid version"
792
500cdfa073b3
793
500cdfa073b3
		handler = datahandler.Revelation()
794
500cdfa073b3
		self.assertRaises(datahandler.VersionError, handler.import_data, "rvl\x00\x00" + self.data[5:], self.password)
795
500cdfa073b3
		self.assertRaises(datahandler.VersionError, handler.import_data, "rvl\x00\x02" + self.data[5:], self.password)
796
500cdfa073b3
797
500cdfa073b3
798
500cdfa073b3
	def test_password_long(self):
799
500cdfa073b3
		"Revelation.import_data() handles long (>32 chars) passwords"
800
500cdfa073b3
801
500cdfa073b3
		handler = datahandler.Revelation()
802
500cdfa073b3
		data = handler.export_data(self.entrystore, "abcdefgh12345678abcdefgh12345678abcdefgh")
803
500cdfa073b3
		entrystore = handler.import_data(data, "abcdefgh12345678abcdefgh12345678abcdefgh")
804
500cdfa073b3
805
500cdfa073b3
806
500cdfa073b3
	def test_password_none(self):
807
500cdfa073b3
		"Revelation.import_data() raises PasswordError on None password"
808
500cdfa073b3
809
500cdfa073b3
		handler = datahandler.Revelation()
810
500cdfa073b3
		self.assertRaises(datahandler.PasswordError, handler.import_data, self.data, None)
811
500cdfa073b3
812
500cdfa073b3
813
500cdfa073b3
	def test_valid(self):
814
500cdfa073b3
		"Revelation.import_data() accepts valid data"
815
500cdfa073b3
816
500cdfa073b3
		handler = datahandler.Revelation()
817
500cdfa073b3
		entrystore = handler.import_data(self.data, self.password)
818
500cdfa073b3
819
500cdfa073b3
		self.assertEqual(type(entrystore), type(self.entrystore))
820
500cdfa073b3
821
500cdfa073b3
		e1 = self.entrystore.get_entry(self.entrystore.iter_nth_child(None, 1))
822
500cdfa073b3
		e2 = entrystore.get_entry(entrystore.iter_nth_child(None, 1))
823
500cdfa073b3
824
500cdfa073b3
		self.assertEqual(type(e1), type(e2))
825
500cdfa073b3
		self.assertEqual(e1.name, e2.name)
826
500cdfa073b3
		self.assertEqual(e1.description, e2.description)
827
500cdfa073b3
		self.assertEqual(e1.updated, e2.updated)
828
500cdfa073b3
829
500cdfa073b3
		for f1, f2 in zip(e1.fields, e2.fields):
830
500cdfa073b3
			self.assertEqual(f1.value, f2.value)
831
500cdfa073b3
832
500cdfa073b3
833
500cdfa073b3
834
500cdfa073b3
if __name__ == "__main__":
835
500cdfa073b3
	unittest.main()
836
500cdfa073b3