test_files.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # coding: utf-8
  2. """Test the /files/ handler."""
  3. import io
  4. import os
  5. from unicodedata import normalize
  6. pjoin = os.path.join
  7. import requests
  8. import json
  9. from nbformat import write
  10. from nbformat.v4 import (new_notebook,
  11. new_markdown_cell, new_code_cell,
  12. new_output)
  13. from notebook.utils import url_path_join
  14. from .launchnotebook import NotebookTestBase
  15. from ipython_genutils import py3compat
  16. class FilesTest(NotebookTestBase):
  17. def test_hidden_files(self):
  18. not_hidden = [
  19. u'å b',
  20. u'å b/ç. d',
  21. ]
  22. hidden = [
  23. u'.å b',
  24. u'å b/.ç d',
  25. ]
  26. dirs = not_hidden + hidden
  27. nbdir = self.notebook_dir
  28. for d in dirs:
  29. path = pjoin(nbdir, d.replace('/', os.sep))
  30. if not os.path.exists(path):
  31. os.mkdir(path)
  32. with open(pjoin(path, 'foo'), 'w') as f:
  33. f.write('foo')
  34. with open(pjoin(path, '.foo'), 'w') as f:
  35. f.write('.foo')
  36. for d in not_hidden:
  37. path = pjoin(nbdir, d.replace('/', os.sep))
  38. r = self.request('GET', url_path_join('files', d, 'foo'))
  39. r.raise_for_status()
  40. self.assertEqual(r.text, 'foo')
  41. r = self.request('GET', url_path_join('files', d, '.foo'))
  42. self.assertEqual(r.status_code, 404)
  43. for d in hidden:
  44. path = pjoin(nbdir, d.replace('/', os.sep))
  45. for foo in ('foo', '.foo'):
  46. r = self.request('GET', url_path_join('files', d, foo))
  47. self.assertEqual(r.status_code, 404)
  48. self.notebook.contents_manager.allow_hidden = True
  49. try:
  50. for d in not_hidden:
  51. path = pjoin(nbdir, d.replace('/', os.sep))
  52. r = self.request('GET', url_path_join('files', d, 'foo'))
  53. r.raise_for_status()
  54. self.assertEqual(r.text, 'foo')
  55. r = self.request('GET', url_path_join('files', d, '.foo'))
  56. r.raise_for_status()
  57. self.assertEqual(r.text, '.foo')
  58. for d in hidden:
  59. path = pjoin(nbdir, d.replace('/', os.sep))
  60. for foo in ('foo', '.foo'):
  61. r = self.request('GET', url_path_join('files', d, foo))
  62. r.raise_for_status()
  63. self.assertEqual(r.text, foo)
  64. finally:
  65. self.notebook.contents_manager.allow_hidden = False
  66. def test_contents_manager(self):
  67. "make sure ContentsManager returns right files (ipynb, bin, txt)."
  68. nbdir = self.notebook_dir
  69. nb = new_notebook(
  70. cells=[
  71. new_markdown_cell(u'Created by test ³'),
  72. new_code_cell("print(2*6)", outputs=[
  73. new_output("stream", text="12"),
  74. ])
  75. ]
  76. )
  77. with io.open(pjoin(nbdir, 'testnb.ipynb'), 'w',
  78. encoding='utf-8') as f:
  79. write(nb, f, version=4)
  80. with io.open(pjoin(nbdir, 'test.bin'), 'wb') as f:
  81. f.write(b'\xff' + os.urandom(5))
  82. f.close()
  83. with io.open(pjoin(nbdir, 'test.txt'), 'w') as f:
  84. f.write(u'foobar')
  85. f.close()
  86. r = self.request('GET', 'files/testnb.ipynb')
  87. self.assertEqual(r.status_code, 200)
  88. self.assertIn('print(2*6)', r.text)
  89. json.loads(r.text)
  90. r = self.request('GET', 'files/test.bin')
  91. self.assertEqual(r.status_code, 200)
  92. self.assertEqual(r.headers['content-type'], 'application/octet-stream')
  93. self.assertEqual(r.content[:1], b'\xff')
  94. self.assertEqual(len(r.content), 6)
  95. r = self.request('GET', 'files/test.txt')
  96. self.assertEqual(r.status_code, 200)
  97. self.assertEqual(r.headers['content-type'], 'text/plain; charset=UTF-8')
  98. self.assertEqual(r.text, 'foobar')
  99. def test_download(self):
  100. nbdir = self.notebook_dir
  101. text = 'hello'
  102. with open(pjoin(nbdir, 'test.txt'), 'w') as f:
  103. f.write(text)
  104. r = self.request('GET', 'files/test.txt')
  105. disposition = r.headers.get('Content-Disposition', '')
  106. self.assertNotIn('attachment', disposition)
  107. r = self.request('GET', 'files/test.txt?download=1')
  108. disposition = r.headers.get('Content-Disposition', '')
  109. self.assertIn('attachment', disposition)
  110. self.assertIn("filename*=utf-8''test.txt", disposition)
  111. def test_view_html(self):
  112. nbdir = self.notebook_dir
  113. html = '<div>Test test</div>'
  114. with open(pjoin(nbdir, 'test.html'), 'w') as f:
  115. f.write(html)
  116. r = self.request('GET', 'view/test.html')
  117. self.assertEqual(r.status_code, 200)
  118. def test_old_files_redirect(self):
  119. """pre-2.0 'files/' prefixed links are properly redirected"""
  120. nbdir = self.notebook_dir
  121. os.mkdir(pjoin(nbdir, 'files'))
  122. os.makedirs(pjoin(nbdir, 'sub', 'files'))
  123. for prefix in ('', 'sub'):
  124. with open(pjoin(nbdir, prefix, 'files', 'f1.txt'), 'w') as f:
  125. f.write(prefix + '/files/f1')
  126. with open(pjoin(nbdir, prefix, 'files', 'f2.txt'), 'w') as f:
  127. f.write(prefix + '/files/f2')
  128. with open(pjoin(nbdir, prefix, 'f2.txt'), 'w') as f:
  129. f.write(prefix + '/f2')
  130. with open(pjoin(nbdir, prefix, 'f3.txt'), 'w') as f:
  131. f.write(prefix + '/f3')
  132. url = url_path_join('notebooks', prefix, 'files', 'f1.txt')
  133. r = self.request('GET', url)
  134. self.assertEqual(r.status_code, 200)
  135. self.assertEqual(r.text, prefix + '/files/f1')
  136. url = url_path_join('notebooks', prefix, 'files', 'f2.txt')
  137. r = self.request('GET', url)
  138. self.assertEqual(r.status_code, 200)
  139. self.assertEqual(r.text, prefix + '/files/f2')
  140. url = url_path_join('notebooks', prefix, 'files', 'f3.txt')
  141. r = self.request('GET', url)
  142. self.assertEqual(r.status_code, 200)
  143. self.assertEqual(r.text, prefix + '/f3')