~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/tests/test_simple.py

  • Committer: John Arbash Meinel
  • Date: 2011-06-15 14:47:11 UTC
  • mfrom: (447.1.3 loggerhead)
  • Revision ID: john@arbash-meinel.com-20110615144711-wv0wgim27u1ismhi
Merge css updates for annotate from Jasper St. Pierre.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007, 2008, 2009, 2011 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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
#
 
17
 
1
18
import cgi
2
 
import unittest
3
 
import os
4
 
import tempfile
5
 
import shutil
6
19
import logging
7
 
 
8
 
import bzrlib.bzrdir
9
 
import bzrlib.osutils
10
 
from configobj import ConfigObj
11
 
 
12
 
from loggerhead.history import History
 
20
import re
 
21
 
 
22
from bzrlib.tests import TestCaseWithTransport
 
23
try:
 
24
    from bzrlib.util.configobj.configobj import ConfigObj
 
25
except ImportError:
 
26
    from configobj import ConfigObj
 
27
from bzrlib import config
 
28
 
13
29
from loggerhead.apps.branch import BranchWSGIApp
 
30
from loggerhead.apps.http_head import HeadMiddleware
14
31
from paste.fixture import TestApp
15
 
 
16
 
 
17
 
def test_config_root():
18
 
    from loggerhead.apps.config import Root
19
 
    config = ConfigObj()
20
 
    app = TestApp(Root(config))
21
 
    res = app.get('/')
22
 
    res.mustcontain('loggerhead branches')
23
 
 
24
 
 
25
 
class BasicTests(object):
26
 
 
27
 
    # setup_method and teardown_method are so i can run the tests with
28
 
    # py.test and take advantage of the error reporting.
29
 
    def setup_method(self, meth):
30
 
        self.setUp()
31
 
 
32
 
    def teardown_method(self, meth):
33
 
        self.tearDown()
 
32
from paste.httpexceptions import HTTPExceptionHandler, HTTPMovedPermanently
 
33
 
 
34
 
 
35
 
 
36
class BasicTests(TestCaseWithTransport):
34
37
 
35
38
    def setUp(self):
36
 
        logging.basicConfig(level=logging.DEBUG)
37
 
        self.bzrbranch = None
38
 
        self.old_bzrhome = None
 
39
        TestCaseWithTransport.setUp(self)
 
40
        logging.basicConfig(level=logging.ERROR)
 
41
        logging.getLogger('bzr').setLevel(logging.CRITICAL)
39
42
 
40
43
    def createBranch(self):
41
 
        self.old_bzrhome = bzrlib.osutils.set_or_unset_env('BZR_HOME', '')
42
 
        self.bzrbranch = tempfile.mkdtemp()
43
 
        self.branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
44
 
            self.bzrbranch, force_new_tree=True)
45
 
        self.tree = self.branch.bzrdir.open_workingtree()
46
 
 
47
 
    config_template = """
48
 
    [project]
49
 
        [[branch]]
50
 
            branch_name = 'branch'
51
 
            folder = '%(branch)s'
52
 
    """
53
 
 
54
 
    def makeHistory(self):
55
 
        return History.from_folder(self.bzrbranch)
56
 
 
57
 
    def setUpLoggerhead(self):
58
 
        app = TestApp(BranchWSGIApp(self.bzrbranch).app)
59
 
        return app
60
 
 
61
 
    def tearDown(self):
62
 
        if self.bzrbranch is not None:
63
 
            shutil.rmtree(self.bzrbranch)
64
 
        bzrlib.osutils.set_or_unset_env('BZR_HOME', self.old_bzrhome)
 
44
        self.tree = self.make_branch_and_tree('.')
 
45
 
 
46
    def setUpLoggerhead(self, **kw):
 
47
        branch_app = BranchWSGIApp(self.tree.branch, '', **kw).app
 
48
        return TestApp(HTTPExceptionHandler(branch_app))
65
49
 
66
50
 
67
51
class TestWithSimpleTree(BasicTests):
70
54
        BasicTests.setUp(self)
71
55
        self.createBranch()
72
56
 
73
 
        f = open(os.path.join(self.bzrbranch, 'myfilename'), 'w')
74
57
        self.filecontents = ('some\nmultiline\ndata\n'
75
58
                             'with<htmlspecialchars\n')
76
 
        try:
77
 
            f.write(self.filecontents)
78
 
        finally:
79
 
            f.close()
80
 
        self.tree.add('myfilename')
 
59
        filenames = ['myfilename', 'anotherfile<']
 
60
        self.build_tree_contents(
 
61
            (filename, self.filecontents) for filename in filenames)
 
62
        for filename in filenames:
 
63
            self.tree.add(filename, '%s-id' % filename)
81
64
        self.fileid = self.tree.path2id('myfilename')
82
65
        self.msg = 'a very exciting commit message <'
83
66
        self.revid = self.tree.commit(message=self.msg)
84
67
 
85
 
 
86
68
    def test_changes(self):
87
69
        app = self.setUpLoggerhead()
88
70
        res = app.get('/changes')
89
71
        res.mustcontain(cgi.escape(self.msg))
90
72
 
 
73
    def test_changes_for_file(self):
 
74
        app = self.setUpLoggerhead()
 
75
        res = app.get('/changes?filter_file_id=myfilename-id')
 
76
        res.mustcontain(cgi.escape(self.msg))
 
77
 
 
78
    def test_changes_branch_from(self):
 
79
        app = self.setUpLoggerhead(served_url="lp:loggerhead")
 
80
        res = app.get('/changes')
 
81
        self.failUnless("To get this branch, use:" in res)
 
82
        self.failUnless("lp:loggerhead" in res)
 
83
        app = self.setUpLoggerhead(served_url=None)
 
84
        res = app.get('/changes')
 
85
        self.failIf("To get this branch, use:" in res)
 
86
 
91
87
    def test_changes_search(self):
92
88
        app = self.setUpLoggerhead()
93
89
        res = app.get('/changes', params={'q': 'foo'})
95
91
 
96
92
    def test_annotate(self):
97
93
        app = self.setUpLoggerhead()
98
 
        res = app.get('/annotate', params={'file_id':self.fileid})
 
94
        res = app.get('/annotate', params={'file_id': self.fileid})
 
95
        # If pygments is installed, it inserts <span class="pyg" content into
 
96
        # the output, to trigger highlighting. And it specifically highlights
 
97
        # the &lt; that we are interested in seeing in the output.
 
98
        # Without pygments we have a simple: 'with&lt;htmlspecialchars'
 
99
        # With it, we have
 
100
        # '<span class='pyg-n'>with</span><span class='pyg-o'>&lt;</span>'
 
101
        # '<span class='pyg-n'>htmlspecialchars</span>
 
102
        # So we pre-filter the body, to make sure remove spans of that type.
 
103
        body_no_span = re.sub(r'<span class="pyg-.">', '', res.body)
 
104
        body_no_span = body_no_span.replace('</span>', '')
99
105
        for line in self.filecontents.splitlines():
100
 
            res.mustcontain(cgi.escape(line))
 
106
            escaped = cgi.escape(line)
 
107
            self.assertTrue(escaped in body_no_span,
 
108
                            "did not find %r in %r" % (escaped, body_no_span))
101
109
 
102
110
    def test_inventory(self):
103
111
        app = self.setUpLoggerhead()
104
112
        res = app.get('/files')
105
113
        res.mustcontain('myfilename')
 
114
        res = app.get('/files/')
 
115
        res.mustcontain('myfilename')
 
116
        res = app.get('/files/1')
 
117
        res.mustcontain('myfilename')
 
118
        res = app.get('/files/1/')
 
119
        res.mustcontain('myfilename')
 
120
        res = app.get('/files/1/?file_id=' + self.tree.path2id(''))
 
121
        res.mustcontain('myfilename')
 
122
 
 
123
    def test_inventory_bad_rev_404(self):
 
124
        app = self.setUpLoggerhead()
 
125
        res = app.get('/files/200', status=404)
 
126
        res = app.get('/files/invalid-revid', status=404)
 
127
 
 
128
    def test_inventory_bad_path_404(self):
 
129
        app = self.setUpLoggerhead()
 
130
        res = app.get('/files/1/hooha', status=404)
 
131
        res = app.get('/files/1?file_id=dssadsada', status=404)
106
132
 
107
133
    def test_revision(self):
108
134
        app = self.setUpLoggerhead()
109
135
        res = app.get('/revision/1')
 
136
        res.mustcontain(no=['anotherfile<'])
 
137
        res.mustcontain('anotherfile&lt;')
110
138
        res.mustcontain('myfilename')
111
139
 
112
140
 
113
141
class TestEmptyBranch(BasicTests):
 
142
    """Test that an empty branch doesn't break"""
114
143
 
115
144
    def setUp(self):
116
145
        BasicTests.setUp(self)
121
150
        res = app.get('/changes')
122
151
        res.mustcontain('No revisions!')
123
152
 
 
153
    def test_inventory(self):
 
154
        app = self.setUpLoggerhead()
 
155
        res = app.get('/files')
 
156
        res.mustcontain('No revisions!')
 
157
 
 
158
 
 
159
class TestHiddenBranch(BasicTests):
 
160
    """
 
161
    Test that hidden branches aren't shown
 
162
    FIXME: not tested that it doesn't show up on listings
 
163
    """
 
164
 
 
165
    def setUp(self):
 
166
        BasicTests.setUp(self)
 
167
        self.createBranch()
 
168
        locations = config.locations_config_filename()
 
169
        config.ensure_config_dir_exists()
 
170
        open(locations, 'wb').write('[%s]\nhttp_serve = False'
 
171
                                    % (self.tree.branch.base,))
 
172
 
 
173
    def test_no_access(self):
 
174
        app = self.setUpLoggerhead()
 
175
        res = app.get('/changes', status=404)
 
176
 
 
177
 
 
178
class TestControllerRedirects(BasicTests):
 
179
    """
 
180
    Test that a file under /files redirects to /view,
 
181
    and a directory under /view redirects to /files.
 
182
    """
 
183
 
 
184
    def setUp(self):
 
185
        BasicTests.setUp(self)
 
186
        self.createBranch()
 
187
        self.build_tree(('file', 'folder/', 'folder/file'))
 
188
        self.tree.smart_add([])
 
189
        self.tree.commit('')
 
190
 
 
191
    def test_view_folder(self):
 
192
        app = TestApp(BranchWSGIApp(self.tree.branch, '').app)
 
193
 
 
194
        e = self.assertRaises(HTTPMovedPermanently, app.get, '/view/head:/folder')
 
195
        self.assertEqual(e.location(), '/files/head:/folder')
 
196
 
 
197
    def test_files_file(self):
 
198
        app = TestApp(BranchWSGIApp(self.tree.branch, '').app)
 
199
 
 
200
        e = self.assertRaises(HTTPMovedPermanently, app.get, '/files/head:/folder/file')
 
201
        self.assertEqual(e.location(), '/view/head:/folder/file')
 
202
        e = self.assertRaises(HTTPMovedPermanently, app.get, '/files/head:/file')
 
203
        self.assertEqual(e.location(), '/view/head:/file')
 
204
 
 
205
 
 
206
class TestHeadMiddleware(BasicTests):
 
207
 
 
208
    def setUp(self):
 
209
        BasicTests.setUp(self)
 
210
        self.createBranch()
 
211
        self.msg = 'trivial commit message'
 
212
        self.revid = self.tree.commit(message=self.msg)
 
213
 
 
214
    def setUpLoggerhead(self, **kw):
 
215
        branch_app = BranchWSGIApp(self.tree.branch, '', **kw).app
 
216
        return TestApp(HTTPExceptionHandler(HeadMiddleware(branch_app)))
 
217
 
 
218
    def test_get(self):
 
219
        app = self.setUpLoggerhead()
 
220
        res = app.get('/changes')
 
221
        res.mustcontain(self.msg)
 
222
        self.assertEqual('text/html', res.header('Content-Type'))
 
223
 
 
224
    def test_head(self):
 
225
        app = self.setUpLoggerhead()
 
226
        res = app.get('/changes', extra_environ={'REQUEST_METHOD': 'HEAD'})
 
227
        self.assertEqual('text/html', res.header('Content-Type'))
 
228
        self.assertEqualDiff('', res.body)
 
229
 
 
230
 
 
231
#class TestGlobalConfig(BasicTests):
 
232
#    """
 
233
#    Test that global config settings are respected
 
234
#    """
 
235
 
 
236
#    def setUp(self):
 
237
#        BasicTests.setUp(self)
 
238
#        self.createBranch()
 
239
#        config.GlobalConfig().set_user_option('http_version', 'True')
 
240
 
 
241
#    def test_setting_respected(self):
 
242
        #FIXME: Figure out how to test this properly
 
243
#        app = self.setUpLoggerhead()
 
244
#        res = app.get('/changes', status=200)