Index: svnserve.py
===================================================================
--- svnserve.py	(revision 17333)
+++ svnserve.py	(working copy)
@@ -62,10 +62,14 @@
     def has_user(self, user):
         return user in self._config['users']
 
-    def set_password(self, user, password, old_password=None):
+    def set_password(self, user, password, old_password=None, overwrite=True):
         cfg = self._config
+        new_acct = not self.has_user(user)
+        if not new_acct and not overwrite:
+            return new_acct
         cfg.set('users', user, password)
         cfg.save()
+        return new_acct
 
     def check_password(self, user, password):
         if self.has_user(user):
@@ -73,6 +77,9 @@
         return None
 
     def delete_user(self, user):
+        if not self.has_user(user):
+            return False
         cfg = self._config
         cfg.remove('users', user)
         cfg.save()
+        return not self.has_user(user)
Index: tests/svnserve.py
===================================================================
--- tests/svnserve.py	(nonexistent)
+++ tests/svnserve.py	(working copy)
@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+"""
+Test suite for SvnServePasswordStore.
+"""
+
+import os.path
+import unittest
+
+
+class SvnServePasswordTestCase(unittest.TestCase):
+    """
+    Test cases for SvnServePasswordStore.
+    """
+
+    def setUp(self):
+        import tempfile
+        from acct_mgr.svnserve import SvnServePasswordStore
+        from trac.test import EnvironmentStub
+        self.basedir = os.path.realpath(tempfile.mkdtemp())
+        self.env = EnvironmentStub()
+        self.env.path = os.path.join(self.basedir, 'trac-tempenv')
+        self.store = SvnServePasswordStore(self.env)
+        self.default_content = [
+            '[users]\n',
+            'spam = eggs\n',
+            'knights = ni\n',
+        ]
+        os.mkdir(self.env.path)
+
+    def tearDown(self):
+        import shutil
+        shutil.rmtree(self.basedir)
+
+    def _create_file(self, test_id, extra_content=None):
+        file_name = os.path.join(self.basedir, 'test_' + test_id)
+        with open(file_name, 'w') as file_fo:
+            file_fo.writelines(self.default_content)
+            if extra_content is not None:
+                file_fo.writelines(extra_content)
+        self.env.config.set('account-manager', 'password_file', file_name)
+
+    def test_check_password_ok(self):
+        """
+        Verify check_password success: correct user and password.
+        """
+        self._create_file(test_id='check_password_ok')
+        self.assertTrue(self.store.check_password('knights', 'ni'))
+
+    def test_check_password_bad(self):
+        """
+        Verify check_password failure: correct user, incorrect password.
+        """
+        self._create_file(test_id='check_password_bad')
+        self.assertFalse(self.store.check_password('knights', 'noo'))
+
+    def test_check_password_unknown(self):
+        """
+        Verify check_password failure: unknown user.
+        """
+        self._create_file(test_id='check_password_unknown')
+        self.assertIsNone(self.store.check_password('brian', 'naughty'))
+
+    def test_delete_user_ok(self):
+        """
+        Verify delete_user success.
+        """
+        self._create_file(test_id='delete_user_ok')
+        user_to_delete = 'knights'
+        self.assertTrue(self.store.delete_user(user_to_delete))
+        self.assertFalse(self.store.has_user(user_to_delete))
+
+    def test_delete_user_unknown(self):
+        """
+        Verify delete_user failure: unknown user.
+        """
+        self._create_file(test_id='delete_user_unknown')
+        user_to_delete = 'brian'
+        self.assertFalse(self.store.delete_user(user_to_delete))
+
+    def test_get_users(self):
+        self._create_file(test_id='get_users')
+        self.assertEqual(
+            self.store.get_users(),
+            ['spam', 'knights'],
+        )
+
+    def test_has_user_ok(self):
+        """
+        Verify has_user for an existing user.
+        """
+        self._create_file(test_id='has_user_ok')
+        self.assertTrue(self.store.has_user('knights'))
+
+    def test_has_user_unknown(self):
+        """
+        Verify has_user for an unknown user.
+        """
+        self._create_file(test_id='has_user_unknown')
+        self.assertFalse(self.store.has_user('brian'))
+
+    def test_set_password(self):
+        """
+        Verify set_password for a new user.
+        """
+        self._create_file(test_id='set_password')
+        new_user = 'brian'
+        new_passwd = 'naughty'
+        self.assertFalse(self.store.has_user(new_user))
+        self.assertTrue(self.store.set_password(new_user, new_passwd))
+        self.assertTrue(self.store.check_password(new_user, new_passwd))
+
+    def test_update_password(self):
+        """
+        Verify set_password for an existing user.
+        """
+        self._create_file(test_id='update_password')
+        existing_user = 'knights'
+        new_passwd = 'noo'
+        self.assertTrue(self.store.has_user(existing_user))
+        self.assertFalse(self.store.set_password(existing_user, new_passwd))
+        self.assertTrue(self.store.check_password(existing_user, new_passwd))
+
+    def test_overwrite_password(self):
+        """
+        Verify set_password rejects overwrite when instructed.
+        """
+        self._create_file(test_id='update_password')
+        existing_user = 'knights'
+        new_passwd = 'noo'
+        self.assertTrue(self.store.has_user(existing_user))
+        self.assertFalse(self.store.set_password(existing_user, new_passwd, overwrite=False))
+        self.assertFalse(self.store.check_password(existing_user, new_passwd))
+
+
+def test_suite():
+    """
+    The assembled test suite.
+    """
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(SvnServePasswordTestCase))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Property changes on: tests/svnserve.py
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
