| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # Copyright (c) 2019-2021 Cinc |
|---|
| 3 | # All rights reserved. |
|---|
| 4 | # |
|---|
| 5 | # Redistribution and use in source and binary forms, with or without |
|---|
| 6 | # modification, are permitted provided that the following conditions |
|---|
| 7 | # are met: |
|---|
| 8 | # 1. Redistributions of source code must retain the above copyright |
|---|
| 9 | # notice, this list of conditions and the following disclaimer. |
|---|
| 10 | # 2. Redistributions in binary form must reproduce the above copyright |
|---|
| 11 | # notice, this list of conditions and the following disclaimer in the |
|---|
| 12 | # documentation and/or other materials provided with the distribution. |
|---|
| 13 | # 3. The name of the author may not be used to endorse or promote products |
|---|
| 14 | # derived from this software without specific prior written permission. |
|---|
| 15 | # |
|---|
| 16 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|---|
| 17 | # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|---|
| 18 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|---|
| 19 | # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|---|
| 20 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|---|
| 21 | # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|---|
| 22 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|---|
| 23 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|---|
| 24 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|---|
| 25 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|---|
| 26 | |
|---|
| 27 | import unittest |
|---|
| 28 | from codereview.model import PeerReviewModelProvider |
|---|
| 29 | from codereview.report import PeerReviewReport |
|---|
| 30 | from trac.admin.console import TracAdmin |
|---|
| 31 | from trac.perm import PermissionError |
|---|
| 32 | from trac.test import EnvironmentStub, MockRequest |
|---|
| 33 | from trac.web.chrome import Chrome |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | class TestResource(unittest.TestCase): |
|---|
| 37 | |
|---|
| 38 | def _add_permissions(self): |
|---|
| 39 | admin = TracAdmin() |
|---|
| 40 | admin.env_set('Testenv', self.env) |
|---|
| 41 | admin.onecmd("permission add Tester TICKET_VIEW") # User not allowed to perform code reviews |
|---|
| 42 | admin.onecmd("permission add Rev1 TRAC_ADMIN") # This one is also an allowed user |
|---|
| 43 | admin.onecmd("permission add RevMgr CODE_REVIEW_MGR") |
|---|
| 44 | admin.onecmd("permission add RevDev CODE_REVIEW_DEV") |
|---|
| 45 | admin.onecmd("permission add RevView CODE_REVIEW_VIEW") |
|---|
| 46 | admin.onecmd("permission add Rev1 RevGroup") |
|---|
| 47 | admin.onecmd("permission add Rev2 RevGroup") |
|---|
| 48 | |
|---|
| 49 | def _create_standard_reports(self): |
|---|
| 50 | # title, description |
|---|
| 51 | reports = [['title 1', 'Report description 1'], |
|---|
| 52 | ['title 2', 'Report description 2'], |
|---|
| 53 | ['title 3', 'Report description 3'], |
|---|
| 54 | ['title 4', 'Report description 4'] |
|---|
| 55 | ] |
|---|
| 56 | with self.env.db_transaction as db: |
|---|
| 57 | cursor = db.cursor() |
|---|
| 58 | for item in reports: |
|---|
| 59 | cursor.execute("INSERT INTO report (title, description) " |
|---|
| 60 | "VALUES (%s,%s)", item) |
|---|
| 61 | |
|---|
| 62 | def _create_codereview_reports(self): |
|---|
| 63 | desc = """{{{ |
|---|
| 64 | #!comment |
|---|
| 65 | codereview=1 |
|---|
| 66 | }}} |
|---|
| 67 | """ |
|---|
| 68 | # title, description |
|---|
| 69 | reports = [['title 1', desc + 'Report description 1'], |
|---|
| 70 | ['title 2', desc + 'Report description 2'], |
|---|
| 71 | ['title 3', desc + 'Report description 3'], |
|---|
| 72 | ['title 4', desc + 'Report description 4'] |
|---|
| 73 | ] |
|---|
| 74 | with self.env.db_transaction as db: |
|---|
| 75 | cursor = db.cursor() |
|---|
| 76 | for item in reports: |
|---|
| 77 | cursor.execute("INSERT INTO report (title, description) " |
|---|
| 78 | "VALUES (%s,%s)", item) |
|---|
| 79 | |
|---|
| 80 | def setUp(self): |
|---|
| 81 | self.env = EnvironmentStub(default_data=True, enable=['trac.*', |
|---|
| 82 | 'codereview.model.*', |
|---|
| 83 | 'codereview.peerreviewnew.*', |
|---|
| 84 | 'codereview.peerreviewmain.*', |
|---|
| 85 | 'codereview.tracgenericclass.*']) |
|---|
| 86 | PeerReviewModelProvider(self.env).environment_created() |
|---|
| 87 | self.plugin = PeerReviewReport(self.env) |
|---|
| 88 | self._add_permissions() |
|---|
| 89 | # authname causes the addition of an empty permission cache. |
|---|
| 90 | self.req = MockRequest(self.env, authname='user') |
|---|
| 91 | |
|---|
| 92 | def tearDown(self): |
|---|
| 93 | self.env.shutdown() |
|---|
| 94 | |
|---|
| 95 | def test_get_active_navigation_item(self): |
|---|
| 96 | self.assertEqual('peerreviewmain', self.plugin.get_active_navigation_item(self.req)) |
|---|
| 97 | |
|---|
| 98 | def test_get_navigation_items(self): |
|---|
| 99 | self.assertIsNone(self.plugin.get_navigation_items(self.req)) |
|---|
| 100 | |
|---|
| 101 | def test_match_request(self): |
|---|
| 102 | req = MockRequest(self.env, path_info="/peerreviewreport") |
|---|
| 103 | self.assertTrue(self.plugin.match_request(req)) |
|---|
| 104 | req = MockRequest(self.env, path_info="/peerreviewreport/") |
|---|
| 105 | self.assertFalse(self.plugin.match_request(req)) |
|---|
| 106 | |
|---|
| 107 | def test_process_request_no_perm(self): |
|---|
| 108 | self.assertRaises(PermissionError, self.plugin.process_request, self.req) |
|---|
| 109 | |
|---|
| 110 | def test_process_request_perm_view(self): |
|---|
| 111 | """Test permission CODE_REVIEW_VIEW""" |
|---|
| 112 | req = MockRequest(self.env, authname='RevView') |
|---|
| 113 | self.assertRaises(PermissionError, self.plugin.process_request, req) |
|---|
| 114 | |
|---|
| 115 | def test_process_request_perm_dev(self): |
|---|
| 116 | """Test permission CODE_REVIEW_DEV""" |
|---|
| 117 | req = MockRequest(self.env, authname='RevDev') |
|---|
| 118 | self.plugin.process_request(req) |
|---|
| 119 | |
|---|
| 120 | def test_process_request_perm_view_(self): |
|---|
| 121 | """Test permission CODE_REVIEW_MGR""" |
|---|
| 122 | req = MockRequest(self.env, authname='RevMgr') |
|---|
| 123 | self.plugin.process_request(req) |
|---|
| 124 | |
|---|
| 125 | def test_process_request_reports_not_codereview(self): |
|---|
| 126 | """Test with only non codereview reports""" |
|---|
| 127 | req = MockRequest(self.env, authname='RevDev') |
|---|
| 128 | self._create_standard_reports() |
|---|
| 129 | res = self.plugin.process_request(req) |
|---|
| 130 | if hasattr(Chrome, 'jenv'): |
|---|
| 131 | self.assertEqual('peerreview_report_jinja.html', res[0]) |
|---|
| 132 | self.assertEqual(2, len(res)) |
|---|
| 133 | else: |
|---|
| 134 | self.assertEqual('peerreview_report.html', res[0]) |
|---|
| 135 | self.assertIsNone(res[2]) |
|---|
| 136 | self.assertIn('reports', res[1]) |
|---|
| 137 | self.assertEqual(0, len(res[1]['reports'])) |
|---|
| 138 | |
|---|
| 139 | def test_process_request_reports_codereview(self): |
|---|
| 140 | """Test with additional codereview reports""" |
|---|
| 141 | req = MockRequest(self.env, authname='RevDev') |
|---|
| 142 | self._create_standard_reports() |
|---|
| 143 | self._create_codereview_reports() |
|---|
| 144 | res = self.plugin.process_request(req) |
|---|
| 145 | if hasattr(Chrome, 'jenv'): |
|---|
| 146 | self.assertEqual('peerreview_report_jinja.html', res[0]) |
|---|
| 147 | self.assertEqual(2, len(res)) |
|---|
| 148 | else: |
|---|
| 149 | self.assertEqual('peerreview_report.html', res[0]) |
|---|
| 150 | self.assertIsNone(res[2]) |
|---|
| 151 | self.assertIn('reports', res[1]) |
|---|
| 152 | self.assertEqual(4, len(res[1]['reports'])) |
|---|
| 153 | for item in res[1]['reports']: |
|---|
| 154 | # item is a dict |
|---|
| 155 | self.assertEqual(3, len(item)) # each item is: id, title, desc |
|---|
| 156 | for key in ('id', 'title', 'desc'): |
|---|
| 157 | self.assertIn(key, item) |
|---|
| 158 | |
|---|
| 159 | |
|---|
| 160 | def test_suite(): |
|---|
| 161 | suite = unittest.TestSuite() |
|---|
| 162 | suite.addTest(unittest.makeSuite(TestResource)) |
|---|
| 163 | return suite |
|---|