1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#!/usr/bin/env python 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# found in the LICENSE file. 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import posixpath 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import unittest 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)from extensions_paths import PUBLIC_TEMPLATES, SERVER2 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from local_file_system import LocalFileSystem 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)from test_file_system import TestFileSystem 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from object_store_creator import ObjectStoreCreator 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochfrom path_canonicalizer import PathCanonicalizer 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from special_paths import SITE_VERIFICATION_FILE 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class PathCanonicalizerTest(unittest.TestCase): 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def setUp(self): 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._path_canonicalizer = PathCanonicalizer( 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LocalFileSystem.Create(PUBLIC_TEMPLATES), 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ObjectStoreCreator.ForTest(), 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ('.html', '.md')) 23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def testSpecifyCorrectly(self): 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('extensions/browserAction') 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('extensions/storage') 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('extensions/blah') 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('extensions/index') 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('extensions/whats_new') 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('apps/storage') 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('apps/bluetooth') 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('apps/blah') 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('apps/tags/webview') 34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def testSpecifyIncorrectly(self): 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'extensions/browserAction', 'apps/browserAction') 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'extensions/browserAction', 'apps/extensions/browserAction') 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/bluetooth', 'extensions/bluetooth') 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/bluetooth', 'extensions/apps/bluetooth') 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'extensions/index', 'apps/index') 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'extensions/browserAction', 'static/browserAction') 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/tags/webview', 'apps/webview') 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/tags/webview', 'extensions/webview') 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/tags/webview', 'extensions/tags/webview') 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # These are a little trickier because storage.html is in both directories. 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # They must canonicalize to the closest match. 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'extensions/storage', 'extensions/apps/storage') 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/storage', 'apps/extensions/storage') 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def testUnspecified(self): 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'extensions/browserAction', 'browserAction') 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/bluetooth', 'bluetooth') 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Default happens to be apps because it's first alphabetically. 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirectWithDefaultExtensions( 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'apps/storage', 'storage') 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch # Nonexistent APIs should be left alone. 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch self._AssertIdentity('blah.html') 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def testDirectories(self): 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Directories can be canonicalized too! 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('apps/') 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('apps/tags/') 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('extensions/') 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # No trailing slash should be treated as files not directories, at least 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # at least according to PathCanonicalizer. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('extensions/apps', 'apps') 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('extensions', 'extensions') 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Just as tolerant of spelling mistakes. 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('apps/', 'Apps/') 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('apps/tags/', 'Apps/TAGS/') 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('extensions/', 'Extensions/') 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Find directories in the correct place. 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('apps/tags/', 'tags/') 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('apps/tags/', 'extensions/tags/') 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def testSpellingErrors(self): 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for spelme in ('browseraction', 'browseraction.htm', 'BrowserAction', 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'BrowserAction.html', 'browseraction.html', 'Browseraction', 93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'browser-action', 'Browser.action.html', 'browser_action', 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'browser-action.html', 'Browser_Action.html'): 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('extensions/browserAction', spelme) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('extensions/browserAction', 'extensions/%s' % spelme) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('extensions/browserAction', 'apps/%s' % spelme) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def testNonDefaultExtensions(self): 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # The only example currently of a file with a non-default extension is 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # the redirects.json file. That shouldn't have its extension stripped since 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # it's not in the default extensions. 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity('redirects.json') 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('redirects.json', 'redirects') 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('redirects.json', 'redirects.html') 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('redirects.json', 'redirects.js') 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect('redirects.json', 'redirects.md') 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def testSiteVerificationFile(self): 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # The site verification file should not redirect. 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertIdentity(SITE_VERIFICATION_FILE) 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect(SITE_VERIFICATION_FILE, 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) posixpath.splitext(SITE_VERIFICATION_FILE)[0]) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def testDotSeparated(self): 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self._AssertIdentity('extensions/devtools_inspectedWindow') 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self._AssertRedirect('extensions/devtools_inspectedWindow', 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 'extensions/devtools.inspectedWindow') 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) def testUnderscoreSeparated(self): 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) file_system = TestFileSystem({ 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 'pepper_dev': { 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 'c': { 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 'index.html': '' 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }, 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 'pepper_stable': { 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 'c': { 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 'index.html': '' 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) }) 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) self._path_canonicalizer = PathCanonicalizer( 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) file_system, 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ObjectStoreCreator.ForTest(), 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ('.html', '.md')) 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) self._AssertIdentity('pepper_stable/c/index') 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) self._AssertRedirect('pepper_stable/c/index', 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 'pepper_stable/c/index.html') 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def _AssertIdentity(self, path): 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect(path, path) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _AssertRedirect(self, to, from_): 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.assertEqual(to, self._path_canonicalizer.Canonicalize(from_)) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _AssertRedirectWithDefaultExtensions(self, to, from_): 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for ext in ('', '.html', '.md'): 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._AssertRedirect( 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) to, self._path_canonicalizer.Canonicalize(from_ + ext)) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)if __name__ == '__main__': 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unittest.main() 155