~bzr-pqm/bzr/bzr.dev

2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
1
# Copyright (C) 2007 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
16
17
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
18
from bzrlib import bugtracker, errors, urlutils
4119.4.2 by Jonathan Lange
Some refactoring, some unit tests.
19
from bzrlib.tests import TestCase, TestCaseWithMemoryTransport
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
20
21
2376.4.7 by jml at canonical
- Add docstrings to tests.
22
class TestGetBugURL(TestCaseWithMemoryTransport):
23
    """Tests for bugtracker.get_bug_url"""
24
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
25
    class TransientTracker(object):
26
        """An transient tracker used for testing."""
27
28
        @classmethod
29
        def get(klass, abbreviation, branch):
30
            klass.log.append(('get', abbreviation, branch))
31
            if abbreviation != 'transient':
32
                return None
33
            return klass()
34
35
        def get_bug_url(self, bug_id):
36
            self.log.append(('get_bug_url', bug_id))
37
            return "http://bugs.com/%s" % bug_id
38
39
    def setUp(self):
40
        TestCaseWithMemoryTransport.setUp(self)
41
        self.tracker_type = TestGetBugURL.TransientTracker
42
        self.tracker_type.log = []
43
        bugtracker.tracker_registry.register('transient', self.tracker_type)
44
        self.addCleanup(lambda:
45
                        bugtracker.tracker_registry.remove('transient'))
46
47
    def test_get_bug_url_for_transient_tracker(self):
2376.4.7 by jml at canonical
- Add docstrings to tests.
48
        branch = self.make_branch('some_branch')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
49
        self.assertEqual('http://bugs.com/1234',
50
                         bugtracker.get_bug_url('transient', branch, '1234'))
2376.4.7 by jml at canonical
- Add docstrings to tests.
51
        self.assertEqual(
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
52
            [('get', 'transient', branch), ('get_bug_url', '1234')],
53
            self.tracker_type.log)
54
55
    def test_unrecognized_abbreviation_raises_error(self):
56
        """If the abbreviation is unrecognized, then raise an error."""
2376.4.7 by jml at canonical
- Add docstrings to tests.
57
        branch = self.make_branch('some_branch')
2376.4.26 by Jonathan Lange
Tests for MalformedBugIdentifier and new error UnknownBugTrackerAbbreviation.
58
        self.assertRaises(errors.UnknownBugTrackerAbbreviation,
2376.4.7 by jml at canonical
- Add docstrings to tests.
59
                          bugtracker.get_bug_url, 'xxx', branch, '1234')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
60
        self.assertEqual([('get', 'xxx', branch)], self.tracker_type.log)
2376.4.7 by jml at canonical
- Add docstrings to tests.
61
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
62
2376.4.29 by Jonathan Lange
Tests for builtin trackers.
63
class TestBuiltinTrackers(TestCaseWithMemoryTransport):
64
    """Test that the builtin trackers are registered and return sane URLs."""
65
66
    def test_launchpad_registered(self):
67
        """The Launchpad bug tracker should be registered by default and
68
        generate Launchpad bug page URLs.
69
        """
70
        branch = self.make_branch('some_branch')
71
        tracker = bugtracker.tracker_registry.get_tracker('lp', branch)
72
        self.assertEqual('https://launchpad.net/bugs/1234',
73
                         tracker.get_bug_url('1234'))
74
75
    def test_debian_registered(self):
76
        """The Debian bug tracker should be registered by default and generate
77
        bugs.debian.org bug page URLs.
78
        """
79
        branch = self.make_branch('some_branch')
80
        tracker = bugtracker.tracker_registry.get_tracker('deb', branch)
81
        self.assertEqual('http://bugs.debian.org/1234',
82
                         tracker.get_bug_url('1234'))
83
3270.5.1 by James Westby
Add gnome to the list of known bugtrackers.
84
    def test_gnome_registered(self):
85
        branch = self.make_branch('some_branch')
86
        tracker = bugtracker.tracker_registry.get_tracker('gnome', branch)
87
        self.assertEqual('http://bugzilla.gnome.org/show_bug.cgi?id=1234',
88
                         tracker.get_bug_url('1234'))
89
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
90
    def test_trac_registered(self):
91
        """The Trac bug tracker should be registered by default and generate
92
        Trac bug page URLs when the appropriate configuration is present.
93
        """
94
        branch = self.make_branch('some_branch')
95
        config = branch.get_config()
96
        config.set_user_option('trac_foo_url', 'http://bugs.com/trac')
97
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
98
        self.assertEqual('http://bugs.com/trac/ticket/1234',
99
                         tracker.get_bug_url('1234'))
100
101
    def test_bugzilla_registered(self):
102
        """The Bugzilla bug tracker should be registered by default and
103
        generate Bugzilla bug page URLs when the appropriate configuration is
104
        present.
105
        """
106
        branch = self.make_branch('some_branch')
107
        config = branch.get_config()
108
        config.set_user_option('bugzilla_foo_url', 'http://bugs.com')
109
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
110
        self.assertEqual('http://bugs.com/show_bug.cgi?id=1234',
111
                         tracker.get_bug_url('1234'))
112
3035.3.1 by Lukáš Lalinský
Generic bug tracker configuration.
113
    def test_generic_registered(self):
114
        branch = self.make_branch('some_branch')
115
        config = branch.get_config()
116
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/{id}/view.html')
117
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
118
        self.assertEqual('http://bugs.com/1234/view.html',
119
                         tracker.get_bug_url('1234'))
120
3035.3.2 by Lukáš Lalinský
Add tests for InvalidBugTrackerURL.
121
    def test_generic_incorrect_url(self):
122
        branch = self.make_branch('some_branch')
123
        config = branch.get_config()
124
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/view.html')
125
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
126
        self.assertRaises(errors.InvalidBugTrackerURL, tracker.get_bug_url, '1234')
3035.3.1 by Lukáš Lalinský
Generic bug tracker configuration.
127
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
128
129
class TestUniqueIntegerBugTracker(TestCaseWithMemoryTransport):
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
130
3329.1.1 by Ian Clatworthy
Add gnome to list of known bugtrackers (James Westby, Andrew Cowie)
131
    def test_appends_id_to_base_url(self):
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
132
        """The URL of a bug is the base URL joined to the identifier."""
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
133
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
3329.1.1 by Ian Clatworthy
Add gnome to list of known bugtrackers (James Westby, Andrew Cowie)
134
                'http://bugs.com/foo')
135
        self.assertEqual('http://bugs.com/foo1234', tracker.get_bug_url('1234'))
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
136
2376.4.23 by Jonathan Lange
Change 'tag' to 'abbreviated_tracker_name'
137
    def test_returns_tracker_if_abbreviation_matches(self):
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
138
        """The get() method should return an instance of the tracker if the
139
        given abbreviation matches the tracker's abbreviated name.
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
140
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
141
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
142
                'http://bugs.com/')
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
143
        branch = self.make_branch('some_branch')
2376.4.25 by Jonathan Lange
Make singleton bug tracker thing work via instances.
144
        self.assertIs(tracker, tracker.get('xxx', branch))
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
145
2376.4.23 by Jonathan Lange
Change 'tag' to 'abbreviated_tracker_name'
146
    def test_returns_none_if_abbreviation_doesnt_match(self):
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
147
        """The get() method should return None if the given abbreviated name
148
        doesn't match the tracker's abbreviation.
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
149
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
150
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
151
                'http://bugs.com/')
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
152
        branch = self.make_branch('some_branch')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
153
        self.assertIs(None, tracker.get('yyy', branch))
154
155
    def test_doesnt_consult_branch(self):
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
156
        """A UniqueIntegerBugTracker shouldn't consult the branch for tracker
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
157
        information.
158
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
159
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
160
                'http://bugs.com/')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
161
        self.assertIs(tracker, tracker.get('xxx', None))
162
        self.assertIs(None, tracker.get('yyy', None))
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
163
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
164
    def test_check_bug_id_only_accepts_integers(self):
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
165
        """A UniqueIntegerBugTracker accepts integers as bug IDs."""
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
166
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
167
                'http://bugs.com/')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
168
        tracker.check_bug_id('1234')
169
170
    def test_check_bug_id_doesnt_accept_non_integers(self):
171
        """A UniqueIntegerBugTracker rejects non-integers as bug IDs."""
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
172
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
173
                'http://bugs.com/')
2376.4.26 by Jonathan Lange
Tests for MalformedBugIdentifier and new error UnknownBugTrackerAbbreviation.
174
        self.assertRaises(
175
            errors.MalformedBugIdentifier, tracker.check_bug_id, 'red')
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
176
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
177
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
178
class TestURLParametrizedIntegerBugTracker(TestCaseWithMemoryTransport):
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
179
    """Tests for TracTracker."""
180
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
181
    def setUp(self):
182
        TestCaseWithMemoryTransport.setUp(self)
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
183
        self.url = 'http://twistedmatrix.com/trac'
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
184
        self.tracker = bugtracker.URLParametrizedIntegerBugTracker('some',
185
                                                                   'ticket/')
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
186
187
    def test_get_with_unsupported_tag(self):
2376.4.7 by jml at canonical
- Add docstrings to tests.
188
        """If asked for an unrecognized or unconfigured tag, return None."""
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
189
        branch = self.make_branch('some_branch')
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
190
        self.assertEqual(None, self.tracker.get('lp', branch))
191
        self.assertEqual(None, self.tracker.get('twisted', branch))
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
192
193
    def test_get_with_supported_tag(self):
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
194
        """If asked for a valid tag, return a tracker instance that can map bug
195
        IDs to <base_url>/<bug_area> + <bug_id>."""
196
        bugtracker.tracker_registry.register('some', self.tracker)
197
        self.addCleanup(lambda: bugtracker.tracker_registry.remove('some'))
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
198
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
199
        branch = self.make_branch('some_branch')
200
        config = branch.get_config()
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
201
        config.set_user_option('some_twisted_url', self.url)
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
202
        tracker = self.tracker.get('twisted', branch)
203
        self.assertEqual(
204
            urlutils.join(self.url, 'ticket/') + '1234',
205
            tracker.get_bug_url('1234'))
2376.4.7 by jml at canonical
- Add docstrings to tests.
206
2376.4.30 by Jonathan Lange
Support for Bugzilla bug trackers.
207
    def test_get_bug_url_for_bad_bug(self):
208
        """When given a bug identifier that is invalid for Trac, get_bug_url
209
        should raise an error.
210
        """
211
        self.assertRaises(
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
212
            errors.MalformedBugIdentifier, self.tracker.get_bug_url, 'bad')
4119.4.2 by Jonathan Lange
Some refactoring, some unit tests.
213
214
215
class TestPropertyEncoding(TestCase):
216
    """Tests for how the bug URLs are encoded as revision properties."""
217
218
    def test_encoding_one(self):
219
        self.assertEqual(
220
            'http://example.com/bugs/1 fixed',
221
            bugtracker.encode_fixes_bug_urls(['http://example.com/bugs/1']))
222
223
    def test_encoding_zero(self):
224
        self.assertEqual('', bugtracker.encode_fixes_bug_urls([]))
225
226
    def test_encoding_two(self):
227
        self.assertEqual(
228
            'http://example.com/bugs/1 fixed\n'
229
            'http://example.com/bugs/2 fixed',
230
            bugtracker.encode_fixes_bug_urls(
231
                ['http://example.com/bugs/1', 'http://example.com/bugs/2']))