1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#!/usr/bin/env python 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch# found in the LICENSE file. 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochimport unittest 7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochfrom file_system import FileNotFoundError 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochfrom link_error_detector import LinkErrorDetector 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochfrom servlet import Response 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochfrom test_file_system import TestFileSystem 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochfile_system = TestFileSystem({ 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'docs': { 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'templates': { 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'public': { 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'apps': { 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch '404.html': '404', 19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'index.html': ''' 20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <h1 id="actual-top">Hello</h1> 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="#top">world</p> 22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="#actual-top">!</a> 23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="broken.json"></a> 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="crx.html"></a> 25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ''', 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'crx.html': ''' 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="index.html#actual-top">back</a> 28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="broken.html"></a> 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="devtools.events.html">do to underscore translation</a> 30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ''', 31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'devtools_events.html': ''' 32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href=" http://www.google.com/">leading space in href</a> 33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href=" index.html">home</a> 34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="index.html#invalid"></a> 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="fake.html#invalid"></a> 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ''', 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'unreachable.html': ''' 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <p>so lonely</p> 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="#aoesu"></a> 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch <a href="invalid.html"></a> 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ''', 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'devtools_disconnected.html': '' 43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch }, 46ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'static': {}, 47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'examples': {}, 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}) 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass LinkErrorDetectorTest(unittest.TestCase): 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def _Render(self, path): 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch try: 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return Response( 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) content=file_system.ReadSingle('docs/templates/public/' + path).Get(), 56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch status=200) 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch except FileNotFoundError: 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return Response(status=404) 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def testGetBrokenLinks(self): 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch expected_broken_links = set([ 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) (404, 'apps/crx.html', 'apps/broken.html', 'target page not found'), 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) (404, 'apps/index.html', 'apps/broken.json', 'target page not found'), 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) (404, 'apps/unreachable.html', 'apps/invalid.html', 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 'target page not found'), 66558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch (404, 'apps/devtools_events.html', 'apps/fake.html#invalid', 67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 'target page not found'), 68558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch (200, 'apps/devtools_events.html', 'apps/index.html#invalid', 69558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 'target anchor not found'), 70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch (200, 'apps/unreachable.html', '#aoesu', 'target anchor not found')]) 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch link_error_detector = LinkErrorDetector( 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_system, self._Render, 'templates/public/', ('apps/index.html')) 74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch broken_links = link_error_detector.GetBrokenLinks() 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch self.assertEqual(expected_broken_links, set(broken_links)) 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch def testGetOrphanedPages(self): 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch expected_orphaned_pages = set([ 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'apps/unreachable.html', 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 'apps/devtools_disconnected.html']) 82ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch link_error_detector = LinkErrorDetector( 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_system, self._Render, 'templates/public/', ('apps/crx.html',)) 85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch orphaned_pages = link_error_detector.GetOrphanedPages() 86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch self.assertEqual(expected_orphaned_pages, set(orphaned_pages)) 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochif __name__ == '__main__': 90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch unittest.main() 91