content_provider_test.py revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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 6from cStringIO import StringIO 7import json 8import unittest 9from zipfile import ZipFile 10 11from compiled_file_system import CompiledFileSystem 12from content_provider import ContentProvider 13from file_system import FileNotFoundError 14from object_store_creator import ObjectStoreCreator 15from path_canonicalizer import PathCanonicalizer 16from test_file_system import TestFileSystem 17from third_party.handlebar import Handlebar 18 19_REDIRECTS_JSON = json.dumps({ 20 'oldfile.html': 'storage.html', 21 'index.html': 'https://developers.google.com/chrome', 22}) 23 24 25_MARKDOWN_CONTENT = ( 26 ('# Header 1 #', u'<h1 id="header-1">Header 1</h1>'), 27 ('1. Foo\n', u'<ol>\n<li>Foo</li>\n</ol>'), 28 ('![alt text](/path/img.jpg "Title")\n', 29 '<p><img alt="alt text" src="/path/img.jpg" title="Title" /></p>'), 30 ('* Unordered item 1', u'<ul>\n<li>Unordered item 1</li>\n</ul>') 31) 32 33# Test file system data which exercises many different mimetypes. 34_TEST_DATA = { 35 'dir': { 36 'a.txt': 'a.txt content', 37 'b.txt': 'b.txt content', 38 'c': { 39 'd.txt': 'd.txt content', 40 }, 41 }, 42 'dir2': { 43 'dir3': { 44 'a.txt': 'a.txt content', 45 'b.txt': 'b.txt content', 46 'c': { 47 'd.txt': 'd.txt content', 48 }, 49 }, 50 }, 51 'dir4': { 52 'index.html': 'index.html content 1' 53 }, 54 'dir5': { 55 'index.html': 'index.html content 2' 56 }, 57 'dir6': { 58 'notindex.html': 'notindex.html content' 59 }, 60 'dir7': { 61 'index.md': '\n'.join(text[0] for text in _MARKDOWN_CONTENT) 62 }, 63 'dir.txt': 'dir.txt content', 64 'dir5.html': 'dir5.html content', 65 'img.png': 'img.png content', 66 'index.html': 'index.html content', 67 'read.txt': 'read.txt content', 68 'redirects.json': _REDIRECTS_JSON, 69 'noextension': 'noextension content', 70 'run.js': 'run.js content', 71 'site.css': 'site.css content', 72 'storage.html': 'storage.html content', 73 'markdown.md': '\n'.join(text[0] for text in _MARKDOWN_CONTENT) 74} 75 76 77class ContentProviderUnittest(unittest.TestCase): 78 def setUp(self): 79 self._content_provider = self._CreateContentProvider() 80 81 def _CreateContentProvider(self, supports_zip=False): 82 object_store_creator = ObjectStoreCreator.ForTest() 83 test_file_system = TestFileSystem(_TEST_DATA) 84 return ContentProvider( 85 'foo', 86 CompiledFileSystem.Factory(object_store_creator), 87 test_file_system, 88 object_store_creator, 89 default_extensions=('.html', '.md'), 90 # TODO(kalman): Test supports_templates=False. 91 supports_templates=True, 92 supports_zip=supports_zip) 93 94 def _assertContent(self, content, content_type, content_and_type): 95 # Assert type so that str is differentiated from unicode. 96 self.assertEqual(type(content), type(content_and_type.content)) 97 self.assertEqual(content, content_and_type.content) 98 self.assertEqual(content_type, content_and_type.content_type) 99 100 def _assertTemplateContent(self, content, path): 101 content_and_type = self._content_provider.GetContentAndType(path).Get() 102 self.assertEqual(Handlebar, type(content_and_type.content)) 103 content_and_type.content = content_and_type.content.source 104 self._assertContent(content, 'text/html', content_and_type) 105 106 def _assertMarkdownContent(self, content, path): 107 content_and_type = self._content_provider.GetContentAndType(path).Get() 108 content_and_type.content = content_and_type.content.source 109 self._assertContent(content, 'text/html', content_and_type) 110 111 def testPlainText(self): 112 self._assertContent( 113 u'a.txt content', 'text/plain', 114 self._content_provider.GetContentAndType('dir/a.txt').Get()) 115 self._assertContent( 116 u'd.txt content', 'text/plain', 117 self._content_provider.GetContentAndType('dir/c/d.txt').Get()) 118 self._assertContent( 119 u'read.txt content', 'text/plain', 120 self._content_provider.GetContentAndType('read.txt').Get()) 121 self._assertContent( 122 unicode(_REDIRECTS_JSON, 'utf-8'), 'application/json', 123 self._content_provider.GetContentAndType('redirects.json').Get()) 124 self._assertContent( 125 u'run.js content', 'application/javascript', 126 self._content_provider.GetContentAndType('run.js').Get()) 127 self._assertContent( 128 u'site.css content', 'text/css', 129 self._content_provider.GetContentAndType('site.css').Get()) 130 131 def testTemplate(self): 132 self._assertTemplateContent(u'storage.html content', 'storage.html') 133 134 def testImage(self): 135 self._assertContent( 136 'img.png content', 'image/png', 137 self._content_provider.GetContentAndType('img.png').Get()) 138 139 def testZipTopLevel(self): 140 zip_content_provider = self._CreateContentProvider(supports_zip=True) 141 content_and_type = zip_content_provider.GetContentAndType('dir.zip').Get() 142 zipfile = ZipFile(StringIO(content_and_type.content)) 143 content_and_type.content = zipfile.namelist() 144 self._assertContent( 145 ['dir/a.txt', 'dir/b.txt', 'dir/c/d.txt'], 'application/zip', 146 content_and_type) 147 148 def testZip2ndLevel(self): 149 zip_content_provider = self._CreateContentProvider(supports_zip=True) 150 content_and_type = zip_content_provider.GetContentAndType( 151 'dir2/dir3.zip').Get() 152 zipfile = ZipFile(StringIO(content_and_type.content)) 153 content_and_type.content = zipfile.namelist() 154 self._assertContent( 155 ['dir3/a.txt', 'dir3/b.txt', 'dir3/c/d.txt'], 'application/zip', 156 content_and_type) 157 158 def testCanonicalZipPaths(self): 159 # Without supports_zip the path is canonicalized as a file. 160 self.assertEqual( 161 'dir.txt', 162 self._content_provider.GetCanonicalPath('dir.zip')) 163 self.assertEqual( 164 'dir.txt', 165 self._content_provider.GetCanonicalPath('diR.zip')) 166 # With supports_zip the path is canonicalized as the zip file which 167 # corresponds to the canonical directory. 168 zip_content_provider = self._CreateContentProvider(supports_zip=True) 169 self.assertEqual( 170 'dir.zip', 171 zip_content_provider.GetCanonicalPath('dir.zip')) 172 self.assertEqual( 173 'dir.zip', 174 zip_content_provider.GetCanonicalPath('diR.zip')) 175 176 def testMarkdown(self): 177 self._assertMarkdownContent( 178 '\n'.join(text[1] for text in _MARKDOWN_CONTENT), 179 'markdown') 180 181 def testNotFound(self): 182 self.assertRaises( 183 FileNotFoundError, 184 self._content_provider.GetContentAndType('oops').Get) 185 186 def testIndexRedirect(self): 187 self._assertTemplateContent(u'index.html content', '') 188 self._assertTemplateContent(u'index.html content 1', 'dir4') 189 self._assertTemplateContent(u'dir5.html content', 'dir5') 190 self._assertMarkdownContent( 191 '\n'.join(text[1] for text in _MARKDOWN_CONTENT), 192 'dir7') 193 self._assertContent( 194 'noextension content', 'text/plain', 195 self._content_provider.GetContentAndType('noextension').Get()) 196 self.assertRaises( 197 FileNotFoundError, 198 self._content_provider.GetContentAndType('dir6').Get) 199 200if __name__ == '__main__': 201 unittest.main() 202