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