Enable Enterprise enrollment on desktop builds.
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / patch_servlet_test.py
blob11d028958c354aaaab280d4f52f974478424b759
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.
6 from HTMLParser import HTMLParser
7 import unittest
9 from fake_fetchers import ConfigureFakeFetchers
10 from github_file_system_provider import GithubFileSystemProvider
11 from host_file_system_provider import HostFileSystemProvider
12 from patch_servlet import PatchServlet
13 from render_servlet import RenderServlet
14 from server_instance import ServerInstance
15 from servlet import Request
16 from test_branch_utility import TestBranchUtility
17 from test_util import DisableLogging
21 _ALLOWED_HOST = 'https://chrome-apps-doc.appspot.com'
24 def _CheckURLsArePatched(content, patch_servlet_path):
25 errors = []
26 class LinkChecker(HTMLParser):
27 def handle_starttag(self, tag, attrs):
28 if tag != 'a':
29 return
30 tag_description = '<a %s .../>' % ' '.join('%s="%s"' % (key, val)
31 for key, val in attrs)
32 attrs = dict(attrs)
33 if ('href' in attrs and
34 attrs['href'].startswith('/') and
35 not attrs['href'].startswith('/%s/' % patch_servlet_path)):
36 errors.append('%s has an unqualified href' % tag_description)
37 LinkChecker().feed(content)
38 return errors
41 class _RenderServletDelegate(RenderServlet.Delegate):
42 def CreateServerInstance(self):
43 return ServerInstance.ForLocal()
45 class _PatchServletDelegate(RenderServlet.Delegate):
46 def CreateBranchUtility(self, object_store_creator):
47 return TestBranchUtility.CreateWithCannedData()
49 def CreateHostFileSystemProvider(self, object_store_creator, **optargs):
50 return HostFileSystemProvider.ForLocal(object_store_creator, **optargs)
52 def CreateGithubFileSystemProvider(self, object_store_creator):
53 return GithubFileSystemProvider.ForEmpty()
56 class PatchServletTest(unittest.TestCase):
57 def setUp(self):
58 ConfigureFakeFetchers()
60 def _RenderWithPatch(self, path, issue):
61 path_with_issue = '%s/%s' % (issue, path)
62 return PatchServlet(Request.ForTest(path_with_issue, host=_ALLOWED_HOST),
63 _PatchServletDelegate()).Get()
65 def _RenderWithoutPatch(self, path):
66 return RenderServlet(Request.ForTest(path, host=_ALLOWED_HOST),
67 _RenderServletDelegate()).Get()
69 def _RenderAndCheck(self, path, issue, expected_equal):
70 '''Renders |path| with |issue| patched in and asserts that the result is
71 the same as |expected_equal| modulo any links that get rewritten to
72 "_patch/issue".
73 '''
74 patched_response = self._RenderWithPatch(path, issue)
75 unpatched_response = self._RenderWithoutPatch(path)
76 for header in ('Cache-Control', 'ETag'):
77 patched_response.headers.pop(header, None)
78 unpatched_response.headers.pop(header, None)
79 unpatched_content = unpatched_response.content.ToString()
81 # Check that all links in the patched content are qualified with
82 # the patch URL, then strip them out for checking (in)equality.
83 patched_content = patched_response.content.ToString()
84 patch_servlet_path = '_patch/%s' % issue
85 errors = _CheckURLsArePatched(patched_content, patch_servlet_path)
86 self.assertFalse(errors,
87 '%s\nFound errors:\n * %s' % (patched_content, '\n * '.join(errors)))
88 patched_content = patched_content.replace('/%s' % patch_servlet_path, '')
90 self.assertEqual(patched_response.status, unpatched_response.status)
91 self.assertEqual(patched_response.headers, unpatched_response.headers)
92 if expected_equal:
93 self.assertEqual(patched_content, unpatched_content)
94 else:
95 self.assertNotEqual(patched_content, unpatched_content)
97 def _RenderAndAssertEqual(self, path, issue):
98 self._RenderAndCheck(path, issue, True)
100 def _RenderAndAssertNotEqual(self, path, issue):
101 self._RenderAndCheck(path, issue, False)
103 @DisableLogging('warning')
104 def _AssertNotFound(self, path, issue):
105 response = self._RenderWithPatch(path, issue)
106 self.assertEqual(response.status, 404,
107 'Path %s with issue %s should have been removed for %s.' % (
108 path, issue, response))
110 def _AssertOk(self, path, issue):
111 response = self._RenderWithPatch(path, issue)
112 self.assertEqual(response.status, 200,
113 'Failed to render path %s with issue %s.' % (path, issue))
114 self.assertTrue(len(response.content.ToString()) > 0,
115 'Rendered result for path %s with issue %s should not be empty.' %
116 (path, issue))
118 def _AssertRedirect(self, path, issue, redirect_path):
119 response = self._RenderWithPatch(path, issue)
120 self.assertEqual(302, response.status)
121 self.assertEqual('/_patch/%s/%s' % (issue, redirect_path),
122 response.headers['Location'])
124 def testRender(self):
125 # '_patch' is not included in paths below because it's stripped by Handler.
126 issue = '14096030'
128 # TODO(kalman): Test with chrome_sidenav.json once the sidenav logic has
129 # stabilised.
131 # extensions/runtime.html is removed in the patch, should redirect to the
132 # apps version.
133 self._AssertRedirect('extensions/runtime', issue, 'apps/runtime')
135 # apps/runtime.html is not removed.
136 self._RenderAndAssertEqual('apps/runtime', issue)
138 # test_foo.html is added in the patch.
139 self._AssertOk('extensions/test_foo', issue)
141 # Invalid issue number results in a 404.
142 self._AssertNotFound('extensions/index', '11111')
144 def testXssRedirect(self):
145 def is_redirect(from_host, from_path, to_url):
146 response = PatchServlet(Request.ForTest(from_path, host=from_host),
147 _PatchServletDelegate()).Get()
148 redirect_url, _ = response.GetRedirect()
149 if redirect_url is None:
150 return (False, '%s/%s did not cause a redirect' % (
151 from_host, from_path))
152 if redirect_url != to_url:
153 return (False, '%s/%s redirected to %s not %s' % (
154 from_host, from_path, redirect_url, to_url))
155 return (True, '%s/%s redirected to %s' % (
156 from_host, from_path, redirect_url))
157 self.assertTrue(*is_redirect('http://developer.chrome.com', '12345',
158 '%s/_patch/12345' % _ALLOWED_HOST))
159 self.assertTrue(*is_redirect('http://developers.google.com', '12345',
160 '%s/_patch/12345' % _ALLOWED_HOST))
161 self.assertFalse(*is_redirect('http://chrome-apps-doc.appspot.com', '12345',
162 None))
163 self.assertFalse(*is_redirect('http://some-other-app.appspot.com', '12345',
164 None))
166 if __name__ == '__main__':
167 unittest.main()