1 #!/usr/bin/env python 2 # Copyright 2013 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 import unittest 7 8 from extensions_paths import EXAMPLES, PUBLIC_TEMPLATES, STATIC_DOCS 9 from local_file_system import LocalFileSystem 10 from render_servlet import RenderServlet 11 from server_instance import ServerInstance 12 from servlet import Request, Response 13 from test_util import ReadFile 14 15 16 class _RenderServletDelegate(RenderServlet.Delegate): 17 def CreateServerInstance(self): 18 return ServerInstance.ForTest(LocalFileSystem.Create()) 19 20 21 class RenderServletTest(unittest.TestCase): 22 def _Render(self, path, headers=None, host=None): 23 return RenderServlet(Request.ForTest(path, headers=headers, host=host), 24 _RenderServletDelegate()).Get() 25 26 def testExtensionAppRedirect(self): 27 self.assertEqual( 28 Response.Redirect('/apps/storage', permanent=False), 29 self._Render('storage')) 30 31 def testChannelRedirect(self): 32 for channel in ('stable', 'beta', 'dev', 'trunk'): 33 self.assertEqual( 34 Response.Redirect('/extensions/storage', permanent=True), 35 self._Render('%s/extensions/storage' % channel)) 36 37 def testOldHostsRedirect(self): 38 self.assertEqual( 39 Response.Redirect('https://developer.chrome.com/extensions', 40 permanent=False), 41 self._Render('/chrome/extensions', host='http://code.google.com')) 42 self.assertEqual( 43 Response.Redirect('https://developer.chrome.com/extensions', 44 permanent=False), 45 self._Render('/chrome/extensions', host='https://code.google.com')) 46 47 def testNotFound(self): 48 def create_404_response(real_path): 49 real_404 = self._Render(real_path) 50 self.assertEqual(200, real_404.status) 51 real_404.status = 404 52 return real_404 53 54 root_404 = create_404_response('404') 55 extensions_404 = create_404_response('extensions/404') 56 apps_404 = create_404_response('apps/404') 57 58 self.assertEqual(root_404, self._Render('not_found')) 59 self.assertEqual(root_404, self._Render('not_found/not_found')) 60 61 self.assertEqual(extensions_404, self._Render('extensions/not_found')) 62 self.assertEqual( 63 extensions_404, self._Render('extensions/manifest/not_found')) 64 self.assertEqual( 65 extensions_404, 66 self._Render('extensions/manifest/not_found/not_found')) 67 68 self.assertEqual(apps_404, self._Render('apps/not_found')) 69 self.assertEqual(apps_404, self._Render('apps/manifest/not_found')) 70 self.assertEqual( 71 apps_404, self._Render('apps/manifest/not_found/not_found')) 72 73 def testSampleFile(self): 74 sample_file = 'extensions/talking_alarm_clock/background.js' 75 response = self._Render('extensions/examples/%s' % sample_file) 76 self.assertEqual(200, response.status) 77 self.assertTrue(response.headers['Content-Type'] in ( 78 'application/javascript; charset=utf-8', 79 'application/x-javascript; charset=utf-8')) 80 self.assertEqual(ReadFile('%s%s' % (EXAMPLES, sample_file)), 81 response.content.ToString()) 82 83 def testSampleZip(self): 84 sample_dir = 'extensions/talking_alarm_clock' 85 response = self._Render('extensions/examples/%s.zip' % sample_dir) 86 self.assertEqual(200, response.status) 87 self.assertEqual('application/zip', response.headers['Content-Type']) 88 89 def testStaticFile(self): 90 static_file = 'css/out/site.css' 91 response = self._Render('static/%s' % static_file) 92 self.assertEqual(200, response.status) 93 self.assertEqual('text/css; charset=utf-8', 94 response.headers['Content-Type']) 95 self.assertEqual(ReadFile('%s%s' % (STATIC_DOCS, static_file)), 96 response.content.ToString()) 97 98 def testHtmlTemplate(self): 99 html_file = 'extensions/storage' 100 response = self._Render(html_file) 101 self.assertEqual(200, response.status) 102 self.assertEqual('text/html; charset=utf-8', 103 response.headers.get('Content-Type')) 104 # Can't really test rendering all that well. 105 self.assertTrue(len(response.content) > 106 len(ReadFile('%s%s.html' % (PUBLIC_TEMPLATES, html_file)))) 107 108 def testIndexRender(self): 109 response = self._Render('extensions') 110 self.assertEqual(200, response.status) 111 self.assertEqual(self._Render('extensions/index').content.ToString(), 112 response.content.ToString()) 113 114 def testOtherRedirectsJsonRedirect(self): 115 response = self._Render('apps/webview_tag') 116 self.assertEqual(('/apps/tags/webview', False), 117 response.GetRedirect()) 118 119 def testDirectories(self): 120 # Directories should be redirected to a URL that doesn't end in a '/' 121 # whether or not that exists. 122 self.assertEqual(('/dir', False), self._Render('dir/').GetRedirect()) 123 124 def testEtags(self): 125 def test_path(path, content_type): 126 # Render without etag. 127 response = self._Render(path) 128 self.assertEqual(200, response.status) 129 etag = response.headers.get('ETag') 130 self.assertTrue(etag is not None) 131 132 # Render with an If-None-Match which doesn't match. 133 response = self._Render(path, headers={ 134 'If-None-Match': '"fake etag"', 135 }) 136 self.assertEqual(200, response.status) 137 self.assertEqual(content_type, response.headers.get('Content-Type')) 138 self.assertEqual(etag, response.headers.get('ETag')) 139 140 # Render with the correct matching If-None-Match. 141 response = self._Render(path, headers={ 142 'If-None-Match': etag, 143 }) 144 self.assertEqual(304, response.status) 145 self.assertEqual('Not Modified', response.content.ToString()) 146 self.assertEqual(content_type, response.headers.get('Content-Type')) 147 self.assertEqual(etag, response.headers.get('ETag')) 148 149 # Test with a static path and a dynamic path. 150 test_path('static/css/out/site.css', 'text/css; charset=utf-8') 151 test_path('extensions/storage', 'text/html; charset=utf-8') 152 153 154 if __name__ == '__main__': 155 unittest.main() 156