Home | History | Annotate | Download | only in server2
      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 from cStringIO import StringIO
      7 import json
      8 import unittest
      9 from zipfile import ZipFile
     10 
     11 from compiled_file_system import CompiledFileSystem
     12 from content_provider import ContentProvider
     13 from file_system import FileNotFoundError
     14 from object_store_creator import ObjectStoreCreator
     15 from path_canonicalizer import PathCanonicalizer
     16 from test_file_system import TestFileSystem
     17 from third_party.motemplate import Motemplate
     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 
     77 class ContentProviderUnittest(unittest.TestCase):
     78   def setUp(self):
     79     self._test_file_system = TestFileSystem(_TEST_DATA)
     80     self._content_provider = self._CreateContentProvider()
     81 
     82   def _CreateContentProvider(self, supports_zip=False):
     83     object_store_creator = ObjectStoreCreator.ForTest()
     84     return ContentProvider(
     85         'foo',
     86         CompiledFileSystem.Factory(object_store_creator),
     87         self._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, version):
    101     content_and_type = self._content_provider.GetContentAndType(path).Get()
    102     self.assertEqual(Motemplate, 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     self.assertEqual(version, self._content_provider.GetVersion(path).Get())
    106 
    107   def _assertMarkdownContent(self, content, path, version):
    108     content_and_type = self._content_provider.GetContentAndType(path).Get()
    109     content_and_type.content = content_and_type.content.source
    110     self._assertContent(content, 'text/html', content_and_type)
    111     self.assertEqual(version, self._content_provider.GetVersion(path).Get())
    112 
    113   def testPlainText(self):
    114     self._assertContent(
    115         u'a.txt content', 'text/plain',
    116         self._content_provider.GetContentAndType('dir/a.txt').Get())
    117     self._assertContent(
    118         u'd.txt content', 'text/plain',
    119         self._content_provider.GetContentAndType('dir/c/d.txt').Get())
    120     self._assertContent(
    121         u'read.txt content', 'text/plain',
    122         self._content_provider.GetContentAndType('read.txt').Get())
    123     self._assertContent(
    124         unicode(_REDIRECTS_JSON, 'utf-8'), 'application/json',
    125         self._content_provider.GetContentAndType('redirects.json').Get())
    126     self._assertContent(
    127         u'run.js content', 'application/javascript',
    128         self._content_provider.GetContentAndType('run.js').Get())
    129     self._assertContent(
    130         u'site.css content', 'text/css',
    131         self._content_provider.GetContentAndType('site.css').Get())
    132 
    133   def testTemplate(self):
    134     self._assertTemplateContent(u'storage.html content', 'storage.html', '0')
    135     self._test_file_system.IncrementStat('storage.html')
    136     self._assertTemplateContent(u'storage.html content', 'storage.html', '1')
    137 
    138   def testImage(self):
    139     self._assertContent(
    140         'img.png content', 'image/png',
    141         self._content_provider.GetContentAndType('img.png').Get())
    142 
    143   def testZipTopLevel(self):
    144     zip_content_provider = self._CreateContentProvider(supports_zip=True)
    145     content_and_type = zip_content_provider.GetContentAndType('dir.zip').Get()
    146     zipfile = ZipFile(StringIO(content_and_type.content))
    147     content_and_type.content = zipfile.namelist()
    148     self._assertContent(
    149         ['dir/a.txt', 'dir/b.txt', 'dir/c/d.txt'], 'application/zip',
    150         content_and_type)
    151 
    152   def testZip2ndLevel(self):
    153     zip_content_provider = self._CreateContentProvider(supports_zip=True)
    154     content_and_type = zip_content_provider.GetContentAndType(
    155         'dir2/dir3.zip').Get()
    156     zipfile = ZipFile(StringIO(content_and_type.content))
    157     content_and_type.content = zipfile.namelist()
    158     self._assertContent(
    159         ['dir3/a.txt', 'dir3/b.txt', 'dir3/c/d.txt'], 'application/zip',
    160         content_and_type)
    161 
    162   def testCanonicalZipPaths(self):
    163     # Without supports_zip the path is canonicalized as a file.
    164     self.assertEqual(
    165         'dir.txt',
    166         self._content_provider.GetCanonicalPath('dir.zip'))
    167     self.assertEqual(
    168         'dir.txt',
    169         self._content_provider.GetCanonicalPath('diR.zip'))
    170     # With supports_zip the path is canonicalized as the zip file which
    171     # corresponds to the canonical directory.
    172     zip_content_provider = self._CreateContentProvider(supports_zip=True)
    173     self.assertEqual(
    174         'dir.zip',
    175         zip_content_provider.GetCanonicalPath('dir.zip'))
    176     self.assertEqual(
    177         'dir.zip',
    178         zip_content_provider.GetCanonicalPath('diR.zip'))
    179 
    180   def testMarkdown(self):
    181     expected_content = '\n'.join(text[1] for text in _MARKDOWN_CONTENT)
    182     self._assertMarkdownContent(expected_content, 'markdown', '0')
    183     self._test_file_system.IncrementStat('markdown.md')
    184     self._assertMarkdownContent(expected_content, 'markdown', '1')
    185 
    186   def testNotFound(self):
    187     self.assertRaises(
    188         FileNotFoundError,
    189         self._content_provider.GetContentAndType('oops').Get)
    190 
    191   def testIndexRedirect(self):
    192     self._assertTemplateContent(u'index.html content', '', '0')
    193     self._assertTemplateContent(u'index.html content 1', 'dir4', '0')
    194     self._assertTemplateContent(u'dir5.html content', 'dir5', '0')
    195     self._assertMarkdownContent(
    196         '\n'.join(text[1] for text in _MARKDOWN_CONTENT),
    197         'dir7',
    198         '0')
    199     self._assertContent(
    200         'noextension content', 'text/plain',
    201         self._content_provider.GetContentAndType('noextension').Get())
    202     self.assertRaises(
    203         FileNotFoundError,
    204         self._content_provider.GetContentAndType('dir6').Get)
    205 
    206   def testRefresh(self):
    207     # Not entirely sure what to test here, but get some code coverage.
    208     self._content_provider.Refresh().Get()
    209 
    210 
    211 if __name__ == '__main__':
    212   unittest.main()
    213