| @@ -46,6 +46,8 @@ def _makeuuid(s): | |||
| return uuid.UUID(s) | |||
| # XXX - known issue, store is not atomic/safe, overwrites in place instead of renames | |||
| # XXX - add validation | |||
| # XXX - how to add singletons | |||
| class MDBase(object): | |||
| @@ -473,6 +475,8 @@ def main(): | |||
| default=[], help='delete the arg as metadata from files. Either specify tag, and all tags are removed, or specify tag=value and that specific tag will be removed.') | |||
| parser.add_option('-g', action='store_true', dest='generateident', | |||
| default=False, help='generate an identity') | |||
| parser.add_option('-i', action='store_true', dest='updateident', | |||
| default=False, help='update the identity') | |||
| parser.add_option('-l', action='store_true', dest='list', | |||
| default=False, help='list metadata') | |||
| @@ -481,15 +485,19 @@ def main(): | |||
| # this is shared between generateident and add | |||
| addprops = map(lambda x: x.split('=', 1), options.add) | |||
| if options.generateident: | |||
| if options.generateident or options.updateident: | |||
| identfname = os.path.expanduser('~/.medashare_identity.pasn1') | |||
| if os.path.exists(identfname): | |||
| if options.generateident and os.path.exists(identfname): | |||
| print >>sys.stderr, 'Error: Identity already created.' | |||
| sys.exit(1) | |||
| persona = Persona() | |||
| persona.generate_key() | |||
| if options.generateident: | |||
| persona = Persona() | |||
| persona.generate_key() | |||
| else: | |||
| persona = Persona.load(identfname) | |||
| persona.new_version(*addprops) | |||
| persona.store(identfname) | |||
| return | |||
| @@ -830,24 +838,70 @@ class _TestCases(unittest.TestCase): | |||
| with mock.patch('os.path.expanduser', side_effect=expandusermock) \ | |||
| as eu: | |||
| # that generating a new identity | |||
| with nested(mock.patch('sys.stdout', | |||
| StringIO.StringIO()), mock.patch('sys.argv', | |||
| [ 'progname', '-g', '-a', 'name=A Test User' ])) as (stdout, argv): | |||
| main() | |||
| self.assertEqual(stdout.getvalue(), | |||
| '') | |||
| # does not output anything | |||
| self.assertEqual(stdout.getvalue(), '') | |||
| # looks up the correct file | |||
| eu.assert_called_with('~/.medashare_identity.pasn1') | |||
| # and that the identity | |||
| persona = Persona.load(identfname) | |||
| self.assertEqual(persona.get_identity().name, 'A Test User') | |||
| pident = persona.get_identity() | |||
| # has the correct name | |||
| self.assertEqual(pident.name, 'A Test User') | |||
| # that when generating an identity when one already exists | |||
| with nested(mock.patch('sys.stderr', | |||
| StringIO.StringIO()), mock.patch('sys.argv', | |||
| [ 'progname', '-g', '-a', 'name=A Test User' ])) as (stderr, argv): | |||
| self.assertRaises(SystemExit, main) | |||
| # that it exits | |||
| with self.assertRaises(SystemExit) as cm: | |||
| main() | |||
| # with error code 5 | |||
| self.assertEqual(cm.exception[0], 1) | |||
| # and outputs an error message | |||
| self.assertEqual(stderr.getvalue(), | |||
| 'Error: Identity already created.\n') | |||
| # and looked up the correct file | |||
| eu.assert_called_with('~/.medashare_identity.pasn1') | |||
| # that when updating the identity | |||
| with nested(mock.patch('sys.stdout', | |||
| StringIO.StringIO()), mock.patch('sys.argv', | |||
| [ 'progname', '-i', '-a', 'name=Changed Name' ])) as (stdout, argv): | |||
| main() | |||
| # it doesn't output anything | |||
| self.assertEqual(stdout.getvalue(), '') | |||
| # and looked up the correct file | |||
| eu.assert_called_with('~/.medashare_identity.pasn1') | |||
| npersona = Persona.load(identfname) | |||
| nident = npersona.get_identity() | |||
| # and has the new name | |||
| self.assertEqual(nident.name, 'Changed Name') | |||
| # and has the same old uuid | |||
| self.assertEqual(nident.uuid, pident.uuid) | |||
| # and that the modified date has changed | |||
| self.assertNotEqual(pident.modified, nident.modified) | |||
| # and that the old Persona can verify the new one | |||
| self.assertTrue(persona.verify(nident)) | |||
| with nested(mock.patch('sys.stdout', | |||
| StringIO.StringIO()), mock.patch('sys.argv', | |||
| [ 'progname', '-l', testfname ])) as (stdout, argv): | |||