Commits

Anonymous committed 7d03343

0.13dev: Merged from 0.12-stable.

Comments (0)

Files changed (5)

trac/templates/layout.html

     </title>
     <meta py:if="chrome.content_type == 'text/html'" http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <meta py:for="meta in chrome.metas" py:attrs="meta"/>
+    <!--[if IE]><script type="text/javascript">window.location.hash = window.location.hash;</script><![endif]-->
     <py:if test="chrome.links">
       <py:for each="rel, links in chrome.links.items()">
         <link rel="${rel}" py:for="link in links" py:attrs="link" />

trac/ticket/query.py

                     if val[:1] in ('~', '^', '$') \
                                         and not val in self.substitutions:
                         mode, val = val[:1], val[1:]
+                    val = val.replace('$USER', req.authname)
                     constraint['mode'] = ('!' if neg else '') + mode
                     constraint['values'].append(val)
                 constraints[k] = constraint
                 args = arg_list_to_args(arg_list)
                 constraints = self._get_constraints(arg_list=arg_list)
             else:
-                constraints = Query.from_string(self.env, qstring).constraints
-                # Substitute $USER, or ensure no field constraints that depend
-                # on $USER are used if we have no username.
-                for clause in constraints:
-                    for field, vals in clause.items():
-                        for (i, val) in enumerate(vals):
-                            if user:
-                                vals[i] = val.replace('$USER', user)
-                            elif val.endswith('$USER'):
-                                del clause[field]
-                                break
+                query = Query.from_string(self.env, qstring)
+                args = {'order': query.order, 'group': query.group,
+                        'col': query.cols, 'max': query.max}
+                if query.desc:
+                    args['desc'] = '1'
+                if query.groupdesc:
+                    args['groupdesc'] = '1'
+                constraints = query.constraints
+
+            # Substitute $USER, or ensure no field constraints that depend
+            # on $USER are used if we have no username.
+            for clause in constraints:
+                for field, vals in clause.items():
+                    for (i, val) in enumerate(vals):
+                        if user:
+                            vals[i] = val.replace('$USER', user)
+                        elif val.endswith('$USER'):
+                            del clause[field]
+                            break
 
         cols = args.get('col')
         if isinstance(cols, basestring):

trac/ticket/tests/functional.py

                 '<td class="owner"></td>', 's')
 
 
+class RegressionTestTicket7821group(FunctionalTwillTestCaseSetup):
+    def runTest(self):
+        """Test for regression of http://trac.edgewall.org/ticket/7821 group"""
+        env = self._testenv.get_trac_environment()
+        saved_default_query = env.config.get('query', 'default_query')
+        default_query = 'status!=closed&order=status&group=status&max=42' \
+                        '&desc=1&groupdesc=1&col=summary|status|cc' \
+                        '&cc~=$USER'
+        env.config.set('query', 'default_query', default_query)
+        env.config.save()
+        try:
+            self._testenv.restart()
+            self._tester.create_ticket('RegressionTestTicket7821 group')
+            self._tester.go_to_query()
+            # $USER
+            tc.find('<input type="text" name="0_cc" value="admin"'
+                    ' size="[0-9]+" />')
+            # col
+            tc.find('<input type="checkbox" name="col" value="summary"'
+                    ' checked="checked" />')
+            tc.find('<input type="checkbox" name="col" value="owner" />')
+            tc.find('<input type="checkbox" name="col" value="status"'
+                    ' checked="checked" />')
+            tc.find('<input type="checkbox" name="col" value="cc"'
+                    ' checked="checked" />')
+            # group
+            tc.find('<option selected="selected" value="status">Status'
+                    '</option>')
+            # groupdesc
+            tc.find('<input type="checkbox" name="groupdesc" id="groupdesc"'
+                    ' checked="checked" />')
+            # max
+            tc.find('<input type="text" name="max" id="max" size="[0-9]*?"'
+                    ' value="42" />')
+            # col in results
+            tc.find('<a title="Sort by Ticket [(]ascending[)]" ')
+            tc.find('<a title="Sort by Summary [(]ascending[)]" ')
+            tc.find('<a title="Sort by Status [(]ascending[)]" ')
+            tc.find('<a title="Sort by Cc [(]ascending[)]" ')
+            tc.notfind('<a title="Sort by Owner "')
+        finally:
+            env.config.set('query', 'default_query', saved_default_query)
+            env.config.save()
+            self._testenv.restart()
+
+
+class RegressionTestTicket7821var(FunctionalTwillTestCaseSetup):
+    def runTest(self):
+        """Test for regression of http://trac.edgewall.org/ticket/7821 var"""
+        env = self._testenv.get_trac_environment()
+        saved_default_query = env.config.get('query', 'default_query')
+        saved_restrict_owner = env.config.get('ticket', 'restrict_owner')
+        default_query = '?status=!closed&cc=~$USER&owner=$USER'
+        env.config.set('query', 'default_query', default_query)
+        env.config.set('ticket', 'restrict_owner', 'no')
+        env.config.save()
+        try:
+            self._testenv.restart()
+            self._tester.create_ticket('RegressionTestTicket7821 var')
+            self._tester.go_to_query()
+            # $USER in default_query
+            tc.find('<input type="text" name="0_owner" value="admin"'
+                    ' size="[0-9]+" />')
+            tc.find('<input type="text" name="0_cc" value="admin"'
+                    ' size="[0-9]+" />')
+            # query:owner=$USER&or&cc~=$USER
+            tc.go(self._tester.url + \
+                  '/intertrac/query:owner=$USER&or&cc~=$USER')
+            tc.find('<input type="text" name="0_owner" value="admin"'
+                    ' size="[0-9]+" />')
+            tc.find('<input type="text" name="1_cc" value="admin"'
+                    ' size="[0-9]+" />')
+        finally:
+            env.config.set('query', 'default_query', saved_default_query)
+            env.config.set('ticket', 'restrict_owner', saved_restrict_owner)
+            env.config.save()
+            self._testenv.restart()
+
+
 class RegressionTestTicket8247(FunctionalTwillTestCaseSetup):
     def runTest(self):
         """Test for regression of http://trac.edgewall.org/ticket/8247
     suite.addTest(RegressionTestTicket6879b())
     suite.addTest(RegressionTestTicket6912a())
     suite.addTest(RegressionTestTicket6912b())
+    suite.addTest(RegressionTestTicket7821group())
+    suite.addTest(RegressionTestTicket7821var())
     suite.addTest(RegressionTestTicket8247())
     suite.addTest(RegressionTestTicket8861())
     suite.addTest(RegressionTestTicket9084())

trac/ticket/tests/query.py

         self.assertEqual(args, like_args)
         tickets = query.execute(self.req)
 
+    def test_user_var(self):
+        query = Query.from_string(self.env, 'owner=$USER&order=id')
+        sql, args = query.get_sql(req=self.req)
+        self.assertEqualSQL(sql,
+"""SELECT t.id AS id,t.summary AS summary,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.milestone AS milestone,t.time AS time,t.changetime AS changetime,priority.value AS priority_value
+FROM ticket AS t
+  LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND priority.name=priority)
+WHERE ((COALESCE(t.owner,'')=%s))
+ORDER BY COALESCE(t.id,0)=0,t.id""")
+        self.assertEqual(['anonymous'], args)
+        tickets = query.execute(self.req)
+
     def test_csv_escape(self):
         query = Mock(get_columns=lambda: ['col1'],
                      execute=lambda r: [{'id': 1, 

trac/versioncontrol/admin.py

                self._complete_repos, self._do_resync)
         yield ('repository sync', '<repos> [rev]',
                """Resume synchronization of repositories
+
+               It works like `resync`, except that it doesn't clear the already
+               synchronized changesets, so it's a better way to resume an
+               interrupted `resync`.
                
-               Similar to `resync`, but doesn't clear the already synchronized
-               changesets. Useful for resuming an interrupted `resync`.
-               
-               To synchronize all repositories, specify "*" as the repository.
+               See `resync` help for detailed usage.
                """,
                self._complete_repos, self._do_sync)