1
# Copyright (C) 2007, 2008, 2009, 2011 Canonical Ltd.
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.
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.
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
22
from cStringIO import StringIO
24
4
from bzrlib.tests import TestCaseWithTransport
26
from bzrlib.util.configobj.configobj import ConfigObj
28
from configobj import ConfigObj
29
from bzrlib import config
5
from bzrlib.util.configobj.configobj import ConfigObj
31
7
from loggerhead.apps.branch import BranchWSGIApp
32
from loggerhead.apps.http_head import HeadMiddleware
33
8
from paste.fixture import TestApp
34
from paste.httpexceptions import HTTPExceptionHandler, HTTPMovedPermanently
36
from loggerhead.tests.fixtures import (
9
from paste.httpexceptions import HTTPExceptionHandler
13
def test_config_root():
14
from loggerhead.apps.config import Root
16
app = TestApp(HTTPExceptionHandler(Root(config)))
18
res.mustcontain('loggerhead branches')
41
21
class BasicTests(TestCaseWithTransport):
52
32
branch_app = BranchWSGIApp(self.tree.branch, '', **kw).app
53
33
return TestApp(HTTPExceptionHandler(branch_app))
55
def assertOkJsonResponse(self, app, env):
56
start, content = consume_app(app, env)
57
self.assertEqual('200 OK', start[0])
58
self.assertEqual('application/json', dict(start[1])['Content-Type'])
59
self.assertEqual(None, start[2])
60
simplejson.loads(content)
62
def make_branch_app(self, branch, **kw):
63
branch_app = BranchWSGIApp(branch, friendly_name='friendly-name', **kw)
64
branch_app._environ = {
69
branch_app._url_base = ''
73
36
class TestWithSimpleTree(BasicTests):
76
39
BasicTests.setUp(self)
77
self.sample_branch_fixture = SampleBranch(self)
79
# XXX: This could be cleaned up more... -- mbp 2011-11-25
80
self.useFixture(self.sample_branch_fixture)
81
self.tree = self.sample_branch_fixture.tree
82
self.fileid = self.sample_branch_fixture.fileid
83
self.filecontents = self.sample_branch_fixture.filecontents
84
self.msg = self.sample_branch_fixture.msg
86
def test_public_private(self):
87
app = self.make_branch_app(self.tree.branch, private=True)
88
self.assertEqual(app.public_private_css(), 'private')
89
app = self.make_branch_app(self.tree.branch)
90
self.assertEqual(app.public_private_css(), 'public')
42
self.filecontents = ('some\nmultiline\ndata\n'
43
'with<htmlspecialchars\n')
44
self.build_tree_contents(
45
[('myfilename', self.filecontents)])
46
self.tree.add('myfilename')
47
self.fileid = self.tree.path2id('myfilename')
48
self.msg = 'a very exciting commit message <'
49
self.revid = self.tree.commit(message=self.msg)
92
51
def test_changes(self):
93
52
app = self.setUpLoggerhead()
94
53
res = app.get('/changes')
95
54
res.mustcontain(cgi.escape(self.msg))
97
def test_changes_for_file(self):
98
app = self.setUpLoggerhead()
99
res = app.get('/changes?filter_file_id=myfilename-id')
100
res.mustcontain(cgi.escape(self.msg))
102
56
def test_changes_branch_from(self):
103
57
app = self.setUpLoggerhead(served_url="lp:loggerhead")
104
58
res = app.get('/changes')
105
59
self.failUnless("To get this branch, use:" in res)
106
60
self.failUnless("lp:loggerhead" in res)
108
def test_no_empty_download_location(self):
109
"""With no served_url, no instructions how to get it"""
110
app = self.setUpLoggerhead()
61
app = self.setUpLoggerhead(served_url=None)
111
62
res = app.get('/changes')
112
63
self.failIf("To get this branch, use:" in res)
119
70
def test_annotate(self):
120
71
app = self.setUpLoggerhead()
121
72
res = app.get('/annotate', params={'file_id': self.fileid})
122
# If pygments is installed, it inserts <span class="pyg" content into
123
# the output, to trigger highlighting. And it specifically highlights
124
# the < that we are interested in seeing in the output.
125
# Without pygments we have a simple: 'with<htmlspecialchars'
127
# '<span class='pyg-n'>with</span><span class='pyg-o'><</span>'
128
# '<span class='pyg-n'>htmlspecialchars</span>
129
# So we pre-filter the body, to make sure remove spans of that type.
130
body_no_span = re.sub(r'<span class="pyg-.">', '', res.body)
131
body_no_span = body_no_span.replace('</span>', '')
132
73
for line in self.filecontents.splitlines():
133
escaped = cgi.escape(line)
134
self.assertTrue(escaped in body_no_span,
135
"did not find %r in %r" % (escaped, body_no_span))
74
res.mustcontain(cgi.escape(line))
137
76
def test_inventory(self):
138
77
app = self.setUpLoggerhead()
182
118
res = app.get('/files')
183
119
res.mustcontain('No revisions!')
186
class TestHiddenBranch(BasicTests):
188
Test that hidden branches aren't shown
189
FIXME: not tested that it doesn't show up on listings
193
BasicTests.setUp(self)
195
locations = config.locations_config_filename()
196
config.ensure_config_dir_exists()
197
open(locations, 'wb').write('[%s]\nhttp_serve = False'
198
% (self.tree.branch.base,))
200
def test_no_access(self):
201
app = self.setUpLoggerhead()
202
res = app.get('/changes', status=404)
205
class TestControllerRedirects(BasicTests):
207
Test that a file under /files redirects to /view,
208
and a directory under /view redirects to /files.
212
BasicTests.setUp(self)
214
self.build_tree(('file', 'folder/', 'folder/file'))
215
self.tree.smart_add([])
218
def test_view_folder(self):
219
app = TestApp(BranchWSGIApp(self.tree.branch, '').app)
221
e = self.assertRaises(HTTPMovedPermanently, app.get, '/view/head:/folder')
222
self.assertEqual(e.location(), '/files/head:/folder')
224
def test_files_file(self):
225
app = TestApp(BranchWSGIApp(self.tree.branch, '').app)
227
e = self.assertRaises(HTTPMovedPermanently, app.get, '/files/head:/folder/file')
228
self.assertEqual(e.location(), '/view/head:/folder/file')
229
e = self.assertRaises(HTTPMovedPermanently, app.get, '/files/head:/file')
230
self.assertEqual(e.location(), '/view/head:/file')
233
class TestHeadMiddleware(BasicTests):
236
BasicTests.setUp(self)
238
self.msg = 'trivial commit message'
239
self.revid = self.tree.commit(message=self.msg)
241
def setUpLoggerhead(self, **kw):
242
branch_app = BranchWSGIApp(self.tree.branch, '', **kw).app
243
return TestApp(HTTPExceptionHandler(HeadMiddleware(branch_app)))
246
app = self.setUpLoggerhead()
247
res = app.get('/changes')
248
res.mustcontain(self.msg)
249
self.assertEqual('text/html', res.header('Content-Type'))
252
app = self.setUpLoggerhead()
253
res = app.get('/changes', extra_environ={'REQUEST_METHOD': 'HEAD'})
254
self.assertEqual('text/html', res.header('Content-Type'))
255
self.assertEqualDiff('', res.body)
258
def consume_app(app, env):
261
def start_response(status, headers, exc_info=None):
262
start.append((status, headers, exc_info))
264
extra_content = list(app(env, start_response))
265
body.writelines(extra_content)
266
return start[0], body.getvalue()
270
#class TestGlobalConfig(BasicTests):
272
# Test that global config settings are respected
276
# BasicTests.setUp(self)
277
# self.createBranch()
278
# config.GlobalConfig().set_user_option('http_version', 'True')
280
# def test_setting_respected(self):
281
#FIXME: Figure out how to test this properly
282
# app = self.setUpLoggerhead()
283
# res = app.get('/changes', status=200)