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 import json
      7 import unittest
      8 
      9 from compiled_file_system import CompiledFileSystem
     10 from object_store_creator import ObjectStoreCreator
     11 from redirector import Redirector
     12 from test_file_system import TestFileSystem
     13 from third_party.json_schema_compiler.json_parse import Parse
     14 
     15 HOST = 'http://localhost/'
     16 
     17 file_system = TestFileSystem({
     18   'redirects.json': json.dumps({
     19     'foo/...': 'apps/...',
     20     '': '/index.html',
     21     'home': 'index.html',
     22     'index.html': 'http://something.absolute.com/'
     23   }),
     24   'apps': {
     25     'redirects.json': json.dumps({
     26       '': '../index.html',
     27       'index.html': 'about_apps.html',
     28       'foo.html': '/bar.html',
     29     })
     30   },
     31   'extensions': {
     32     'redirects.json': json.dumps({
     33       'manifest': 'manifest.html',
     34       'tabs': 'tabs.html',
     35       'dev/...': '...',
     36       'a/very/long/dir/chain/...': 'short/...',
     37       '_short/...': 'another/long/chain/...',
     38       'r1/...': 'r2/r1/...',
     39       'r2/r1/...': 'r3/...',
     40       'r3/...': 'r4/...',
     41       'r5/...': 'r6/...',
     42       'nofile1/...': 'nofile2/...',
     43       'noredirects1/...': 'noredirects2/...'
     44     }),
     45     'manifest': {
     46       'redirects.json': json.dumps({
     47         '': '../manifest.html',
     48         'more-info': 'http://lmgtfy.com'
     49       }),
     50     },
     51     'stable': {
     52         'redirects.json': json.dumps({
     53             'tabs': 'tabs.html'
     54         }),
     55         'manifest': {
     56           'redirects.json': json.dumps({
     57             'storage': 'storage.html'
     58           })
     59         },
     60     },
     61     'dev': {
     62       'redirects.json': json.dumps({
     63         'tabs': 'tabs.html',
     64         'manifest': 'manifest.html'
     65       }),
     66       'manifest': {
     67         'redirects.json': json.dumps({
     68           'storage': 'storage.html'
     69         })
     70       }
     71     },
     72     'r4': {
     73       'redirects.json': json.dumps({
     74         'manifest': 'manifest.html'
     75       })
     76     },
     77     'r6': {
     78       'redirects.json': json.dumps({
     79         '...': 'directory/...'
     80       }),
     81       'directory': {
     82         'redirects.json': json.dumps({
     83           'manifest': 'manifest.html'
     84         }),
     85         'manifest': 'manifest.html'
     86       }
     87     },
     88     'short': {
     89       'redirects.json': json.dumps({
     90         'index': 'index.html'
     91       })
     92     },
     93     'another': {
     94       'long': {
     95         'chain': {
     96           'redirects.json': json.dumps({
     97             'index': 'index.html'
     98           })
     99         }
    100       }
    101     },
    102     'nofile': {
    103       'redirects.json': json.dumps({
    104       })
    105     }
    106   },
    107   'priority': {
    108     'redirects.json': json.dumps({
    109       'directory/...': 'GOOD/...'
    110     }),
    111     'directory': {
    112       'redirects.json': json.dumps({
    113         '...': '../BAD/...'
    114       }),
    115     }
    116   },
    117   'relative_directory': {
    118     'redirects.json': json.dumps({
    119       '...': '../...'
    120     })
    121   },
    122   'infinite_redirect': {
    123     'redirects.json': json.dumps({
    124       '...': 'loop/...'
    125     }),
    126     'loop': {
    127       'redirects.json': json.dumps({
    128         '...': './...'
    129       })
    130     }
    131   },
    132   'parent_redirect': {
    133     'redirects.json': json.dumps({
    134       'a/...': 'b/...'
    135     })
    136   }
    137 })
    138 
    139 class RedirectorTest(unittest.TestCase):
    140   def setUp(self):
    141     self._redirector = Redirector(
    142         CompiledFileSystem.Factory(ObjectStoreCreator.ForTest()),
    143         file_system)
    144 
    145   def testExternalRedirection(self):
    146     self.assertEqual(
    147         'http://something.absolute.com/',
    148         self._redirector.Redirect(HOST, 'index.html'))
    149     self.assertEqual(
    150         'http://lmgtfy.com',
    151         self._redirector.Redirect(HOST, 'extensions/manifest/more-info'))
    152 
    153   def testAbsoluteRedirection(self):
    154     self.assertEqual(
    155         '/index.html', self._redirector.Redirect(HOST, ''))
    156     self.assertEqual(
    157         '/bar.html', self._redirector.Redirect(HOST, 'apps/foo.html'))
    158 
    159   def testRelativeRedirection(self):
    160     self.assertEqual(
    161         'apps/about_apps.html',
    162         self._redirector.Redirect(HOST, 'apps/index.html'))
    163     self.assertEqual(
    164         'extensions/manifest.html',
    165         self._redirector.Redirect(HOST, 'extensions/manifest/'))
    166     self.assertEqual(
    167         'extensions/manifest.html',
    168         self._redirector.Redirect(HOST, 'extensions/manifest'))
    169     self.assertEqual(
    170         'index.html', self._redirector.Redirect(HOST, 'apps/'))
    171     self.assertEqual(
    172         'index.html', self._redirector.Redirect(HOST, 'home'))
    173 
    174   def testNotFound(self):
    175     self.assertEqual(
    176         None, self._redirector.Redirect(HOST, 'not/a/real/path'))
    177     self.assertEqual(
    178         None, self._redirector.Redirect(HOST, 'public/apps/okay.html'))
    179 
    180   def testOldHosts(self):
    181     self.assertEqual(
    182         'https://developer.chrome.com/',
    183         self._redirector.Redirect('http://code.google.com', ''))
    184     self.assertEqual(
    185         'https://developer.chrome.com/',
    186         self._redirector.Redirect('https://code.google.com', ''))
    187 
    188   def testRefresh(self):
    189     self._redirector.Refresh().Get()
    190 
    191     expected_paths = set([
    192       'redirects.json',
    193       'apps/redirects.json',
    194       'extensions/redirects.json',
    195       'extensions/manifest/redirects.json'
    196     ])
    197 
    198     for path in expected_paths:
    199       self.assertEqual(
    200           Parse(file_system.ReadSingle(path).Get()),
    201           # Access the cache's object store to see what files were hit during
    202           # the cron run. Returns strings parsed as JSON.
    203           # TODO(jshumway): Make a non hack version of this check.
    204           self._redirector._cache._file_object_store.Get(
    205               path).Get().cache_data)
    206 
    207   def testDirectoryRedirection(self):
    208     # Simple redirect.
    209     self.assertEqual(
    210       'extensions/manifest.html',
    211       self._redirector.Redirect(HOST, 'extensions/dev/manifest'))
    212 
    213     # Multiple hops with one file.
    214     self.assertEqual(
    215       'extensions/r4/manifest.html',
    216       self._redirector.Redirect(HOST, 'extensions/r1/manifest'))
    217 
    218     # Multiple hops w/ multiple redirection files.
    219     self.assertEqual(
    220       'extensions/r6/directory/manifest.html',
    221       self._redirector.Redirect(HOST, 'extensions/r5/manifest'))
    222 
    223     # Redirection from root directory redirector.
    224     self.assertEqual(
    225       'apps/about_apps.html',
    226       self._redirector.Redirect(HOST, 'foo/index.html'))
    227 
    228     # Short to long.
    229     self.assertEqual(
    230       'extensions/short/index.html',
    231       self._redirector.Redirect(HOST, 'extensions/a/very/long/dir/chain/index'))
    232 
    233     # Long to short.
    234     self.assertEqual(
    235       'extensions/another/long/chain/index.html',
    236       self._redirector.Redirect(HOST, 'extensions/_short/index'))
    237 
    238     # Directory redirection without a redirects.json in final directory.
    239     self.assertEqual(
    240       'extensions/noredirects2/file',
    241       self._redirector.Redirect(HOST, 'extensions/noredirects1/file'))
    242 
    243     # Directory redirection with redirects.json without rule for the filename.
    244     self.assertEqual(
    245       'extensions/nofile2/file',
    246       self._redirector.Redirect(HOST, 'extensions/nofile1/file'))
    247 
    248     # Relative directory path.
    249     self.assertEqual(
    250       'index.html',
    251       self._redirector.Redirect(HOST, 'relative_directory/home'))
    252 
    253     # Shallower directory redirects have priority.
    254     self.assertEqual(
    255       'priority/GOOD/index',
    256       self._redirector.Redirect(HOST, 'priority/directory/index'))
    257 
    258     # Don't infinitely redirect.
    259     self.assertEqual('infinite_redirect/loop/index',
    260       self._redirector.Redirect(HOST, 'infinite_redirect/index'))
    261 
    262     # If a parent directory is redirected, redirect children properly.
    263     self.assertEqual('parent_redirect/b/c/index',
    264       self._redirector.Redirect(HOST, 'parent_redirect/a/c/index'))
    265 
    266 
    267 if __name__ == '__main__':
    268   unittest.main()
    269