content_provider_test.py revision a02191e04bc25c4935f804f2c080ae28663d096d
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 'read.txt': 'read.txt content', 67 'redirects.json': _REDIRECTS_JSON, 68 'noextension': 'noextension content', 69 'run.js': 'run.js content', 70 'site.css': 'site.css content', 71 'storage.html': 'storage.html content', 72 'markdown.md': '\n'.join(text[0] for text in _MARKDOWN_CONTENT) 73} 74 75 76class ContentProviderUnittest(unittest.TestCase): 77 def setUp(self): 78 self._content_provider = self._CreateContentProvider() 79 80 def _CreateContentProvider(self, supports_zip=False): 81 object_store_creator = ObjectStoreCreator.ForTest() 82 test_file_system = TestFileSystem(_TEST_DATA) 83 return ContentProvider( 84 'foo', 85 CompiledFileSystem.Factory(object_store_creator), 86 test_file_system, 87 object_store_creator, 88 default_extensions=('.html', '.md'), 89 # TODO(kalman): Test supports_templates=False. 90 supports_templates=True, 91 supports_zip=supports_zip) 92 93 def _assertContent(self, content, content_type, content_and_type): 94 # Assert type so that str is differentiated from unicode. 95 self.assertEqual(type(content), type(content_and_type.content)) 96 self.assertEqual(content, content_and_type.content) 97 self.assertEqual(content_type, content_and_type.content_type) 98 99 def _assertTemplateContent(self, content, path): 100 content_and_type = self._content_provider.GetContentAndType(path).Get() 101 self.assertEqual(Handlebar, type(content_and_type.content)) 102 content_and_type.content = content_and_type.content.source 103 self._assertContent(content, 'text/html', content_and_type) 104 105 def _assertMarkdownContent(self, content, path): 106 content_and_type = self._content_provider.GetContentAndType(path).Get() 107 content_and_type.content = content_and_type.content.source 108 self._assertContent(content, 'text/html', content_and_type) 109 110 def testPlainText(self): 111 self._assertContent( 112 u'a.txt content', 'text/plain', 113 self._content_provider.GetContentAndType('dir/a.txt').Get()) 114 self._assertContent( 115 u'd.txt content', 'text/plain', 116 self._content_provider.GetContentAndType('dir/c/d.txt').Get()) 117 self._assertContent( 118 u'read.txt content', 'text/plain', 119 self._content_provider.GetContentAndType('read.txt').Get()) 120 self._assertContent( 121 unicode(_REDIRECTS_JSON, 'utf-8'), 'application/json', 122 self._content_provider.GetContentAndType('redirects.json').Get()) 123 self._assertContent( 124 u'run.js content', 'application/javascript', 125 self._content_provider.GetContentAndType('run.js').Get()) 126 self._assertContent( 127 u'site.css content', 'text/css', 128 self._content_provider.GetContentAndType('site.css').Get()) 129 130 def testTemplate(self): 131 self._assertTemplateContent(u'storage.html content', 'storage.html') 132 133 def testImage(self): 134 self._assertContent( 135 'img.png content', 'image/png', 136 self._content_provider.GetContentAndType('img.png').Get()) 137 138 def testZipTopLevel(self): 139 zip_content_provider = self._CreateContentProvider(supports_zip=True) 140 content_and_type = zip_content_provider.GetContentAndType('dir.zip').Get() 141 zipfile = ZipFile(StringIO(content_and_type.content)) 142 content_and_type.content = zipfile.namelist() 143 self._assertContent( 144 ['dir/a.txt', 'dir/b.txt', 'dir/c/d.txt'], 'application/zip', 145 content_and_type) 146 147 def testZip2ndLevel(self): 148 zip_content_provider = self._CreateContentProvider(supports_zip=True) 149 content_and_type = zip_content_provider.GetContentAndType( 150 'dir2/dir3.zip').Get() 151 zipfile = ZipFile(StringIO(content_and_type.content)) 152 content_and_type.content = zipfile.namelist() 153 self._assertContent( 154 ['dir3/a.txt', 'dir3/b.txt', 'dir3/c/d.txt'], 'application/zip', 155 content_and_type) 156 157 def testCanonicalZipPaths(self): 158 # Without supports_zip the path is canonicalized as a file. 159 self.assertEqual( 160 'dir.txt', 161 self._content_provider.GetCanonicalPath('dir.zip')) 162 self.assertEqual( 163 'dir.txt', 164 self._content_provider.GetCanonicalPath('diR.zip')) 165 # With supports_zip the path is canonicalized as the zip file which 166 # corresponds to the canonical directory. 167 zip_content_provider = self._CreateContentProvider(supports_zip=True) 168 self.assertEqual( 169 'dir.zip', 170 zip_content_provider.GetCanonicalPath('dir.zip')) 171 self.assertEqual( 172 'dir.zip', 173 zip_content_provider.GetCanonicalPath('diR.zip')) 174 175 def testMarkdown(self): 176 self._assertMarkdownContent( 177 '\n'.join(text[1] for text in _MARKDOWN_CONTENT), 178 'markdown') 179 180 def testNotFound(self): 181 self.assertRaises( 182 FileNotFoundError, 183 self._content_provider.GetContentAndType('oops').Get) 184 185 def testIndexRedirect(self): 186 self._assertTemplateContent(u'index.html content 1', 'dir4') 187 self._assertTemplateContent(u'dir5.html content', 'dir5') 188 self._assertMarkdownContent( 189 '\n'.join(text[1] for text in _MARKDOWN_CONTENT), 190 'dir7') 191 self._assertContent( 192 'noextension content', 'text/plain', 193 self._content_provider.GetContentAndType('noextension').Get()) 194 self.assertRaises( 195 FileNotFoundError, 196 self._content_provider.GetContentAndType('dir6').Get) 197 198if __name__ == '__main__': 199 unittest.main() 200