Ejemplo n.º 1
0
class TracAdminDeployTestCase(TracAdminTestCaseBase):
    """Tests for the trac-admin deploy command."""
    def setUp(self):
        self.env = Environment(path=mkdtemp(), create=True)
        self.admin = TracAdmin(self.env.path)
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env.shutdown()  # really closes the db connections
        shutil.rmtree(self.env.path)

    def test_deploy(self):
        """Deploy into valid target directory."""
        target = os.path.join(self.env.path, 'www')
        htdocs_dir = os.path.join(target, 'htdocs')

        rv, output = self.execute('deploy %s' % target)

        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertTrue(os.path.exists(os.path.join(target, 'cgi-bin')))
        self.assertTrue(os.path.exists(htdocs_dir))
        self.assertTrue(os.path.exists(os.path.join(htdocs_dir, 'common')))
        self.assertTrue(os.path.exists(os.path.join(htdocs_dir, 'site')))

    def test_deploy_to_invalid_target_raises_error(self):
        """Running deploy with target directory equal to or below the source 
        directory raises AdminCommandError.
        """
        rv, output = self.execute('deploy %s' % self.env.htdocs_dir)

        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Ejemplo n.º 2
0
class TracAdminDeployTestCase(TracAdminTestCaseBase):
    """Tests for the trac-admin deploy command."""

    stdout = None
    stderr = None
    devnull = None

    @classmethod
    def setUpClass(cls):
        cls.stdout = sys.stdout
        cls.stderr = sys.stderr
        cls.devnull = io.open(os.devnull, 'wb')
        sys.stdout = sys.stderr = cls.devnull

    @classmethod
    def tearDownClass(cls):
        cls.devnull.close()
        sys.stdout = cls.stdout
        sys.stderr = cls.stderr

    def setUp(self):
        self.env = Environment(path=mkdtemp(), create=True)
        self.admin = TracAdmin(self.env.path)
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env.shutdown()
        rmtree(self.env.path)

    def test_deploy(self):
        target = os.path.join(self.env.path, 'www')
        shebang = ('#!' + sys.executable).encode('utf-8')
        rv, output = self.execute('deploy %s' % target)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertTrue(os.path.exists(os.path.join(target, 'cgi-bin')))
        self.assertTrue(os.path.exists(os.path.join(target, 'htdocs')))
        self.assertTrue(os.path.exists(os.path.join(target, 'htdocs',
                                                    'common')))
        self.assertTrue(os.path.exists(os.path.join(target, 'htdocs',
                                                    'site')))
        self.assertTrue(os.path.isfile(os.path.join(
            target, 'htdocs', 'common', 'js', 'trac.js')))
        self.assertTrue(os.path.isfile(os.path.join(
            target, 'htdocs', 'common', 'css', 'trac.css')))
        for ext in ('cgi', 'fcgi', 'wsgi'):
            content = read_file(os.path.join(target, 'cgi-bin',
                                             'trac.%s' % ext), 'rb')
            self.assertIn(shebang, content)
            self.assertEqual(0, content.index(shebang))
            self.assertIn(repr(self.env.path).encode('ascii'), content)

    def test_deploy_to_invalid_target_raises_error(self):
        """Running deploy with target directory equal to or below the source
        directory raises AdminCommandError.
        """
        rv, output = self.execute('deploy %s' % self.env.htdocs_dir)

        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Ejemplo n.º 3
0
def main(trac_env, examples_dir='.'):
    loaded = False
    admin = TracAdmin()
    admin.env_set(trac_env)
    for file in os.listdir(examples_dir):
        if 'GraphvizExamples' in file:
            admin._do_wiki_import(os.path.join(examples_dir, file), 
                                  file.replace('%2F', '/'))
            loaded = True

    if not loaded:
        print 'The %(examples_dir)s does not contain any GrapgvizExamples files.' % locals()
Ejemplo n.º 4
0
class TracAdminTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        provider = DbRepositoryProvider(self.env)
        provider.add_repository('mock', '/', 'mock_type')

    def tearDown(self):
        self.env = None

    def test_changeset_add_no_repository_revision(self):
        rv, output = self.execute('changeset added')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_add_no_revision(self):
        rv, output = self.execute('changeset added mock')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_no_repository_revision(self):
        rv, output = self.execute('changeset modified')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_no_revision(self):
        rv, output = self.execute('changeset modified mock')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_add_invalid_repository(self):
        rv, output = self.execute('changeset added invalid 123')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_invalid_repository(self):
        rv, output = self.execute('changeset modified invalid 123')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_add_invalid_changeset(self):
        rv, output = self.execute('changeset added mock invalid')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_changeset_modify_invalid_changeset(self):
        rv, output = self.execute('changeset modified mock invalid')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Ejemplo n.º 5
0
def main(trac_env, examples_dir='.'):
    loaded = False
    admin = TracAdmin()
    admin.env_set(trac_env)
    for file in os.listdir(examples_dir):
        if 'MetapostExamples' in file:
            admin._do_wiki_import(os.path.join(examples_dir, file),
                                  file.replace('%2F', '/'))
            loaded = True

    if not loaded:
        print 'The %(examples_dir)s does not contain any MetapostExamples files.' % locals(
        )
Ejemplo n.º 6
0
def build_trac_env(request):
    """Create a Trac Environment in a tmp dir
    """
    path = tempfile.mkdtemp()
    ta = TracAdmin()
    ta.env_set(path)
    ta.do_initenv(u'ExampleTracEnv sqlite:db/trac.db')
    env = Environment(path)

    def fin():
        rmtree(path)
    request.addfinalizer(fin)

    if request.cls:
        request.cls.env = env
    return env
Ejemplo n.º 7
0
class TracAdminComponentTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self._orig = {
            'ComponentMeta._components': ComponentMeta._components,
            'ComponentMeta._registry': ComponentMeta._registry,
            'ConfigSection.registry': ConfigSection.registry,
            'Option.registry': Option.registry,
        }
        ComponentMeta._components = list(ComponentMeta._components)
        ComponentMeta._registry = {
            interface: list(classes)
            for interface, classes in ComponentMeta._registry.iteritems()
        }
        ConfigSection.registry = {}
        Option.registry = {}

        class CompA(Component):
            from trac.config import Option
            opt1 = Option('compa', 'opt1', 1)
            opt2 = Option('compa', 'opt2', 2)

    def tearDown(self):
        self.env = None
        self.admin = None
        ComponentMeta._components = self._orig['ComponentMeta._components']
        ComponentMeta._registry = self._orig['ComponentMeta._registry']
        ConfigSection.registry = self._orig['ConfigSection.registry']
        Option.registry = self._orig['Option.registry']

    def test_config_component_enable(self):
        self.env.config.save()
        initial_file = copy.deepcopy(self.env.config.parser)

        rv, output = self.execute('config set components '
                                  'trac.admin.tests.console.* enabled')

        self.assertEqual(0, rv, output)
        self.assertFalse(initial_file.has_section('compa'))
        self.assertIn('compa', self.env.config)
        self.assertIn('1', self.env.config.parser.get('compa', 'opt1'))
        self.assertIn('2', self.env.config.parser.get('compa', 'opt2'))
Ejemplo n.º 8
0
class TracAdminTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True)
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env.reset_db()
        self.env = None

    def test_permission_list_ok(self):
        """Tests the 'permission list' command in trac-admin."""
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_list_includes_undefined_actions(self):
        """Undefined actions are included in the User Action table,
        but not in the Available Actions list.
        """
        self.env.disable_component(trac.search.web_ui.SearchModule)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_one_action_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add one permission and checks for
        success.
        """
        self.execute('permission add test_user WIKI_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_multiple_actions_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add multiple permissions and checks for
        success.
        """
        self.execute('permission add test_user LOG_VIEW FILE_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_already_exists(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that already exists and checks for the
        message. Other permissions passed are added.
        """
        rv, output = self.execute('permission add anonymous WIKI_CREATE '
                                  'WIKI_VIEW WIKI_MODIFY')
        self.assertEqual(0, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_subject_already_in_group(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a group that the subject is already a member of and
        checks for the message. Other permissions passed are added.
        """
        rv, output1 = self.execute('permission add user1 group2')
        self.assertEqual(0, rv, output1)
        rv, output2 = self.execute('permission add user1 group1 group2 '
                                   'group3')
        self.assertEqual(0, rv, output2)
        rv, output3 = self.execute('permission list')
        self.assertEqual(0, rv, output3)
        self.assertExpectedResult(output2 + output3)

    def test_permission_add_differs_from_action_by_casing(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that differs from an action by casing and
        checks for the message. None of the permissions in the list are
        granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'Trac_Admin WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_unknown_action(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test tries granting NOT_A_PERM to a user. NOT_A_PERM does not exist
        in the system. None of the permissions in the list are granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'NOT_A_PERM WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_remove_one_action_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove one permission and checks for
        success.
        """
        self.execute('permission remove anonymous TICKET_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_multiple_actions_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove multiple permission and checks
        for success.
        """
        self.execute('permission remove anonymous WIKI_CREATE WIKI_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_all_actions_for_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes all permissions for anonymous.
        """
        self.execute('permission remove anonymous *')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_for_all_users(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes the TICKET_CREATE permission from all users.
        """
        self.execute('permission add anonymous TICKET_CREATE')
        self.execute('permission remove * TICKET_CREATE')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing a permission from an unknown user.
        """
        rv, output = self.execute('permission remove joe TICKET_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_not_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing TICKET_CREATE from user anonymous, who doesn't
        have that permission.
        """
        rv, output = self.execute('permission remove anonymous TICKET_CREATE')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_granted_through_meta_permission(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing WIKI_VIEW from a user. WIKI_VIEW has been granted
        through user anonymous."""
        self.execute('permission add joe TICKET_VIEW')
        rv, output = self.execute('permission remove joe WIKI_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system."""
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system, but the user possesses the permission."""
        self.env.db_transaction(
            """
            INSERT INTO permission VALUES (%s, %s)
        """, ('joe', 'NOT_A_PERM'))
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_export_ok(self):
        """
        Tests the 'permission export' command in trac-admin.  This particular
        test exports the default permissions to stdout.
        """
        rv, output = self.execute('permission export')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_import_ok(self):
        """
        Tests the 'permission import' command in trac-admin.  This particular
        test exports additional permissions, removes them and imports them back.
        """
        user = u'test_user\u0250'
        self.execute('permission add ' + user + ' WIKI_VIEW')
        self.execute('permission add ' + user + ' TICKET_VIEW')
        rv, output = self.execute('permission export')
        self.execute('permission remove ' + user + ' *')
        rv, output = self.execute('permission import', input=output)
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
Ejemplo n.º 9
0
class TracAdminTestCase(TracAdminTestCaseBase):

    def setUp(self):
        self.env = EnvironmentStub(default_data=True, enable=('trac.*',),
                                   disable=('trac.tests.*',))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self._test_date = '2004-01-11'  # Set test date to 11th Jan 2004

    def tearDown(self):
        self.env = None

    @property
    def datetime_format_hint(self):
        return get_datetime_format_hint(get_console_locale(self.env))

    def test_component_help(self):
        rv, output = self.execute('help component')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_list_ok(self):
        """
        Tests the 'component list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_add_ok(self):
        """
        Tests the 'component add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('component add new_component')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_add_optional_owner_ok(self):
        """
        Tests the 'component add' command in trac-admin with the optional
        'owner' argument.  This particular test passes valid arguments and
        checks for success.
        """
        self.execute('component add new_component new_user')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_add_complete_optional_owner_restrict_owner_false(self):
        """Tests completion of the 'component add <component>' command with
        [ticket] restrict_owner = false.
        """
        self.execute('config set ticket restrict_owner false')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'add',
                                        'new_component', '')
        self.assertEqual([], output)

    def test_component_add_complete_optional_owner_restrict_owner_true(self):
        """Tests completion of the 'component add <component>' command with
        [ticket] restrict_owner = true.
        """
        self.execute('config set ticket restrict_owner true')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'add',
                                        'new_component', '')
        self.assertEqual(['user1', 'user3'], output)

    def test_component_add_error_already_exists(self):
        """
        Tests the 'component add' command in trac-admin.  This particular
        test passes a component name that already exists and checks for an
        error message.
        """
        rv, output = self.execute('component add component1 new_user')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_rename_ok(self):
        """
        Tests the 'component rename' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('component rename component1 changed_name')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_rename_error_bad_component(self):
        """
        Tests the 'component rename' command in trac-admin.  This particular
        test tries to rename a component that does not exist.
        """
        rv, output = self.execute('component rename bad_component changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_rename_error_bad_new_name(self):
        """
        Tests the 'component rename' command in trac-admin.  This particular
        test tries to rename a component to a name that already exists.
        """
        rv, output = self.execute('component rename component1 component2')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_chown_ok(self):
        """
        Tests the 'component chown' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('component chown component2 changed_owner')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_chown_complete_component(self):
        """Tests completion of the 'component chown' command.
        """
        output = self.complete_command('component', 'chown', '')
        self.assertEqual(['component1', 'component2'], output)

    def test_component_chown_complete_owner_restrict_owner_false(self):
        """Tests completion of the 'component chown <component>' command with
        [ticket] restrict_owner = false.
        """
        self.execute('config set ticket restrict_owner false')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'chown', 'component1', '')
        self.assertEqual([], output)

    def test_component_chown_complete_owner_restrict_owner_true(self):
        """Tests completion of the 'component chown <component>' command with
        [ticket] restrict_owner = true.
        """
        self.execute('config set ticket restrict_owner true')
        self.execute('session add user1')
        self.execute('session add user3')
        self.execute('permission add user1 TICKET_MODIFY')
        self.execute('permission add user2 TICKET_VIEW')
        self.execute('permission add user3 TICKET_MODIFY')
        output = self.complete_command('component', 'chown', 'component1', '')
        self.assertEqual(['user1', 'user3'], output)

    def test_component_chown_error_bad_component(self):
        """
        Tests the 'component chown' command in trac-admin.  This particular
        test tries to change the owner of a component that does not
        exist.
        """
        rv, output = self.execute('component chown bad_component changed_owner')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_component_remove_ok(self):
        """
        Tests the 'component remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('component remove component1')
        rv, output = self.execute('component list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_component_remove_error_bad_component(self):
        """
        Tests the 'component remove' command in trac-admin.  This particular
        test tries to remove a component that does not exist.
        """
        rv, output = self.execute('component remove bad_component')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_help(self):
        rv, output = self.execute('help ticket')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_ok(self):
        """Ticket is successfully deleted."""
        insert_ticket(self.env)
        rv, output = self.execute('ticket remove 1')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_error_no_ticket_argument(self):
        """Error reported when ticket# argument is missing."""
        rv, output = self.execute('ticket remove')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_error_ticket_id_not_an_int(self):
        """Error reported when ticket id is not an int."""
        insert_ticket(self.env)
        rv, output = self.execute('ticket remove a')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_remove_error_invalid_ticket_id(self):
        """ResourceNotFound error reported when ticket does not exist."""
        insert_ticket(self.env)
        rv, output = self.execute('ticket remove 2')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_ok(self):
        """Ticket comment is successfully deleted."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 1 1')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_no_ticket_argument(self):
        """Error reported when ticket# argument is missing."""
        rv, output = self.execute('ticket remove_comment')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_no_comment_argument(self):
        """Error reported when comment# argument is missing."""
        ticket = insert_ticket(self.env)
        rv, output = self.execute('ticket remove_comment 1')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_ticket_id_not_an_int(self):
        """ResourceNotFound error reported when comment does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment a 1')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_comment_id_not_an_int(self):
        """ResourceNotFound error reported when comment does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 1 a')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_invalid_ticket_id(self):
        """ResourceNotFound error reported when ticket does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 2 1')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_comment_remove_error_invalid_comment_id(self):
        """ResourceNotFound error reported when comment does not exist."""
        ticket = insert_ticket(self.env)
        ticket.save_changes('user1', 'the comment')
        rv, output = self.execute('ticket remove_comment 1 2')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_list_ok(self):
        """
        Tests the 'ticket_type list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_add_ok(self):
        """
        Tests the 'ticket_type add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type add new_type')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_add_error_already_exists(self):
        """
        Tests the 'ticket_type add' command in trac-admin.  This particular
        test passes a ticket type that already exists and checks for an error
        message.
        """
        rv, output = self.execute('ticket_type add defect')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_change_ok(self):
        """
        Tests the 'ticket_type change' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('ticket_type change defect bug')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_change_error_bad_type(self):
        """
        Tests the 'ticket_type change' command in trac-admin.  This particular
        test tries to change a priority that does not exist.
        """
        rv, output = self.execute('ticket_type change bad_type changed_type')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_change_error_bad_new_name(self):
        """
        Tests the 'ticket_type change' command in trac-admin.  This particular
        test tries to change a ticket type to another type that already exists.
        """
        rv, output = self.execute('ticket_type change defect task')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_remove_ok(self):
        """
        Tests the 'ticket_type remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type remove task')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_remove_error_bad_type(self):
        """
        Tests the 'ticket_type remove' command in trac-admin.  This particular
        test tries to remove a ticket type that does not exist.
        """
        rv, output = self.execute('ticket_type remove bad_type')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_order_down_ok(self):
        """
        Tests the 'ticket_type order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type order defect down')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_order_up_ok(self):
        """
        Tests the 'ticket_type order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('ticket_type order enhancement up')
        rv, output = self.execute('ticket_type list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_ticket_type_order_error_bad_type(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test tries to reorder a priority that does not exist.
        """
        rv, output = self.execute('ticket_type order bad_type up')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_help(self):
        rv, output = self.execute('help priority')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_list_ok(self):
        """
        Tests the 'priority list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_add_ok(self):
        """
        Tests the 'priority add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority add new_priority')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_add_many_ok(self):
        """
        Tests adding more than 10 priority values.  This makes sure that
        ordering is preserved when adding more than 10 values.
        """
        for i in xrange(11):
            self.execute('priority add p%s' % i)
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_add_error_already_exists(self):
        """
        Tests the 'priority add' command in trac-admin.  This particular
        test passes a priority name that already exists and checks for an
        error message.
        """
        rv, output = self.execute('priority add blocker')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_change_ok(self):
        """
        Tests the 'priority change' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('priority change major normal')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_change_error_bad_priority(self):
        """
        Tests the 'priority change' command in trac-admin.  This particular
        test tries to change a priority that does not exist.
        """
        rv, output = self.execute('priority change bad_priority changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_change_error_bad_new_name(self):
        """
        Tests the 'priority change' command in trac-admin.  This particular
        test tries to change a priority to a name that already exists.
        """
        rv, output = self.execute('priority change major minor')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_remove_ok(self):
        """
        Tests the 'priority remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority remove major')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_remove_error_bad_priority(self):
        """
        Tests the 'priority remove' command in trac-admin.  This particular
        test tries to remove a priority that does not exist.
        """
        rv, output = self.execute('priority remove bad_priority')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_priority_order_down_ok(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority order blocker down')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_order_up_ok(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('priority order critical up')
        rv, output = self.execute('priority list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_priority_order_error_bad_priority(self):
        """
        Tests the 'priority order' command in trac-admin.  This particular
        test tries to reorder a priority that does not exist.
        """
        rv, output = self.execute('priority remove bad_priority')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_help(self):
        rv, output = self.execute('help severity')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_list_ok(self):
        """
        Tests the 'severity list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_add_ok(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity add new_severity')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_add_error_already_exists(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes a severity name that already exists and checks for an
        error message.
        """
        self.execute('severity add blocker')
        rv, output = self.execute('severity add blocker')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_change_ok(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('severity add critical')
        self.execute('severity change critical "end-of-the-world"')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_change_error_bad_severity(self):
        """
        Tests the 'severity change' command in trac-admin.  This particular
        test tries to change a severity that does not exist.
        """
        rv, output = self.execute(
            'severity change bad_severity changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_change_error_bad_new_name(self):
        """
        Tests the 'severity change' command in trac-admin.  This particular
        test tries to change a severity to a name that already exists.
        """
        self.execute('severity add major')
        self.execute('severity add critical')
        rv, output = self.execute('severity change critical major')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_remove_ok(self):
        """
        Tests the 'severity add' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity remove trivial')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_remove_error_bad_severity(self):
        """
        Tests the 'severity remove' command in trac-admin.  This particular
        test tries to remove a severity that does not exist.
        """
        rv, output = self.execute('severity remove bad_severity')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_severity_order_down_ok(self):
        """
        Tests the 'severity order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity add foo')
        self.execute('severity add bar')
        self.execute('severity order foo down')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_order_up_ok(self):
        """
        Tests the 'severity order' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('severity add foo')
        self.execute('severity add bar')
        self.execute('severity order bar up')
        rv, output = self.execute('severity list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_severity_order_error_bad_severity(self):
        """
        Tests the 'severity order' command in trac-admin.  This particular
        test tries to reorder a priority that does not exist.
        """
        rv, output = self.execute('severity remove bad_severity')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_help_version_time(self):
        doc = self.get_command_help('version', 'time')
        self.assertIn(self.datetime_format_hint, doc)
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)

    def test_version_help(self):
        rv, output = self.execute('help version')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_list_ok(self):
        """
        Tests the 'version list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_add_ok(self):
        """
        Tests the 'version add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('version add 9.9 "%s"' % self._test_date)
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_add_too_many_arguments(self):
        rv, output = self.execute('version add 7.7 8.8 9.9')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_add_error_already_exists(self):
        """
        Tests the 'version add' command in trac-admin.  This particular
        test passes a version name that already exists and checks for an
        error message.
        """
        rv, output = self.execute(
            'version add 1.0 "%s"' % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_rename_ok(self):
        """
        Tests the 'version rename' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('version rename 1.0 9.9')
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_rename_error_bad_version(self):
        """
        Tests the 'version rename' command in trac-admin.  This particular
        test tries to rename a version that does not exist.
        """
        rv, output = self.execute(
            'version rename bad_version changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_rename_error_bad_new_name(self):
        """
        Tests the 'version rename' command in trac-admin.  This particular
        test tries to rename a version to a name that already exists.
        """
        rv, output = self.execute('version rename 1.0 2.0')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_time_ok(self):
        """
        Tests the 'version time' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('version time 2.0 "%s"' % self._test_date)
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_time_unset_ok(self):
        """
        Tests the 'version time' command in trac-admin.  This particular
        test passes valid arguments for unsetting the date.
        """
        self.execute('version time 2.0 "%s"' % self._test_date)
        self.execute('version time 2.0 ""')
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_time_error_bad_version(self):
        """
        Tests the 'version time' command in trac-admin.  This particular
        test tries to change the time on a version that does not exist.
        """
        rv, output = self.execute('version time bad_version "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_version_remove_ok(self):
        """
        Tests the 'version remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('version remove 1.0')
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_version_remove_error_bad_version(self):
        """
        Tests the 'version remove' command in trac-admin.  This particular
        test tries to remove a version that does not exist.
        """
        rv, output = self.execute('version remove bad_version')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_backslash_use_ok(self):
        if self.admin.interactive:
            self.execute('version add \\')
        else:
            self.execute(r"version add '\'")
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_help(self):
        rv, output = self.execute('help milestone')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_help_milestone_due(self):
        doc = self.get_command_help('milestone', 'due')
        self.assertIn(self.datetime_format_hint, doc)
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)

    def test_help_milestone_completed(self):
        doc = self.get_command_help('milestone', 'completed')
        self.assertIn(self.datetime_format_hint, doc)
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)

    def test_milestone_list_ok(self):
        """
        Tests the 'milestone list' command in trac-admin.  Since this command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_ok(self):
        """
        Tests the 'milestone add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('milestone add new_milestone "%s"' % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_utf8_ok(self):
        """
        Tests the 'milestone add' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute(u'milestone add \xa9tat_final "%s"'  # \xc2\xa9
                     % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_error_already_exists(self):
        """
        Tests the 'milestone add' command in trac-admin.  This particular
        test passes a milestone name that already exists and checks for an
        error message.
        """
        rv, output = self.execute('milestone add milestone1 "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_add_invalid_date(self):
        rv, output = self.execute('milestone add new_milestone <add>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'hint': self.datetime_format_hint,
            'isohint': get_datetime_format_hint('iso8601')
        })

    def test_milestone_rename_ok(self):
        """
        Tests the 'milestone rename' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('milestone rename milestone1 changed_milestone')
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_rename_error_bad_milestone(self):
        """
        Tests the 'milestone rename' command in trac-admin.  This particular
        test tries to rename a milestone that does not exist.
        """
        rv, output = self.execute(
            'milestone rename bad_milestone changed_name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_ok(self):
        """
        Tests the 'milestone due' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute('milestone due milestone2 "%s"' % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_unset_ok(self):
        """
        Tests the 'milestone due' command in trac-admin.  This particular
        test passes valid arguments for unsetting the due date.
        """
        self.execute('milestone due milestone2 "%s"' % self._test_date)
        self.execute('milestone due milestone2 ""')
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_error_bad_milestone(self):
        """
        Tests the 'milestone due' command in trac-admin.  This particular
        test tries to change the due date on a milestone that does not exist.
        """
        rv, output = self.execute('milestone due bad_milestone "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_due_invalid_date(self):
        rv, output = self.execute('milestone due milestone1 <due>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'hint': self.datetime_format_hint,
            'isohint': get_datetime_format_hint('iso8601')
        })

    def test_milestone_completed_ok(self):
        """
        Tests the 'milestone completed' command in trac-admin.  This particular
        test passes valid arguments and checks for success.
        """
        self.execute(
            'milestone completed milestone2 "%s"' % self._test_date)
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_completed_error_bad_milestone(self):
        """
        Tests the 'milestone completed' command in trac-admin.  This particular
        test tries to change the completed date on a milestone that does not
        exist.
        """
        rv, output = self.execute('milestone completed bad_milestone "%s"'
                                  % self._test_date)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_completed_invalid_date(self):
        rv, output = self.execute('milestone completed milestone1 <com>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'hint': self.datetime_format_hint,
            'isohint': get_datetime_format_hint('iso8601')
        })

    def test_milestone_remove_ok(self):
        """
        Tests the 'milestone remove' command in trac-admin.  This particular
        test passes a valid argument and checks for success.
        """
        self.execute('milestone remove milestone3')
        rv, output = self.execute('milestone list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_milestone_remove_error_bad_milestone(self):
        """
        Tests the 'milestone remove' command in trac-admin.  This particular
        test tries to remove a milestone that does not exist.
        """
        rv, output = self.execute('milestone remove bad_milestone')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Ejemplo n.º 10
0
class TracadminTestCase(TracAdminTestCaseBase):
    """
    Tests the output of trac-admin and is meant to be used with
    .../trac/tests.py.
    """
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env = None

    @property
    def datetime_format_hint(self):
        return get_datetime_format_hint(get_console_locale(self.env))

    def test_python_with_optimizations_returns_error(self):
        """Error is returned when a command is executed in interpreter
        with optimizations enabled.
        """
        with Popen((sys.executable, '-O', '-m', 'trac.admin.console', 'help'),
                   stdin=PIPE,
                   stdout=PIPE,
                   stderr=PIPE,
                   close_fds=close_fds) as proc:
            stdout, stderr = proc.communicate(input='')
        self.assertEqual(2, proc.returncode)
        self.assertEqual("Python with optimizations is not supported.",
                         stderr.strip())

    # Help test

    def test_help_ok(self):
        """
        Tests the 'help' command in trac-admin.  Since the 'help' command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('help')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'version': self.env.trac_version,
                'date_format_hint': get_date_format_hint()
            })
        self.assertTrue(all(len(line) < 80 for line in output.split('\n')),
                        "Lines should be less than 80 characters in length.")

    # Locale test

    def _test_get_console_locale_with_babel(self):
        from babel.core import Locale, UnknownLocaleError
        locales = get_available_locales()
        en_US = Locale.parse('en_US')
        de = Locale.parse('de')

        def unset_locale_envs():
            for name in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
                if name in os.environ:
                    del os.environ[name]

        if 'de' in locales:
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, None))
            self.assertEqual(de, get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertEqual(de, get_console_locale(self.env, None))
            self.assertEqual(de, get_console_locale(self.env, 'C'))
            self.env.config.set('trac', 'default_language', 'en_US')
            self.assertEqual(en_US, get_console_locale(self.env, None))
            self.assertEqual(en_US, get_console_locale(self.env, 'C'))
            self.assertEqual(de, get_console_locale(self.env, 'de_DE.UTF8'))

            self.env.config.set('trac', 'default_language', 'de')
            os.environ['LANG'] = 'POSIX'  # unavailable locale in Trac
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = '****'  # invalid locale
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LC_ALL'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LANGUAGE'] = 'de_DE:en_US:en'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))

        if not locales:  # compiled catalog is missing
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertIsNone(get_console_locale(self.env, None))
            self.assertIsNone(get_console_locale(self.env, 'C'))
            self.assertIsNone(get_console_locale(self.env, 'de_DE.UTF8'))
            os.environ['LANG'] = 'en_US.utf-8'
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            os.environ['LC_ALL'] = 'en_US.utf-8'
            os.environ['LANGUAGE'] = 'de_DE:en_US'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))

    def _test_get_console_locale_without_babel(self):
        os.environ['LANG'] = 'en_US.utf-8'
        os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
        os.environ['LC_ALL'] = 'en_US.utf-8'
        os.environ['LANGUAGE'] = 'de_DE:en_US'
        self.assertIsNone(get_console_locale(None, 'en_US.UTF8'))
        self.env.config.set('trac', 'default_language', '')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))
        self.env.config.set('trac', 'default_language', 'en_US')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))

    if has_babel:
        test_get_console_locale = _test_get_console_locale_with_babel
    else:
        test_get_console_locale = _test_get_console_locale_without_babel

    # Attachment tests

    def test_attachment_list_empty(self):
        """
        Tests the 'attachment list' command in trac-admin, on a wiki page that
        doesn't have any attachments.
        """
        # FIXME: Additional tests should be written for the other 'attachment'
        #        commands. This requires being able to control the current
        #        time, which in turn would require centralizing the time
        #        provider, for example in the environment object.
        rv, output = self.execute('attachment list wiki:WikiStart')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_attachment_add_nonexistent_resource(self):
        """Tests the 'attachment add' command in trac-admin, on a non-existent
        resource."""
        rv, output = self.execute('attachment add wiki:NonExistentPage "%s"' %
                                  __file__)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    # Config tests

    def test_config_get(self):
        """
        Tests the 'config get' command in trac-admin.  This particular
        test gets the project name from the config.
        """
        self.env.config.set('project', 'name', 'Test project')
        rv, output = self.execute('config get project name')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_config_set(self):
        """
        Tests the 'config set' command in trac-admin.  This particular
        test sets the project name using an option value containing a space.
        """
        rv, output = self.execute('config set project name "Test project"')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertEqual('Test project',
                         self.env.config.get('project', 'name'))

    def test_config_remove(self):
        """
        Tests the 'config remove' command in trac-admin.  This particular
        test removes the project name from the config, therefore reverting
        the option to the default value.
        """
        self.env.config.set('project', 'name', 'Test project')
        rv, output = self.execute('config remove project name')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        self.assertEqual('My Project', self.env.config.get('project', 'name'))

    # Permission tests

    def test_permission_list_ok(self):
        """Tests the 'permission list' command in trac-admin."""
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_list_includes_undefined_actions(self):
        """Undefined actions are included in the User Action table,
        but not in the Available Actions list.
        """
        self.env.disable_component(trac.search.web_ui.SearchModule)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_one_action_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add one permission and checks for
        success.
        """
        self.execute('permission add test_user WIKI_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_multiple_actions_ok(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes valid arguments to add multiple permissions and checks for
        success.
        """
        self.execute('permission add test_user LOG_VIEW FILE_VIEW')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_add_already_exists(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that already exists and checks for the
        message. Other permissions passed are added.
        """
        rv, output = self.execute('permission add anonymous WIKI_CREATE '
                                  'WIKI_VIEW WIKI_MODIFY')
        self.assertEqual(0, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_subject_already_in_group(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a group that the subject is already a member of and
        checks for the message. Other permissions passed are added.
        """
        rv, output1 = self.execute('permission add user1 group2')
        self.assertEqual(0, rv, output1)
        rv, output2 = self.execute('permission add user1 group1 group2 '
                                   'group3')
        self.assertEqual(0, rv, output2)
        rv, output3 = self.execute('permission list')
        self.assertEqual(0, rv, output3)
        self.assertExpectedResult(output2 + output3)

    def test_permission_add_differs_from_action_by_casing(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test passes a permission that differs from an action by casing and
        checks for the message. None of the permissions in the list are
        granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'Trac_Admin WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_add_unknown_action(self):
        """
        Tests the 'permission add' command in trac-admin.  This particular
        test tries granting NOT_A_PERM to a user. NOT_A_PERM does not exist
        in the system. None of the permissions in the list are granted.
        """
        rv, output = self.execute('permission add joe WIKI_CREATE '
                                  'NOT_A_PERM WIKI_MODIFY')
        self.assertEqual(2, rv, output)
        rv, output2 = self.execute('permission list')
        self.assertEqual(0, rv, output2)
        self.assertExpectedResult(output + output2)

    def test_permission_remove_one_action_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove one permission and checks for
        success.
        """
        self.execute('permission remove anonymous TICKET_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_multiple_actions_ok(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test passes valid arguments to remove multiple permission and checks
        for success.
        """
        self.execute('permission remove anonymous WIKI_CREATE WIKI_MODIFY')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_all_actions_for_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes all permissions for anonymous.
        """
        self.execute('permission remove anonymous *')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_for_all_users(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test removes the TICKET_CREATE permission from all users.
        """
        self.execute('permission add anonymous TICKET_CREATE')
        self.execute('permission remove * TICKET_CREATE')
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_user(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing a permission from an unknown user.
        """
        rv, output = self.execute('permission remove joe TICKET_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_not_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing TICKET_CREATE from user anonymous, who doesn't
        have that permission.
        """
        rv, output = self.execute('permission remove anonymous TICKET_CREATE')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_action_granted_through_meta_permission(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing WIKI_VIEW from a user. WIKI_VIEW has been granted
        through user anonymous."""
        self.execute('permission add joe TICKET_VIEW')
        rv, output = self.execute('permission remove joe WIKI_VIEW')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system."""
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_permission_remove_unknown_action_granted(self):
        """
        Tests the 'permission remove' command in trac-admin.  This particular
        test tries removing NOT_A_PERM from a user. NOT_A_PERM does not exist
        in the system, but the user possesses the permission."""
        self.env.db_transaction(
            """
            INSERT INTO permission VALUES (%s, %s)
        """, ('joe', 'NOT_A_PERM'))
        rv, output = self.execute('permission remove joe NOT_A_PERM')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_export_ok(self):
        """
        Tests the 'permission export' command in trac-admin.  This particular
        test exports the default permissions to stdout.
        """
        rv, output = self.execute('permission export')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_permission_import_ok(self):
        """
        Tests the 'permission import' command in trac-admin.  This particular
        test exports additional permissions, removes them and imports them back.
        """
        user = u'test_user\u0250'
        self.execute('permission add ' + user + ' WIKI_VIEW')
        self.execute('permission add ' + user + ' TICKET_VIEW')
        rv, output = self.execute('permission export')
        self.execute('permission remove ' + user + ' *')
        rv, output = self.execute('permission import', input=output)
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('permission list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_backslash_use_ok(self):
        if self.admin.interactive:
            self.execute('version add \\')
        else:
            self.execute(r"version add '\'")
        rv, output = self.execute('version list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_no_sessions(self):
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list anonymous')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_all(self):
        _prep_session_table(self.env)
        if self.admin.interactive:
            rv, output = self.execute("session list *")
        else:
            rv, output = self.execute("session list '*'")
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name00')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name10:0')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_missing_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list thisdoesntexist')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_missing_sid(self):
        rv, output = self.execute('session add')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_duplicate_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session add name00')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_sid_all(self):
        rv, output = self.execute('session add john John [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid(self):
        rv, output = self.execute('session add john')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid_name(self):
        rv, output = self.execute('session add john John')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_set_attr_name(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set name name00 JOHN')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_email(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set email name00 [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler(self):
        _prep_session_table(self.env)
        rv, output = \
            self.execute('session set default_handler name00 SearchModule')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler_invalid(self):
        _prep_session_table(self.env)
        rv, output = \
            self.execute('session set default_handler name00 InvalidModule')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_attr(self):
        rv, output = self.execute('session set')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_value(self):
        rv, output = self.execute('session set name john')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_sid(self):
        rv, output = self.execute('session set name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_nonexistent_sid(self):
        rv, output = self.execute('session set name john foo')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list nam00')
        self.assertExpectedResult(output)

    def test_session_delete_missing_params(self):
        rv, output = self.execute('session delete')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete anonymous')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_delete_multiple_sids(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00 name01 name02 '
                                  'name03')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_age(self):
        _prep_session_table(self.env, spread_visits=True)
        rv, output = self.execute('session purge 20100112')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_invalid_date(self):
        rv, output = self.execute('session purge <purge>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(
            output, {
                'hint': self.datetime_format_hint,
                'isohint': get_datetime_format_hint('iso8601')
            })

    def test_help_session_purge(self):
        doc = self.get_command_help('session', 'purge')
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)
Ejemplo n.º 11
0
class TracAdminTestCase(TracAdminTestCaseBase):
    def setUp(self):
        self.env = EnvironmentStub(default_data=True,
                                   enable=('trac.*', ),
                                   disable=('trac.tests.*', ))
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self.tempdir = mkdtemp()

    def tearDown(self):
        self.env = None

    def _insert_page(self, name=None):
        page = WikiPage(self.env)
        if name is None:
            name = random_unique_camel()
        page.name = name
        page.text = random_paragraph()
        page.save('user1', 'Page created.')
        return name

    def _insert_pages(self, int_or_names):
        if isinstance(int_or_names, int):
            names = sorted(random_unique_camel()
                           for _ in range(0, int_or_names))
        else:
            names = sorted(int_or_names)
        return [self._insert_page(n) for n in names]

    def _change_page(self, name):
        page = WikiPage(self.env, name)
        page.text = random_paragraph()
        page.save('user2', 'Page changed.')

    def _file_content(self, dir_or_path, name=None):
        path = dir_or_path if name is None else os.path.join(dir_or_path, name)
        with open(path, 'r') as f:
            return f.read()

    def _write_file(self, path, content=None):
        if content is None:
            content = random_paragraph()
        with open(path, 'w') as f:
            f.write(content)
        return content

    def execute(self, cmd, *args):
        argstr = ' '.join('"%s"' % a for a in args)
        return super(TracAdminTestCase, self) \
               .execute('wiki {} {}'.format(cmd, argstr))

    def assertFileContentMatchesPage(self, names):
        for n in names:
            self.assertEqual(
                WikiPage(self.env, n).text,
                self._file_content(self.tempdir, n))

    def test_wiki_dump(self):
        names = self._insert_pages(2)
        rv, output = self.execute('dump', self.tempdir, *names)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(self.tempdir, names[0]),
                'path2': os.path.join(self.tempdir, names[1]),
            })
        self.assertFileContentMatchesPage(names)

    def test_wiki_dump_all(self):
        names = self._insert_pages(2)
        rv, output = self.execute('dump', self.tempdir)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(self.tempdir, names[0]),
                'path2': os.path.join(self.tempdir, names[1]),
            })
        self.assertEquals(names, sorted(os.listdir(self.tempdir)))
        self.assertFileContentMatchesPage(names)

    def test_wiki_dump_all_create_dst_dir(self):
        names = self._insert_pages(2)
        dstdir = os.path.join(self.tempdir, 'subdir')
        rv, output = self.execute('dump', dstdir)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(dstdir, names[0]),
                'path2': os.path.join(dstdir, names[1]),
            })
        self.assertEquals(names, sorted(os.listdir(dstdir)))

    def test_wiki_dump_all_glob(self):
        names = self._insert_pages(['PageOne', 'PageTwo', 'ThreePage'])
        rv, output = self.execute('dump', self.tempdir, 'Page*')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'name1': names[0],
                'name2': names[1],
                'path1': os.path.join(self.tempdir, names[0]),
                'path2': os.path.join(self.tempdir, names[1]),
            })
        self.assertEquals(names[0:2], sorted(os.listdir(self.tempdir)))
        self.assertFileContentMatchesPage(names[0:2])

    def test_wiki_dump_all_dst_is_file(self):
        tempdir = os.path.join(self.tempdir, 'dst')
        create_file(tempdir)
        rv, output = self.execute('dump', tempdir)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'dstdir': tempdir,
        })

    def test_wiki_export(self):
        name = self._insert_page()
        export_path = os.path.join(self.tempdir, name)
        rv, output = self.execute('export', name, export_path)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': export_path,
        })
        self.assertFileContentMatchesPage([name])

    def test_wiki_export_page_not_found(self):
        name = random_unique_camel()
        export_path = os.path.join(self.tempdir, name)
        rv, output = self.execute('export', name, export_path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
        })

    def test_wiki_export_file_exists(self):
        name = self._insert_page()
        export_path = os.path.join(self.tempdir, name)
        create_file(export_path)
        rv, output = self.execute('export', name, export_path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'export_path': export_path,
        })

    def test_wiki_export_print_to_stdout(self):
        name = self._insert_page()
        rv, output = self.execute('export', name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'content': WikiPage(self.env, name).text,
        })

    def test_wiki_import(self):
        name = random_unique_camel()
        import_path = os.path.join(self.tempdir, name)
        content = self._write_file(import_path)
        rv, output = self.execute('import', name, import_path)
        page = WikiPage(self.env, name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': import_path,
        })
        self.assertIn(('INFO', '%s imported from %s' % (name, import_path)),
                      self.env.log_messages)
        self.assertEqual(content, page.text)

    def test_wiki_import_page_exists(self):
        name = self._insert_page()
        import_path = os.path.join(self.tempdir, name)
        self._write_file(import_path)
        rv, output = self.execute('import', name, import_path)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': import_path,
        })
        self.assertEqual(2, WikiPage(self.env, name).version)

    def test_wiki_import_page_up_to_date(self):
        name = self._insert_page()
        import_path = os.path.join(self.tempdir, name)
        self._write_file(import_path, WikiPage(self.env, name).text)
        rv, output = self.execute('import', name, import_path)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'tempdir': self.tempdir,
            'name': name,
        })
        self.assertIn(('INFO', '%s is already up to date' % name),
                      self.env.log_messages)
        self.assertEqual(1, WikiPage(self.env, name).version)

    def test_wiki_import_page_name_invalid(self):
        name = 'PageOne/../PageTwo'
        import_path = os.path.join(self.tempdir, 'PageOne')
        self._write_file(import_path)
        rv, output = self.execute('import', name, import_path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'tempdir': self.tempdir,
            'name': name
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_import_file_not_found(self):
        name = random_unique_camel()
        import_path = os.path.join(self.tempdir, name)
        rv, output = self.execute('import', name, import_path)
        page = WikiPage(self.env, name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'import_path': import_path,
        })

    def test_wiki_list(self):
        name1 = self._insert_page('PageOne')
        name2 = self._insert_page('PageTwo')
        self._change_page(name2)
        rv, output = self.execute('list')
        self.assertEqual(0, rv, output)
        fmt = lambda m: format_datetime(m, console_datetime_format)
        self.assertExpectedResult(
            output, {
                'page1_modified': fmt(WikiPage(self.env, name1).time),
                'page2_modified': fmt(WikiPage(self.env, name2).time),
            })

    def test_wiki_list_no_pages(self):
        rv, output = self.execute('list')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_wiki_load(self):
        name1 = 'PageOne'
        name2 = 'PageTwo'
        path1 = os.path.join(self.tempdir, name1)
        path2 = os.path.join(self.tempdir, name2)
        content1 = random_paragraph()
        content2 = random_paragraph()
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        rv, output = self.execute('load', path1, path2)
        page1 = WikiPage(self.env, name1)
        page2 = WikiPage(self.env, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
            'path1': path1,
            'path2': path2,
        })
        self.assertIn(('INFO', '%s imported from %s' % (name1, path1)),
                      self.env.log_messages)
        self.assertIn(('INFO', '%s imported from %s' % (name2, path2)),
                      self.env.log_messages)
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_load_page_exists(self):
        name = self._insert_page()
        path = os.path.join(self.tempdir, name)
        content = self._write_file(path)
        rv, output = self.execute('load', path)
        page = WikiPage(self.env, name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': path,
        })
        self.assertEqual(content, page.text)
        self.assertEqual(2, page.version)

    def test_wiki_load_pages_from_dir(self):
        name1 = 'PageOne'
        name2 = 'PageTwo'
        path1 = os.path.join(self.tempdir, name1)
        path2 = os.path.join(self.tempdir, name2)
        content1 = random_paragraph()
        content2 = random_paragraph()
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        os.mkdir(os.path.join(self.tempdir, 'subdir'))
        rv, output = self.execute('load', self.tempdir)
        page1 = WikiPage(self.env, name1)
        page2 = WikiPage(self.env, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
            'path1': path1,
            'path2': path2,
        })
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_load_from_invalid_path(self):
        name = random_unique_camel()
        path = os.path.join(self.tempdir, name)
        rv, output = self.execute('load', path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'path': path,
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_remove(self):
        name = self._insert_page()

        rv, output = self.execute('remove', name)
        self.assertIn(('INFO', 'Deleted page %s' % name),
                      self.env.log_messages)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_remove_glob(self):
        names = self._insert_pages(['PageOne', 'PageTwo', 'PageThree'])

        rv, output = self.execute('remove', 'Page*')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
        for n in names:
            self.assertIn(('INFO', 'Deleted page %s' % n),
                          self.env.log_messages)
            self.assertFalse(WikiPage(self.env, n).exists)

    def test_wiki_rename(self):
        name1 = self._insert_page()
        name2 = random_unique_camel()

        rv, output = self.execute('rename', name1, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
        })
        self.assertIn(('INFO', 'Renamed page %s to %s' % (name1, name2)),
                      self.env.log_messages)
        self.assertFalse(WikiPage(self.env, name1).exists)
        self.assertTrue(WikiPage(self.env, name2).exists)

    def test_wiki_rename_name_unchanged(self):
        name = self._insert_page()

        rv, output = self.execute('rename', name, name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
        self.assertTrue(WikiPage(self.env, name).exists)

    def test_wiki_rename_name_not_specified(self):
        name = self._insert_page()

        rv, output = self.execute('rename', name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_wiki_rename_new_name_invalid(self):
        name = self._insert_page()
        new_name = 'PageOne/../PageTwo'

        rv, output = self.execute('rename', name, new_name)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'name': new_name,
        })
        self.assertTrue(WikiPage(self.env, name).exists)

    def test_wiki_rename_new_page_exists(self):
        names = self._insert_pages(['PageOne', 'PageTwo'])
        page1_content = WikiPage(self.env, names[0]).text
        page2_content = WikiPage(self.env, names[1]).text

        rv, output = self.execute('rename', *names)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
        page1 = WikiPage(self.env, names[0])
        page2 = WikiPage(self.env, names[1])
        self.assertTrue(page1.exists)
        self.assertTrue(page2.exists)
        self.assertEqual(page1_content, page1.text)
        self.assertEqual(page2_content, page2.text)

    def test_wiki_replace(self):
        name1 = random_unique_camel()
        name2 = random_unique_camel()
        path1 = os.path.join(self.tempdir, name1)
        path2 = os.path.join(self.tempdir, name2)
        content1 = random_paragraph()
        content2 = random_paragraph()
        self._insert_page(name1)
        self._insert_page(name2)
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        rv, output = self.execute('replace', path1, path2)
        page1 = WikiPage(self.env, name1)
        page2 = WikiPage(self.env, name2)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': name1,
            'name2': name2,
            'path1': path1,
            'path2': path2,
        })
        self.assertIn(('INFO', '%s imported from %s' % (name1, path1)),
                      self.env.log_messages)
        self.assertIn(('INFO', '%s imported from %s' % (name2, path2)),
                      self.env.log_messages)
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_replace_new_page(self):
        name = random_unique_camel()
        path = os.path.join(self.tempdir, name)
        content = self._write_file(path)
        rv, output = self.execute('replace', path)
        page = WikiPage(self.env, name)
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name': name,
            'path': path,
        })
        self.assertEqual(1, page.version)
        self.assertEqual(content, page.text)

    def test_wiki_replace_pages_from_dir(self):
        names = self._insert_pages(2)
        path1 = os.path.join(self.tempdir, names[0])
        path2 = os.path.join(self.tempdir, names[1])
        content1 = random_paragraph()
        content2 = random_paragraph()
        with open(path1, 'w') as f:
            f.write(content1)
        with open(path2, 'w') as f:
            f.write(content2)
        os.mkdir(os.path.join(self.tempdir, 'subdir'))
        rv, output = self.execute('replace', self.tempdir)
        page1 = WikiPage(self.env, names[0])
        page2 = WikiPage(self.env, names[1])
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'name1': names[0],
            'name2': names[1],
            'path1': path1,
            'path2': path2,
        })
        self.assertEqual(content1, page1.text)
        self.assertEqual(content2, page2.text)
        self.assertEqual(1, page1.version)
        self.assertEqual(1, page2.version)

    def test_wiki_replace_from_invalid_path(self):
        name = random_unique_camel()
        path = os.path.join(self.tempdir, name)
        rv, output = self.execute('replace', path)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output, {
            'path': path,
        })
        self.assertFalse(WikiPage(self.env, name).exists)

    def test_wiki_upgrade(self):
        rv, output = self.execute('upgrade')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_wiki_upgrade_up_to_date(self):
        self.execute('upgrade')
        rv, output = self.execute('upgrade')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)
Ejemplo n.º 12
0
class TracadminTestCase(TracAdminTestCaseBase):
    """
    Tests the output of trac-admin and is meant to be used with
    .../trac/tests.py.
    """
    def setUp(self):
        self.env = EnvironmentStub()
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env = None

    def test_help_ok(self):
        """
        Tests the 'help' command in trac-admin.  Since the 'help' command
        has no command arguments, it is hard to call it incorrectly.  As
        a result, there is only this one test.
        """
        rv, output = self.execute('help')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(
            output, {
                'version': self.env.trac_version,
                'date_format_hint': get_date_format_hint()
            })
        self.assertTrue(all(len(line) < 80 for line in output.split('\n')),
                        "Lines should be less than 80 characters in length.")

    def _test_get_console_locale_with_babel(self):
        locales = get_available_locales()
        en_US = Locale.parse('en_US')
        de = Locale.parse('de')

        def unset_locale_envs():
            for name in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
                if name in os.environ:
                    del os.environ[name]

        if 'de' in locales:
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, None))
            self.assertEqual(de, get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertEqual(de, get_console_locale(self.env, None))
            self.assertEqual(de, get_console_locale(self.env, 'C'))
            self.env.config.set('trac', 'default_language', 'en_US')
            self.assertEqual(en_US, get_console_locale(self.env, None))
            self.assertEqual(en_US, get_console_locale(self.env, 'C'))
            self.assertEqual(de, get_console_locale(self.env, 'de_DE.UTF8'))

            self.env.config.set('trac', 'default_language', 'de')
            os.environ['LANG'] = 'POSIX'  # unavailable locale in Trac
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = '****'  # invalid locale
            self.assertIsNone(get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LANG'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))
            os.environ['LC_ALL'] = 'en_US.utf-8'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))
            os.environ['LANGUAGE'] = 'de_DE:en_US:en'
            self.assertEqual(de, get_console_locale())
            self.assertEqual(de, get_console_locale(self.env))

        if not locales:  # compiled catalog is missing
            unset_locale_envs()
            self.assertIsNone(get_console_locale(None, 'de_DE.UTF8'))
            self.env.config.set('trac', 'default_language', 'de')
            self.assertIsNone(get_console_locale(self.env, None))
            self.assertIsNone(get_console_locale(self.env, 'C'))
            self.assertIsNone(get_console_locale(self.env, 'de_DE.UTF8'))
            os.environ['LANG'] = 'en_US.utf-8'
            os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
            os.environ['LC_ALL'] = 'en_US.utf-8'
            os.environ['LANGUAGE'] = 'de_DE:en_US'
            self.assertEqual(en_US, get_console_locale())
            self.assertEqual(en_US, get_console_locale(self.env))

    def _test_get_console_locale_without_babel(self):
        os.environ['LANG'] = 'en_US.utf-8'
        os.environ['LC_MESSAGES'] = 'de_DE.utf-8'
        os.environ['LC_ALL'] = 'en_US.utf-8'
        os.environ['LANGUAGE'] = 'de_DE:en_US'
        self.assertIsNone(get_console_locale(None, 'en_US.UTF8'))
        self.env.config.set('trac', 'default_language', '')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))
        self.env.config.set('trac', 'default_language', 'en_US')
        self.assertIsNone(get_console_locale(self.env, 'en_US.UTF8'))
        self.assertIsNone(get_console_locale(self.env))

    if has_babel:
        test_get_console_locale = _test_get_console_locale_with_babel
    else:
        test_get_console_locale = _test_get_console_locale_without_babel
Ejemplo n.º 13
0
class TracAdminTestCase(TracAdminTestCaseBase):
    """
    Tests the output of trac-admin and is meant to be used with
    .../trac/tests.py.
    """

    expected_results_filename = 'attachment-console-tests.txt'

    def setUp(self):
        self.env = EnvironmentStub(default_data=True, enable=('trac.*',),
                                   disable=('trac.tests.*',))
        self.env.path = mkdtemp()
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)
        self.datetime = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
        with self.env.db_transaction as db:
            db("INSERT INTO wiki (name,version) VALUES ('WikiStart',1)")
            db("INSERT INTO wiki (name,version) VALUES ('SomePage',1)")
            db("INSERT INTO ticket (id) VALUES (42)")
            db("INSERT INTO ticket (id) VALUES (43)")
            db("INSERT INTO attachment VALUES (%s,%s,%s,%s,%s,%s,%s)",
               ('ticket', '43', 'foo.txt', 8, to_utimestamp(self.datetime),
                'A comment', 'joe'))

    def tearDown(self):
        self.env.reset_db_and_disk()

    def test_attachment_list(self):
        """Attachment list command."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)
        rv, output = self.execute('attachment list wiki:SomePage')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'date': format_datetime(attachment.date, console_datetime_format)
        })

    def test_attachment_list_empty(self):
        """Attachment list command with no output."""
        rv, output = self.execute('attachment list wiki:WikiStart')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_attachment_add_nonexistent_resource(self):
        """Error raised when adding an attachment to a non-existent resource.
        """
        rv, output = self.execute('attachment add wiki:NonExistentPage "%s"'
                                  % __file__)
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_attachment_rename(self):
        """Rename attachment."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)

        rv, output = self.execute('attachment move wiki:SomePage foo.txt '
                                  'wiki:SomePage bar.txt')
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('attachment list wiki:SomePage')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'date': format_datetime(attachment.date, console_datetime_format)
        })

    def test_attachment_reparent(self):
        """Reparent attachment to another resource."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)

        rv, output = self.execute('attachment move wiki:SomePage foo.txt '
                                  'wiki:WikiStart foo.txt')
        self.assertEqual(0, rv, output)
        self.assertEqual('', output)
        rv, output = self.execute('attachment list wiki:SomePage')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('attachment list wiki:WikiStart')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output, {
            'date': format_datetime(attachment.date, console_datetime_format)
        })

    def test_attachment_move_nonexistent_resource(self):
        """Error raised when reparenting attachment to another resource."""
        attachment = Attachment(self.env, 'wiki', 'SomePage')
        attachment.insert('foo.txt', io.BytesIO(), 0)

        rv, output = self.execute('attachment move wiki:SomePage foo.txt '
                                  'wiki:NonExistentPage foo.txt')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)
Ejemplo n.º 14
0
class TracAdminTestCase(TracAdminTestCaseBase):

    request_handlers = []

    @classmethod
    def setUpClass(cls):
        class DefaultHandlerStub(Component):
            implements(IRequestHandler)

            def match_request(self, req):
                pass

            def process_request(req):
                pass

        cls.request_handlers = [DefaultHandlerStub]

    @classmethod
    def tearDownClass(cls):
        for component in cls.request_handlers:
            ComponentMeta.deregister(component)

    def setUp(self):
        self.env = EnvironmentStub()
        self.admin = TracAdmin()
        self.admin.env_set('', self.env)

    def tearDown(self):
        self.env = None

    @property
    def datetime_format_hint(self):
        return get_datetime_format_hint(get_console_locale(self.env))

    def test_session_list_no_sessions(self):
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list authenticated')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list anonymous')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_all(self):
        _prep_session_table(self.env)
        if self.admin.interactive:
            rv, output = self.execute("session list *")
        else:
            rv, output = self.execute("session list '*'")
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_authenticated_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name00')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_anonymous_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list name10:0')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_list_missing_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session list thisdoesntexist')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_missing_sid(self):
        rv, output = self.execute('session add')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_duplicate_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session add name00')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_add_sid_all(self):
        rv, output = self.execute('session add john John [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid(self):
        rv, output = self.execute('session add john')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_add_sid_name(self):
        rv, output = self.execute('session add john John')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list john')
        self.assertExpectedResult(
            output, {'today': format_date(None, console_date_format)})

    def test_session_set_attr_name(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set name name00 JOHN')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_email(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set email name00 [email protected]')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session set default_handler name00 '
                                  'DefaultHandlerStub')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list name00')
        self.assertExpectedResult(output)

    def test_session_set_attr_default_handler_invalid(self):
        _prep_session_table(self.env)
        rv, output = \
            self.execute('session set default_handler name00 InvalidModule')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_attr(self):
        rv, output = self.execute('session set')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_value(self):
        rv, output = self.execute('session set name john')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_missing_sid(self):
        rv, output = self.execute('session set name')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_set_attr_nonexistent_sid(self):
        rv, output = self.execute('session set name john foo')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_sid(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list nam00')
        self.assertExpectedResult(output)

    def test_session_delete_missing_params(self):
        rv, output = self.execute('session delete')
        self.assertEqual(0, rv, output)
        self.assertExpectedResult(output)

    def test_session_delete_anonymous(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete anonymous')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_delete_multiple_sids(self):
        _prep_session_table(self.env)
        rv, output = self.execute('session delete name00 name01 name02 '
                                  'name03')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_age(self):
        _prep_session_table(self.env, spread_visits=True)
        rv, output = self.execute('session purge 20100112')
        self.assertEqual(0, rv, output)
        rv, output = self.execute('session list *')
        self.assertExpectedResult(output)

    def test_session_purge_invalid_date(self):
        rv, output = self.execute('session purge <purge>')
        self.assertEqual(2, rv, output)
        self.assertExpectedResult(
            output, {
                'hint': self.datetime_format_hint,
                'isohint': get_datetime_format_hint('iso8601')
            })

    def test_help_session_purge(self):
        doc = self.get_command_help('session', 'purge')
        self.assertIn(u'"YYYY-MM-DDThh:mm:ss±hh:mm"', doc)