~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)
4985.2.1 by Vincent Ladeuil
Deploy addAttrCleanup on the whole test suite.
44
        self.addCleanup(bugtracker.tracker_registry.remove, 'transient')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
45
46
    def test_get_bug_url_for_transient_tracker(self):
2376.4.7 by jml at canonical
- Add docstrings to tests.
47
        branch = self.make_branch('some_branch')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
48
        self.assertEqual('http://bugs.com/1234',
49
                         bugtracker.get_bug_url('transient', branch, '1234'))
2376.4.7 by jml at canonical
- Add docstrings to tests.
50
        self.assertEqual(
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
51
            [('get', 'transient', branch), ('get_bug_url', '1234')],
52
            self.tracker_type.log)
53
54
    def test_unrecognized_abbreviation_raises_error(self):
55
        """If the abbreviation is unrecognized, then raise an error."""
2376.4.7 by jml at canonical
- Add docstrings to tests.
56
        branch = self.make_branch('some_branch')
2376.4.26 by Jonathan Lange
Tests for MalformedBugIdentifier and new error UnknownBugTrackerAbbreviation.
57
        self.assertRaises(errors.UnknownBugTrackerAbbreviation,
2376.4.7 by jml at canonical
- Add docstrings to tests.
58
                          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
59
        self.assertEqual([('get', 'xxx', branch)], self.tracker_type.log)
2376.4.7 by jml at canonical
- Add docstrings to tests.
60
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
61
2376.4.29 by Jonathan Lange
Tests for builtin trackers.
62
class TestBuiltinTrackers(TestCaseWithMemoryTransport):
63
    """Test that the builtin trackers are registered and return sane URLs."""
64
65
    def test_launchpad_registered(self):
66
        """The Launchpad bug tracker should be registered by default and
67
        generate Launchpad bug page URLs.
68
        """
69
        branch = self.make_branch('some_branch')
70
        tracker = bugtracker.tracker_registry.get_tracker('lp', branch)
71
        self.assertEqual('https://launchpad.net/bugs/1234',
72
                         tracker.get_bug_url('1234'))
73
74
    def test_debian_registered(self):
75
        """The Debian bug tracker should be registered by default and generate
76
        bugs.debian.org bug page URLs.
77
        """
78
        branch = self.make_branch('some_branch')
79
        tracker = bugtracker.tracker_registry.get_tracker('deb', branch)
80
        self.assertEqual('http://bugs.debian.org/1234',
81
                         tracker.get_bug_url('1234'))
82
3270.5.1 by James Westby
Add gnome to the list of known bugtrackers.
83
    def test_gnome_registered(self):
84
        branch = self.make_branch('some_branch')
85
        tracker = bugtracker.tracker_registry.get_tracker('gnome', branch)
86
        self.assertEqual('http://bugzilla.gnome.org/show_bug.cgi?id=1234',
87
                         tracker.get_bug_url('1234'))
88
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
89
    def test_trac_registered(self):
90
        """The Trac bug tracker should be registered by default and generate
91
        Trac bug page URLs when the appropriate configuration is present.
92
        """
93
        branch = self.make_branch('some_branch')
94
        config = branch.get_config()
95
        config.set_user_option('trac_foo_url', 'http://bugs.com/trac')
96
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
97
        self.assertEqual('http://bugs.com/trac/ticket/1234',
98
                         tracker.get_bug_url('1234'))
99
100
    def test_bugzilla_registered(self):
101
        """The Bugzilla bug tracker should be registered by default and
102
        generate Bugzilla bug page URLs when the appropriate configuration is
103
        present.
104
        """
105
        branch = self.make_branch('some_branch')
106
        config = branch.get_config()
107
        config.set_user_option('bugzilla_foo_url', 'http://bugs.com')
108
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
109
        self.assertEqual('http://bugs.com/show_bug.cgi?id=1234',
110
                         tracker.get_bug_url('1234'))
111
3035.3.1 by Lukáš Lalinský
Generic bug tracker configuration.
112
    def test_generic_registered(self):
113
        branch = self.make_branch('some_branch')
114
        config = branch.get_config()
115
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/{id}/view.html')
116
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
117
        self.assertEqual('http://bugs.com/1234/view.html',
118
                         tracker.get_bug_url('1234'))
119
3035.3.2 by Lukáš Lalinský
Add tests for InvalidBugTrackerURL.
120
    def test_generic_incorrect_url(self):
121
        branch = self.make_branch('some_branch')
122
        config = branch.get_config()
123
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/view.html')
124
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
125
        self.assertRaises(errors.InvalidBugTrackerURL, tracker.get_bug_url, '1234')
3035.3.1 by Lukáš Lalinský
Generic bug tracker configuration.
126
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
127
128
class TestUniqueIntegerBugTracker(TestCaseWithMemoryTransport):
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
129
3329.1.1 by Ian Clatworthy
Add gnome to list of known bugtrackers (James Westby, Andrew Cowie)
130
    def test_appends_id_to_base_url(self):
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
131
        """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.
132
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
3329.1.1 by Ian Clatworthy
Add gnome to list of known bugtrackers (James Westby, Andrew Cowie)
133
                'http://bugs.com/foo')
134
        self.assertEqual('http://bugs.com/foo1234', tracker.get_bug_url('1234'))
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
135
2376.4.23 by Jonathan Lange
Change 'tag' to 'abbreviated_tracker_name'
136
    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
137
        """The get() method should return an instance of the tracker if the
138
        given abbreviation matches the tracker's abbreviated name.
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
139
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
140
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
141
                'http://bugs.com/')
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
142
        branch = self.make_branch('some_branch')
2376.4.25 by Jonathan Lange
Make singleton bug tracker thing work via instances.
143
        self.assertIs(tracker, tracker.get('xxx', branch))
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
144
2376.4.23 by Jonathan Lange
Change 'tag' to 'abbreviated_tracker_name'
145
    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
146
        """The get() method should return None if the given abbreviated name
147
        doesn't match the tracker's abbreviation.
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
148
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
149
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
150
                'http://bugs.com/')
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
151
        branch = self.make_branch('some_branch')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
152
        self.assertIs(None, tracker.get('yyy', branch))
153
154
    def test_doesnt_consult_branch(self):
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
155
        """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
156
        information.
157
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
158
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
159
                'http://bugs.com/')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
160
        self.assertIs(tracker, tracker.get('xxx', None))
161
        self.assertIs(None, tracker.get('yyy', None))
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
162
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
163
    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
164
        """A UniqueIntegerBugTracker accepts integers as bug IDs."""
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
165
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
166
                'http://bugs.com/')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
167
        tracker.check_bug_id('1234')
168
169
    def test_check_bug_id_doesnt_accept_non_integers(self):
170
        """A UniqueIntegerBugTracker rejects non-integers as bug IDs."""
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
171
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
172
                'http://bugs.com/')
2376.4.26 by Jonathan Lange
Tests for MalformedBugIdentifier and new error UnknownBugTrackerAbbreviation.
173
        self.assertRaises(
174
            errors.MalformedBugIdentifier, tracker.check_bug_id, 'red')
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
175
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
176
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
177
class TestURLParametrizedIntegerBugTracker(TestCaseWithMemoryTransport):
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
178
    """Tests for TracTracker."""
179
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
180
    def setUp(self):
181
        TestCaseWithMemoryTransport.setUp(self)
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
182
        self.url = 'http://twistedmatrix.com/trac'
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
183
        self.tracker = bugtracker.URLParametrizedIntegerBugTracker('some',
184
                                                                   'ticket/')
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
185
186
    def test_get_with_unsupported_tag(self):
2376.4.7 by jml at canonical
- Add docstrings to tests.
187
        """If asked for an unrecognized or unconfigured tag, return None."""
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
188
        branch = self.make_branch('some_branch')
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
189
        self.assertEqual(None, self.tracker.get('lp', branch))
190
        self.assertEqual(None, self.tracker.get('twisted', branch))
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
191
192
    def test_get_with_supported_tag(self):
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
193
        """If asked for a valid tag, return a tracker instance that can map bug
194
        IDs to <base_url>/<bug_area> + <bug_id>."""
195
        bugtracker.tracker_registry.register('some', self.tracker)
4985.2.1 by Vincent Ladeuil
Deploy addAttrCleanup on the whole test suite.
196
        self.addCleanup(bugtracker.tracker_registry.remove, 'some')
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
197
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
198
        branch = self.make_branch('some_branch')
199
        config = branch.get_config()
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
200
        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
201
        tracker = self.tracker.get('twisted', branch)
202
        self.assertEqual(
203
            urlutils.join(self.url, 'ticket/') + '1234',
204
            tracker.get_bug_url('1234'))
2376.4.7 by jml at canonical
- Add docstrings to tests.
205
2376.4.30 by Jonathan Lange
Support for Bugzilla bug trackers.
206
    def test_get_bug_url_for_bad_bug(self):
207
        """When given a bug identifier that is invalid for Trac, get_bug_url
208
        should raise an error.
209
        """
210
        self.assertRaises(
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
211
            errors.MalformedBugIdentifier, self.tracker.get_bug_url, 'bad')
4119.4.2 by Jonathan Lange
Some refactoring, some unit tests.
212
213
214
class TestPropertyEncoding(TestCase):
215
    """Tests for how the bug URLs are encoded as revision properties."""
216
217
    def test_encoding_one(self):
218
        self.assertEqual(
219
            'http://example.com/bugs/1 fixed',
220
            bugtracker.encode_fixes_bug_urls(['http://example.com/bugs/1']))
221
222
    def test_encoding_zero(self):
223
        self.assertEqual('', bugtracker.encode_fixes_bug_urls([]))
224
225
    def test_encoding_two(self):
226
        self.assertEqual(
227
            'http://example.com/bugs/1 fixed\n'
228
            'http://example.com/bugs/2 fixed',
229
            bugtracker.encode_fixes_bug_urls(
230
                ['http://example.com/bugs/1', 'http://example.com/bugs/2']))