~bzr-pqm/bzr/bzr.dev

5387.2.7 by John Arbash Meinel
Merge bzr.dev 5444 to resolve some small text conflicts.
1
# Copyright (C) 2007-2010 Canonical Ltd
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
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):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
40
        super(TestGetBugURL, self).setUp()
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
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)
5409.3.2 by Alexandre Garnier
Add tests for URLParametrizedBugTracker rather than reusing existing tests
117
        self.assertEqual('http://bugs.com/1234/view.html',
118
                         tracker.get_bug_url('1234'))
119
120
    def test_generic_registered_non_integer(self):
121
        branch = self.make_branch('some_branch')
122
        config = branch.get_config()
123
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/{id}/view.html')
124
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
5409.3.1 by Alexandre Garnier
Allow using string bug ID with generic bug trackers.
125
        self.assertEqual('http://bugs.com/ABC-1234/view.html',
126
                         tracker.get_bug_url('ABC-1234'))
3035.3.1 by Lukáš Lalinský
Generic bug tracker configuration.
127
3035.3.2 by Lukáš Lalinský
Add tests for InvalidBugTrackerURL.
128
    def test_generic_incorrect_url(self):
129
        branch = self.make_branch('some_branch')
130
        config = branch.get_config()
131
        config.set_user_option('bugtracker_foo_url', 'http://bugs.com/view.html')
132
        tracker = bugtracker.tracker_registry.get_tracker('foo', branch)
133
        self.assertRaises(errors.InvalidBugTrackerURL, tracker.get_bug_url, '1234')
3035.3.1 by Lukáš Lalinský
Generic bug tracker configuration.
134
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
135
136
class TestUniqueIntegerBugTracker(TestCaseWithMemoryTransport):
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
137
3329.1.1 by Ian Clatworthy
Add gnome to list of known bugtrackers (James Westby, Andrew Cowie)
138
    def test_appends_id_to_base_url(self):
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
139
        """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.
140
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
3329.1.1 by Ian Clatworthy
Add gnome to list of known bugtrackers (James Westby, Andrew Cowie)
141
                'http://bugs.com/foo')
142
        self.assertEqual('http://bugs.com/foo1234', tracker.get_bug_url('1234'))
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
143
2376.4.23 by Jonathan Lange
Change 'tag' to 'abbreviated_tracker_name'
144
    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
145
        """The get() method should return an instance of the tracker if the
146
        given abbreviation matches the tracker's abbreviated name.
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
147
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
148
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
149
                'http://bugs.com/')
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
150
        branch = self.make_branch('some_branch')
2376.4.25 by Jonathan Lange
Make singleton bug tracker thing work via instances.
151
        self.assertIs(tracker, tracker.get('xxx', branch))
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
152
2376.4.23 by Jonathan Lange
Change 'tag' to 'abbreviated_tracker_name'
153
    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
154
        """The get() method should return None if the given abbreviated name
155
        doesn't match the tracker's abbreviation.
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
156
        """
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
157
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
158
                'http://bugs.com/')
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
159
        branch = self.make_branch('some_branch')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
160
        self.assertIs(None, tracker.get('yyy', branch))
161
162
    def test_doesnt_consult_branch(self):
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
163
        """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
164
        information.
165
        """
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
        self.assertIs(tracker, tracker.get('xxx', None))
169
        self.assertIs(None, tracker.get('yyy', None))
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
170
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
171
    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
172
        """A UniqueIntegerBugTracker accepts integers as bug IDs."""
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
173
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
174
                'http://bugs.com/')
2376.4.28 by Jonathan Lange
Focus the tests better and clean up some dodgy bits in UnknownBugTrackerAbbreviation
175
        tracker.check_bug_id('1234')
176
177
    def test_check_bug_id_doesnt_accept_non_integers(self):
178
        """A UniqueIntegerBugTracker rejects non-integers as bug IDs."""
3270.5.3 by James Westby
No longer add an extra class to accomoadate gnome.
179
        tracker = bugtracker.UniqueIntegerBugTracker('xxx',
180
                'http://bugs.com/')
2376.4.26 by Jonathan Lange
Tests for MalformedBugIdentifier and new error UnknownBugTrackerAbbreviation.
181
        self.assertRaises(
182
            errors.MalformedBugIdentifier, tracker.check_bug_id, 'red')
2376.4.20 by Jonathan Lange
Direct tests for UniqueBugTracker and UniqueIntegerBugTracker
183
5409.3.2 by Alexandre Garnier
Add tests for URLParametrizedBugTracker rather than reusing existing tests
184
class TestURLParametrizedBugTracker(TestCaseWithMemoryTransport):
185
    """Tests for URLParametrizedBugTracker."""
2376.4.22 by Jonathan Lange
Variety of whitespace cleanups, tightening of tests and docstring changes in
186
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
187
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
188
        super(TestURLParametrizedBugTracker, self).setUp()
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
189
        self.url = 'http://twistedmatrix.com/trac'
5409.3.2 by Alexandre Garnier
Add tests for URLParametrizedBugTracker rather than reusing existing tests
190
        self.tracker = bugtracker.URLParametrizedBugTracker('some', 'ticket/')
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
191
192
    def test_get_with_unsupported_tag(self):
2376.4.7 by jml at canonical
- Add docstrings to tests.
193
        """If asked for an unrecognized or unconfigured tag, return None."""
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
194
        branch = self.make_branch('some_branch')
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
195
        self.assertEqual(None, self.tracker.get('lp', branch))
196
        self.assertEqual(None, self.tracker.get('twisted', branch))
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
197
198
    def test_get_with_supported_tag(self):
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
199
        """If asked for a valid tag, return a tracker instance that can map bug
200
        IDs to <base_url>/<bug_area> + <bug_id>."""
201
        bugtracker.tracker_registry.register('some', self.tracker)
4985.2.1 by Vincent Ladeuil
Deploy addAttrCleanup on the whole test suite.
202
        self.addCleanup(bugtracker.tracker_registry.remove, 'some')
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
203
2376.4.4 by jml at canonical
Beginnings of generic bug-tracker plugin system.
204
        branch = self.make_branch('some_branch')
205
        config = branch.get_config()
2376.4.40 by Jonathan Lange
Redo the hierarchy of bug trackers to reduce duplication.
206
        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
207
        tracker = self.tracker.get('twisted', branch)
208
        self.assertEqual(
209
            urlutils.join(self.url, 'ticket/') + '1234',
210
            tracker.get_bug_url('1234'))
2376.4.7 by jml at canonical
- Add docstrings to tests.
211
5409.3.2 by Alexandre Garnier
Add tests for URLParametrizedBugTracker rather than reusing existing tests
212
    def test_get_bug_url_for_integer_id(self):
213
        self.tracker.check_bug_id('1234')
214
215
    def test_get_bug_url_for_non_integer_id(self):
216
        self.tracker.check_bug_id('ABC-1234')
217
218
219
class TestURLParametrizedIntegerBugTracker(TestCaseWithMemoryTransport):
220
    """Tests for URLParametrizedIntegerBugTracker."""
221
222
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
223
        super(TestURLParametrizedIntegerBugTracker, self).setUp()
5409.3.2 by Alexandre Garnier
Add tests for URLParametrizedBugTracker rather than reusing existing tests
224
        self.url = 'http://twistedmatrix.com/trac'
225
        self.tracker = bugtracker.URLParametrizedIntegerBugTracker('some',
226
                                                                   'ticket/')
227
2376.4.30 by Jonathan Lange
Support for Bugzilla bug trackers.
228
    def test_get_bug_url_for_bad_bug(self):
229
        """When given a bug identifier that is invalid for Trac, get_bug_url
230
        should raise an error.
231
        """
232
        self.assertRaises(
2376.4.42 by Jonathan Lange
Parametrize URLParametrizedIntegerBugTracker even further so we don't need to
233
            errors.MalformedBugIdentifier, self.tracker.get_bug_url, 'bad')
4119.4.2 by Jonathan Lange
Some refactoring, some unit tests.
234
235
236
class TestPropertyEncoding(TestCase):
237
    """Tests for how the bug URLs are encoded as revision properties."""
238
239
    def test_encoding_one(self):
240
        self.assertEqual(
241
            'http://example.com/bugs/1 fixed',
242
            bugtracker.encode_fixes_bug_urls(['http://example.com/bugs/1']))
243
244
    def test_encoding_zero(self):
245
        self.assertEqual('', bugtracker.encode_fixes_bug_urls([]))
246
247
    def test_encoding_two(self):
248
        self.assertEqual(
249
            'http://example.com/bugs/1 fixed\n'
250
            'http://example.com/bugs/2 fixed',
251
            bugtracker.encode_fixes_bug_urls(
252
                ['http://example.com/bugs/1', 'http://example.com/bugs/2']))