Anonymous avatar Anonymous committed 908bdb9

0.12.3dev: Adds support for decorating a resource other than ticket and a resource with the parent in a report.

Closes #9254 and #10061.

Comments (0)

Files changed (5)

trac/ticket/report.py

             cell_groups = []
             row = {'cell_groups': cell_groups}
             realm = 'ticket'
+            parent_realm = ''
+            parent_id = ''
             email_cells = []
             for header_group in header_groups:
                 cell_group = []
                         email_cells.append(cell)
                     elif col == 'realm':
                         realm = value
+                    elif col == 'parent_realm':
+                        parent_realm = value
+                    elif col == 'parent_id':
+                        parent_id = value
                     cell_group.append(cell)
                 cell_groups.append(cell_group)
-            resource = Resource(realm, row.get('id'))
+            if parent_realm:
+                resource = Resource(realm, row.get('id'),
+                                    parent=Resource(parent_realm, parent_id))
+            else:
+                resource = Resource(realm, row.get('id'))
             # FIXME: for now, we still need to hardcode the realm in the action
             if resource.realm.upper()+'_VIEW' not in req.perm(resource):
                 continue

trac/ticket/templates/report_view.html

                         <py:when test="col in ('ticket', 'id')">
                           <td class="ticket" py:attrs="td_attrs">
                             <a title="${_('View %(realm)s', realm=row.resource.realm)}"
-                               href="${url_of(row.resource)}">#$cell.value</a>
+                               href="${url_of(row.resource)}">${shortname_of(row.resource)}</a>
                             <hr py:if="fullrow"/>
                           </td>
                         </py:when>

trac/ticket/tests/functional.py

             ' been closed this week.)')
 
 
+class TestReportRealmDecoration(FunctionalTwillTestCaseSetup):
+    def runTest(self):
+        """Realm/id decoration in report"""
+        self._tester.create_report(
+            'Realm/id decoration',
+            """\
+SELECT NULL AS _realm, NULL AS id, NULL AS _parent_realm, NULL AS _parent_id
+UNION ALL SELECT 'ticket', '42', NULL, NULL
+UNION ALL SELECT 'report', '42', NULL, NULL
+UNION ALL SELECT 'milestone', '42', NULL, NULL
+UNION ALL SELECT 'wiki', 'WikiStart', NULL, NULL
+UNION ALL SELECT 'changeset', '42/trunk', NULL, NULL
+UNION ALL SELECT 'changeset', '42/trunk', 'repository', 'repo'
+UNION ALL SELECT 'changeset', '43/tags', 'repository', ''
+UNION ALL SELECT 'attachment', 'file.ext', 'ticket', '42'
+UNION ALL SELECT 'attachment', 'file.ext', 'milestone', '42'
+UNION ALL SELECT 'attachment', 'file.ext', 'wiki', 'WikiStart'
+""", '')
+        tc.find('<a title="View ticket" href="[^"]*?/ticket/42">#42</a>')
+        tc.find('<a title="View report" href="[^"]*?/report/42">report:42</a>')
+        tc.find('<a title="View milestone" href="[^"]*?/milestone/42">42</a>')
+        tc.find('<a title="View wiki" href="[^"]*?/wiki/WikiStart">'
+                'WikiStart</a>')
+        tc.find('<a title="View changeset" href="[^"]*?/changeset/42/trunk">'
+                'Changeset 42/trunk</a>')
+        tc.find('<a title="View changeset" '
+                'href="[^"]*?/changeset/42/trunk/repo">'
+                'Changeset 42/trunk in repo</a>')
+        tc.find('<a title="View changeset" href="[^"]*?/changeset/43/tags">'
+                'Changeset 43/tags</a>')
+        tc.find('<a title="View attachment" '
+                'href="[^"]*?/attachment/ticket/42/file[.]ext">'
+                'file[.]ext [(]Ticket #42[)]</a>')
+        tc.find('<a title="View attachment" '
+                'href="[^"]*?/attachment/milestone/42/file[.]ext">'
+                'file[.]ext [(]Milestone 42[)]</a>')
+        tc.find('<a title="View attachment" '
+                'href="[^"]*?/attachment/wiki/WikiStart/file[.]ext">'
+                'file[.]ext [(]WikiStart[)]</a>')
+
+
 class RegressionTestRev5665(FunctionalTwillTestCaseSetup):
     def runTest(self):
         """Admin create version without release time (r5665)"""
     suite.addTest(TestAdminVersionNonRemoval())
     suite.addTest(TestAdminVersionDefault())
     suite.addTest(TestNewReport())
+    suite.addTest(TestReportRealmDecoration())
     suite.addTest(RegressionTestRev5665())
     suite.addTest(RegressionTestRev5994())
 

trac/versioncontrol/api.py

 
     def get_resource_description(self, resource, format=None, **kwargs):
         if resource.realm == 'changeset':
-            reponame, id = resource.parent.id, resource.id
+            parent = resource.parent
+            reponame = parent and parent.id
+            id = resource.id
             if reponame:
                 return _("Changeset %(rev)s in %(repo)s", rev=id, repo=reponame)
             else:
                 return _("Changeset %(rev)s", rev=id)
         elif resource.realm == 'source':
-            reponame, id = resource.parent.id, resource.id
+            parent = resource.parent
+            reponame = parent and parent.id
+            id = resource.id
             version = ''
             if format == 'summary':
                 repos = self.get_repository(reponame)
 
     def get_resource_url(self, resource, href, **kwargs):
         if resource.realm == 'changeset':
-            return href.changeset(resource.id, resource.parent.id or None)
+            parent = resource.parent
+            return href.changeset(resource.id, parent and parent.id or None)
         elif resource.realm == 'source':
-            return href.source(resource.parent.id or None, resource.id)
+            parent = resource.parent
+            return href.source(parent and parent.id or None, resource.id)
         elif resource.realm == 'repository':
             return href.source(resource.id or None)
 

trac/versioncontrol/tests/api.py

 
 import unittest
 
+from trac.resource import Resource, get_resource_description, get_resource_url
+from trac.test import EnvironmentStub
 from trac.versioncontrol.api import Repository
 
 
         self.failUnlessRaises(NotImplementedError, self.repo_base.get_changes, 'path', 1, 'path', 2)
 
 
+class ResourceManagerTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.env = EnvironmentStub(default_data=True)
+
+    def test_resource_changeset(self):
+        res = Resource('changeset', '42')
+        self.assertEqual('Changeset 42', get_resource_description(self.env, res))
+        self.assertEqual('/trac.cgi/changeset/42',
+                         get_resource_url(self.env, res, self.env.href))
+
+        repo = Resource('repository', 'repo')
+        res = Resource('changeset', '42', parent=repo)
+        self.assertEqual('Changeset 42 in repo',
+                         get_resource_description(self.env, res))
+        self.assertEqual('/trac.cgi/changeset/42/repo',
+                         get_resource_url(self.env, res, self.env.href))
+
+    def test_resource_source(self):
+        res = Resource('source', '/trunk/src')
+        self.assertEqual('path /trunk/src',
+                         get_resource_description(self.env, res))
+        self.assertEqual('/trac.cgi/source/trunk/src',
+                         get_resource_url(self.env, res, self.env.href))
+
+        repo = Resource('repository', 'repo')
+        res = Resource('source', '/trunk/src', parent=repo)
+        self.assertEqual('path /trunk/src in repo',
+                         get_resource_description(self.env, res))
+        self.assertEqual('/trac.cgi/source/repo/trunk/src',
+                         get_resource_url(self.env, res, self.env.href))
+
+        repo = Resource('repository', 'repo')
+        res = Resource('source', '/trunk/src', version=42, parent=repo)
+        self.assertEqual('path /trunk/src@42 in repo',
+                         get_resource_description(self.env, res))
+        self.assertEqual('/trac.cgi/source/repo/trunk/src',
+                         get_resource_url(self.env, res, self.env.href))
+
+
+    def test_resource_repository(self):
+        res = Resource('repository', 'testrepo')
+        self.assertEqual('Repository testrepo',
+                         get_resource_description(self.env, res))
+        self.assertEqual('/trac.cgi/source/testrepo',
+                         get_resource_url(self.env, res, self.env.href))
+
+
 def suite():
-    return unittest.makeSuite(ApiTestCase, 'test')
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(ApiTestCase, 'test'))
+    suite.addTest(unittest.makeSuite(ResourceManagerTestCase, 'test'))
+    return suite
 
 
 if __name__ == '__main__':
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.