##// END OF EJS Templates
MAINT: Remove unused import.
Scott Sanderson -
Show More
@@ -1,498 +1,497
1 # coding: utf-8
1 # coding: utf-8
2 """Tests for the notebook manager."""
2 """Tests for the notebook manager."""
3 from __future__ import print_function
3 from __future__ import print_function
4
4
5 import os
5 import os
6 import sys
6 import sys
7 import time
7 import time
8 from contextlib import contextmanager
8 from contextlib import contextmanager
9
9
10 from nose import SkipTest
10 from nose import SkipTest
11 from tornado.web import HTTPError
11 from tornado.web import HTTPError
12 from unittest import TestCase
12 from unittest import TestCase
13 from tempfile import NamedTemporaryFile
13 from tempfile import NamedTemporaryFile
14
14
15 from IPython.nbformat import v4 as nbformat
15 from IPython.nbformat import v4 as nbformat
16
16
17 from IPython.utils.tempdir import TemporaryDirectory
17 from IPython.utils.tempdir import TemporaryDirectory
18 from IPython.utils.traitlets import TraitError
18 from IPython.utils.traitlets import TraitError
19 from IPython.html.utils import url_path_join
20 from IPython.testing import decorators as dec
19 from IPython.testing import decorators as dec
21
20
22 from ..filemanager import FileContentsManager
21 from ..filemanager import FileContentsManager
23
22
24
23
25 def _make_dir(contents_manager, api_path):
24 def _make_dir(contents_manager, api_path):
26 """
25 """
27 Make a directory.
26 Make a directory.
28 """
27 """
29 os_path = contents_manager._get_os_path(api_path)
28 os_path = contents_manager._get_os_path(api_path)
30 try:
29 try:
31 os.makedirs(os_path)
30 os.makedirs(os_path)
32 except OSError:
31 except OSError:
33 print("Directory already exists: %r" % os_path)
32 print("Directory already exists: %r" % os_path)
34
33
35
34
36 class TestFileContentsManager(TestCase):
35 class TestFileContentsManager(TestCase):
37
36
38 @contextmanager
37 @contextmanager
39 def assertRaisesHTTPError(self, status, msg=None):
38 def assertRaisesHTTPError(self, status, msg=None):
40 msg = msg or "Should have raised HTTPError(%i)" % status
39 msg = msg or "Should have raised HTTPError(%i)" % status
41 try:
40 try:
42 yield
41 yield
43 except HTTPError as e:
42 except HTTPError as e:
44 self.assertEqual(e.status_code, status)
43 self.assertEqual(e.status_code, status)
45 else:
44 else:
46 self.fail(msg)
45 self.fail(msg)
47
46
48 def symlink(self, contents_manager, src, dst):
47 def symlink(self, contents_manager, src, dst):
49 """Make a symlink to src from dst
48 """Make a symlink to src from dst
50
49
51 src and dst are api_paths
50 src and dst are api_paths
52 """
51 """
53 src_os_path = contents_manager._get_os_path(src)
52 src_os_path = contents_manager._get_os_path(src)
54 dst_os_path = contents_manager._get_os_path(dst)
53 dst_os_path = contents_manager._get_os_path(dst)
55 print(src_os_path, dst_os_path, os.path.isfile(src_os_path))
54 print(src_os_path, dst_os_path, os.path.isfile(src_os_path))
56 os.symlink(src_os_path, dst_os_path)
55 os.symlink(src_os_path, dst_os_path)
57
56
58 def test_root_dir(self):
57 def test_root_dir(self):
59 with TemporaryDirectory() as td:
58 with TemporaryDirectory() as td:
60 fm = FileContentsManager(root_dir=td)
59 fm = FileContentsManager(root_dir=td)
61 self.assertEqual(fm.root_dir, td)
60 self.assertEqual(fm.root_dir, td)
62
61
63 def test_missing_root_dir(self):
62 def test_missing_root_dir(self):
64 with TemporaryDirectory() as td:
63 with TemporaryDirectory() as td:
65 root = os.path.join(td, 'notebook', 'dir', 'is', 'missing')
64 root = os.path.join(td, 'notebook', 'dir', 'is', 'missing')
66 self.assertRaises(TraitError, FileContentsManager, root_dir=root)
65 self.assertRaises(TraitError, FileContentsManager, root_dir=root)
67
66
68 def test_invalid_root_dir(self):
67 def test_invalid_root_dir(self):
69 with NamedTemporaryFile() as tf:
68 with NamedTemporaryFile() as tf:
70 self.assertRaises(TraitError, FileContentsManager, root_dir=tf.name)
69 self.assertRaises(TraitError, FileContentsManager, root_dir=tf.name)
71
70
72 def test_get_os_path(self):
71 def test_get_os_path(self):
73 # full filesystem path should be returned with correct operating system
72 # full filesystem path should be returned with correct operating system
74 # separators.
73 # separators.
75 with TemporaryDirectory() as td:
74 with TemporaryDirectory() as td:
76 root = td
75 root = td
77 fm = FileContentsManager(root_dir=root)
76 fm = FileContentsManager(root_dir=root)
78 path = fm._get_os_path('/path/to/notebook/test.ipynb')
77 path = fm._get_os_path('/path/to/notebook/test.ipynb')
79 rel_path_list = '/path/to/notebook/test.ipynb'.split('/')
78 rel_path_list = '/path/to/notebook/test.ipynb'.split('/')
80 fs_path = os.path.join(fm.root_dir, *rel_path_list)
79 fs_path = os.path.join(fm.root_dir, *rel_path_list)
81 self.assertEqual(path, fs_path)
80 self.assertEqual(path, fs_path)
82
81
83 fm = FileContentsManager(root_dir=root)
82 fm = FileContentsManager(root_dir=root)
84 path = fm._get_os_path('test.ipynb')
83 path = fm._get_os_path('test.ipynb')
85 fs_path = os.path.join(fm.root_dir, 'test.ipynb')
84 fs_path = os.path.join(fm.root_dir, 'test.ipynb')
86 self.assertEqual(path, fs_path)
85 self.assertEqual(path, fs_path)
87
86
88 fm = FileContentsManager(root_dir=root)
87 fm = FileContentsManager(root_dir=root)
89 path = fm._get_os_path('////test.ipynb')
88 path = fm._get_os_path('////test.ipynb')
90 fs_path = os.path.join(fm.root_dir, 'test.ipynb')
89 fs_path = os.path.join(fm.root_dir, 'test.ipynb')
91 self.assertEqual(path, fs_path)
90 self.assertEqual(path, fs_path)
92
91
93 def test_checkpoint_subdir(self):
92 def test_checkpoint_subdir(self):
94 subd = u'sub βˆ‚ir'
93 subd = u'sub βˆ‚ir'
95 cp_name = 'test-cp.ipynb'
94 cp_name = 'test-cp.ipynb'
96 with TemporaryDirectory() as td:
95 with TemporaryDirectory() as td:
97 root = td
96 root = td
98 os.mkdir(os.path.join(td, subd))
97 os.mkdir(os.path.join(td, subd))
99 fm = FileContentsManager(root_dir=root)
98 fm = FileContentsManager(root_dir=root)
100 cpm = fm.checkpoints
99 cpm = fm.checkpoints
101 cp_dir = cpm.checkpoint_path(
100 cp_dir = cpm.checkpoint_path(
102 'cp', 'test.ipynb'
101 'cp', 'test.ipynb'
103 )
102 )
104 cp_subdir = cpm.checkpoint_path(
103 cp_subdir = cpm.checkpoint_path(
105 'cp', '/%s/test.ipynb' % subd
104 'cp', '/%s/test.ipynb' % subd
106 )
105 )
107 self.assertNotEqual(cp_dir, cp_subdir)
106 self.assertNotEqual(cp_dir, cp_subdir)
108 self.assertEqual(cp_dir, os.path.join(root, cpm.checkpoint_dir, cp_name))
107 self.assertEqual(cp_dir, os.path.join(root, cpm.checkpoint_dir, cp_name))
109 self.assertEqual(cp_subdir, os.path.join(root, subd, cpm.checkpoint_dir, cp_name))
108 self.assertEqual(cp_subdir, os.path.join(root, subd, cpm.checkpoint_dir, cp_name))
110
109
111 @dec.skip_win32
110 @dec.skip_win32
112 def test_bad_symlink(self):
111 def test_bad_symlink(self):
113 with TemporaryDirectory() as td:
112 with TemporaryDirectory() as td:
114 cm = FileContentsManager(root_dir=td)
113 cm = FileContentsManager(root_dir=td)
115 path = 'test bad symlink'
114 path = 'test bad symlink'
116 _make_dir(cm, path)
115 _make_dir(cm, path)
117
116
118 file_model = cm.new_untitled(path=path, ext='.txt')
117 file_model = cm.new_untitled(path=path, ext='.txt')
119
118
120 # create a broken symlink
119 # create a broken symlink
121 self.symlink(cm, "target", '%s/%s' % (path, 'bad symlink'))
120 self.symlink(cm, "target", '%s/%s' % (path, 'bad symlink'))
122 model = cm.get(path)
121 model = cm.get(path)
123 self.assertEqual(model['content'], [file_model])
122 self.assertEqual(model['content'], [file_model])
124
123
125 @dec.skip_win32
124 @dec.skip_win32
126 def test_good_symlink(self):
125 def test_good_symlink(self):
127 with TemporaryDirectory() as td:
126 with TemporaryDirectory() as td:
128 cm = FileContentsManager(root_dir=td)
127 cm = FileContentsManager(root_dir=td)
129 parent = 'test good symlink'
128 parent = 'test good symlink'
130 name = 'good symlink'
129 name = 'good symlink'
131 path = '{0}/{1}'.format(parent, name)
130 path = '{0}/{1}'.format(parent, name)
132 _make_dir(cm, parent)
131 _make_dir(cm, parent)
133
132
134 file_model = cm.new(path=parent + '/zfoo.txt')
133 file_model = cm.new(path=parent + '/zfoo.txt')
135
134
136 # create a good symlink
135 # create a good symlink
137 self.symlink(cm, file_model['path'], path)
136 self.symlink(cm, file_model['path'], path)
138 symlink_model = cm.get(path, content=False)
137 symlink_model = cm.get(path, content=False)
139 dir_model = cm.get(parent)
138 dir_model = cm.get(parent)
140 self.assertEqual(
139 self.assertEqual(
141 sorted(dir_model['content'], key=lambda x: x['name']),
140 sorted(dir_model['content'], key=lambda x: x['name']),
142 [symlink_model, file_model],
141 [symlink_model, file_model],
143 )
142 )
144
143
145 def test_403(self):
144 def test_403(self):
146 if hasattr(os, 'getuid'):
145 if hasattr(os, 'getuid'):
147 if os.getuid() == 0:
146 if os.getuid() == 0:
148 raise SkipTest("Can't test permissions as root")
147 raise SkipTest("Can't test permissions as root")
149 if sys.platform.startswith('win'):
148 if sys.platform.startswith('win'):
150 raise SkipTest("Can't test permissions on Windows")
149 raise SkipTest("Can't test permissions on Windows")
151
150
152 with TemporaryDirectory() as td:
151 with TemporaryDirectory() as td:
153 cm = FileContentsManager(root_dir=td)
152 cm = FileContentsManager(root_dir=td)
154 model = cm.new_untitled(type='file')
153 model = cm.new_untitled(type='file')
155 os_path = cm._get_os_path(model['path'])
154 os_path = cm._get_os_path(model['path'])
156
155
157 os.chmod(os_path, 0o400)
156 os.chmod(os_path, 0o400)
158 try:
157 try:
159 with cm.open(os_path, 'w') as f:
158 with cm.open(os_path, 'w') as f:
160 f.write(u"don't care")
159 f.write(u"don't care")
161 except HTTPError as e:
160 except HTTPError as e:
162 self.assertEqual(e.status_code, 403)
161 self.assertEqual(e.status_code, 403)
163 else:
162 else:
164 self.fail("Should have raised HTTPError(403)")
163 self.fail("Should have raised HTTPError(403)")
165
164
166 def test_escape_root(self):
165 def test_escape_root(self):
167 with TemporaryDirectory() as td:
166 with TemporaryDirectory() as td:
168 cm = FileContentsManager(root_dir=td)
167 cm = FileContentsManager(root_dir=td)
169 # make foo, bar next to root
168 # make foo, bar next to root
170 with open(os.path.join(cm.root_dir, '..', 'foo'), 'w') as f:
169 with open(os.path.join(cm.root_dir, '..', 'foo'), 'w') as f:
171 f.write('foo')
170 f.write('foo')
172 with open(os.path.join(cm.root_dir, '..', 'bar'), 'w') as f:
171 with open(os.path.join(cm.root_dir, '..', 'bar'), 'w') as f:
173 f.write('bar')
172 f.write('bar')
174
173
175 with self.assertRaisesHTTPError(404):
174 with self.assertRaisesHTTPError(404):
176 cm.get('..')
175 cm.get('..')
177 with self.assertRaisesHTTPError(404):
176 with self.assertRaisesHTTPError(404):
178 cm.get('foo/../../../bar')
177 cm.get('foo/../../../bar')
179 with self.assertRaisesHTTPError(404):
178 with self.assertRaisesHTTPError(404):
180 cm.delete('../foo')
179 cm.delete('../foo')
181 with self.assertRaisesHTTPError(404):
180 with self.assertRaisesHTTPError(404):
182 cm.rename('../foo', '../bar')
181 cm.rename('../foo', '../bar')
183 with self.assertRaisesHTTPError(404):
182 with self.assertRaisesHTTPError(404):
184 cm.save(model={
183 cm.save(model={
185 'type': 'file',
184 'type': 'file',
186 'content': u'',
185 'content': u'',
187 'format': 'text',
186 'format': 'text',
188 }, path='../foo')
187 }, path='../foo')
189
188
190
189
191 class TestContentsManager(TestCase):
190 class TestContentsManager(TestCase):
192
191
193 def setUp(self):
192 def setUp(self):
194 self._temp_dir = TemporaryDirectory()
193 self._temp_dir = TemporaryDirectory()
195 self.td = self._temp_dir.name
194 self.td = self._temp_dir.name
196 self.contents_manager = FileContentsManager(
195 self.contents_manager = FileContentsManager(
197 root_dir=self.td,
196 root_dir=self.td,
198 )
197 )
199
198
200 def tearDown(self):
199 def tearDown(self):
201 self._temp_dir.cleanup()
200 self._temp_dir.cleanup()
202
201
203 def make_dir(self, api_path):
202 def make_dir(self, api_path):
204 """make a subdirectory at api_path
203 """make a subdirectory at api_path
205
204
206 override in subclasses if contents are not on the filesystem.
205 override in subclasses if contents are not on the filesystem.
207 """
206 """
208 _make_dir(self.contents_manager, api_path)
207 _make_dir(self.contents_manager, api_path)
209
208
210 def add_code_cell(self, nb):
209 def add_code_cell(self, nb):
211 output = nbformat.new_output("display_data", {'application/javascript': "alert('hi');"})
210 output = nbformat.new_output("display_data", {'application/javascript': "alert('hi');"})
212 cell = nbformat.new_code_cell("print('hi')", outputs=[output])
211 cell = nbformat.new_code_cell("print('hi')", outputs=[output])
213 nb.cells.append(cell)
212 nb.cells.append(cell)
214
213
215 def new_notebook(self):
214 def new_notebook(self):
216 cm = self.contents_manager
215 cm = self.contents_manager
217 model = cm.new_untitled(type='notebook')
216 model = cm.new_untitled(type='notebook')
218 name = model['name']
217 name = model['name']
219 path = model['path']
218 path = model['path']
220
219
221 full_model = cm.get(path)
220 full_model = cm.get(path)
222 nb = full_model['content']
221 nb = full_model['content']
223 nb['metadata']['counter'] = int(1e6 * time.time())
222 nb['metadata']['counter'] = int(1e6 * time.time())
224 self.add_code_cell(nb)
223 self.add_code_cell(nb)
225
224
226 cm.save(full_model, path)
225 cm.save(full_model, path)
227 return nb, name, path
226 return nb, name, path
228
227
229 def test_new_untitled(self):
228 def test_new_untitled(self):
230 cm = self.contents_manager
229 cm = self.contents_manager
231 # Test in root directory
230 # Test in root directory
232 model = cm.new_untitled(type='notebook')
231 model = cm.new_untitled(type='notebook')
233 assert isinstance(model, dict)
232 assert isinstance(model, dict)
234 self.assertIn('name', model)
233 self.assertIn('name', model)
235 self.assertIn('path', model)
234 self.assertIn('path', model)
236 self.assertIn('type', model)
235 self.assertIn('type', model)
237 self.assertEqual(model['type'], 'notebook')
236 self.assertEqual(model['type'], 'notebook')
238 self.assertEqual(model['name'], 'Untitled.ipynb')
237 self.assertEqual(model['name'], 'Untitled.ipynb')
239 self.assertEqual(model['path'], 'Untitled.ipynb')
238 self.assertEqual(model['path'], 'Untitled.ipynb')
240
239
241 # Test in sub-directory
240 # Test in sub-directory
242 model = cm.new_untitled(type='directory')
241 model = cm.new_untitled(type='directory')
243 assert isinstance(model, dict)
242 assert isinstance(model, dict)
244 self.assertIn('name', model)
243 self.assertIn('name', model)
245 self.assertIn('path', model)
244 self.assertIn('path', model)
246 self.assertIn('type', model)
245 self.assertIn('type', model)
247 self.assertEqual(model['type'], 'directory')
246 self.assertEqual(model['type'], 'directory')
248 self.assertEqual(model['name'], 'Untitled Folder')
247 self.assertEqual(model['name'], 'Untitled Folder')
249 self.assertEqual(model['path'], 'Untitled Folder')
248 self.assertEqual(model['path'], 'Untitled Folder')
250 sub_dir = model['path']
249 sub_dir = model['path']
251
250
252 model = cm.new_untitled(path=sub_dir)
251 model = cm.new_untitled(path=sub_dir)
253 assert isinstance(model, dict)
252 assert isinstance(model, dict)
254 self.assertIn('name', model)
253 self.assertIn('name', model)
255 self.assertIn('path', model)
254 self.assertIn('path', model)
256 self.assertIn('type', model)
255 self.assertIn('type', model)
257 self.assertEqual(model['type'], 'file')
256 self.assertEqual(model['type'], 'file')
258 self.assertEqual(model['name'], 'untitled')
257 self.assertEqual(model['name'], 'untitled')
259 self.assertEqual(model['path'], '%s/untitled' % sub_dir)
258 self.assertEqual(model['path'], '%s/untitled' % sub_dir)
260
259
261 def test_get(self):
260 def test_get(self):
262 cm = self.contents_manager
261 cm = self.contents_manager
263 # Create a notebook
262 # Create a notebook
264 model = cm.new_untitled(type='notebook')
263 model = cm.new_untitled(type='notebook')
265 name = model['name']
264 name = model['name']
266 path = model['path']
265 path = model['path']
267
266
268 # Check that we 'get' on the notebook we just created
267 # Check that we 'get' on the notebook we just created
269 model2 = cm.get(path)
268 model2 = cm.get(path)
270 assert isinstance(model2, dict)
269 assert isinstance(model2, dict)
271 self.assertIn('name', model2)
270 self.assertIn('name', model2)
272 self.assertIn('path', model2)
271 self.assertIn('path', model2)
273 self.assertEqual(model['name'], name)
272 self.assertEqual(model['name'], name)
274 self.assertEqual(model['path'], path)
273 self.assertEqual(model['path'], path)
275
274
276 nb_as_file = cm.get(path, content=True, type='file')
275 nb_as_file = cm.get(path, content=True, type='file')
277 self.assertEqual(nb_as_file['path'], path)
276 self.assertEqual(nb_as_file['path'], path)
278 self.assertEqual(nb_as_file['type'], 'file')
277 self.assertEqual(nb_as_file['type'], 'file')
279 self.assertEqual(nb_as_file['format'], 'text')
278 self.assertEqual(nb_as_file['format'], 'text')
280 self.assertNotIsInstance(nb_as_file['content'], dict)
279 self.assertNotIsInstance(nb_as_file['content'], dict)
281
280
282 nb_as_bin_file = cm.get(path, content=True, type='file', format='base64')
281 nb_as_bin_file = cm.get(path, content=True, type='file', format='base64')
283 self.assertEqual(nb_as_bin_file['format'], 'base64')
282 self.assertEqual(nb_as_bin_file['format'], 'base64')
284
283
285 # Test in sub-directory
284 # Test in sub-directory
286 sub_dir = '/foo/'
285 sub_dir = '/foo/'
287 self.make_dir('foo')
286 self.make_dir('foo')
288 model = cm.new_untitled(path=sub_dir, ext='.ipynb')
287 model = cm.new_untitled(path=sub_dir, ext='.ipynb')
289 model2 = cm.get(sub_dir + name)
288 model2 = cm.get(sub_dir + name)
290 assert isinstance(model2, dict)
289 assert isinstance(model2, dict)
291 self.assertIn('name', model2)
290 self.assertIn('name', model2)
292 self.assertIn('path', model2)
291 self.assertIn('path', model2)
293 self.assertIn('content', model2)
292 self.assertIn('content', model2)
294 self.assertEqual(model2['name'], 'Untitled.ipynb')
293 self.assertEqual(model2['name'], 'Untitled.ipynb')
295 self.assertEqual(model2['path'], '{0}/{1}'.format(sub_dir.strip('/'), name))
294 self.assertEqual(model2['path'], '{0}/{1}'.format(sub_dir.strip('/'), name))
296
295
297 # Test with a regular file.
296 # Test with a regular file.
298 file_model_path = cm.new_untitled(path=sub_dir, ext='.txt')['path']
297 file_model_path = cm.new_untitled(path=sub_dir, ext='.txt')['path']
299 file_model = cm.get(file_model_path)
298 file_model = cm.get(file_model_path)
300 self.assertDictContainsSubset(
299 self.assertDictContainsSubset(
301 {
300 {
302 'content': u'',
301 'content': u'',
303 'format': u'text',
302 'format': u'text',
304 'mimetype': u'text/plain',
303 'mimetype': u'text/plain',
305 'name': u'untitled.txt',
304 'name': u'untitled.txt',
306 'path': u'foo/untitled.txt',
305 'path': u'foo/untitled.txt',
307 'type': u'file',
306 'type': u'file',
308 'writable': True,
307 'writable': True,
309 },
308 },
310 file_model,
309 file_model,
311 )
310 )
312 self.assertIn('created', file_model)
311 self.assertIn('created', file_model)
313 self.assertIn('last_modified', file_model)
312 self.assertIn('last_modified', file_model)
314
313
315 # Test getting directory model
314 # Test getting directory model
316
315
317 # Create a sub-sub directory to test getting directory contents with a
316 # Create a sub-sub directory to test getting directory contents with a
318 # subdir.
317 # subdir.
319 self.make_dir('foo/bar')
318 self.make_dir('foo/bar')
320 dirmodel = cm.get('foo')
319 dirmodel = cm.get('foo')
321 self.assertEqual(dirmodel['type'], 'directory')
320 self.assertEqual(dirmodel['type'], 'directory')
322 self.assertIsInstance(dirmodel['content'], list)
321 self.assertIsInstance(dirmodel['content'], list)
323 self.assertEqual(len(dirmodel['content']), 3)
322 self.assertEqual(len(dirmodel['content']), 3)
324 self.assertEqual(dirmodel['path'], 'foo')
323 self.assertEqual(dirmodel['path'], 'foo')
325 self.assertEqual(dirmodel['name'], 'foo')
324 self.assertEqual(dirmodel['name'], 'foo')
326
325
327 # Directory contents should match the contents of each individual entry
326 # Directory contents should match the contents of each individual entry
328 # when requested with content=False.
327 # when requested with content=False.
329 model2_no_content = cm.get(sub_dir + name, content=False)
328 model2_no_content = cm.get(sub_dir + name, content=False)
330 file_model_no_content = cm.get(u'foo/untitled.txt', content=False)
329 file_model_no_content = cm.get(u'foo/untitled.txt', content=False)
331 sub_sub_dir_no_content = cm.get('foo/bar', content=False)
330 sub_sub_dir_no_content = cm.get('foo/bar', content=False)
332 self.assertEqual(sub_sub_dir_no_content['path'], 'foo/bar')
331 self.assertEqual(sub_sub_dir_no_content['path'], 'foo/bar')
333 self.assertEqual(sub_sub_dir_no_content['name'], 'bar')
332 self.assertEqual(sub_sub_dir_no_content['name'], 'bar')
334
333
335 for entry in dirmodel['content']:
334 for entry in dirmodel['content']:
336 # Order isn't guaranteed by the spec, so this is a hacky way of
335 # Order isn't guaranteed by the spec, so this is a hacky way of
337 # verifying that all entries are matched.
336 # verifying that all entries are matched.
338 if entry['path'] == sub_sub_dir_no_content['path']:
337 if entry['path'] == sub_sub_dir_no_content['path']:
339 self.assertEqual(entry, sub_sub_dir_no_content)
338 self.assertEqual(entry, sub_sub_dir_no_content)
340 elif entry['path'] == model2_no_content['path']:
339 elif entry['path'] == model2_no_content['path']:
341 self.assertEqual(entry, model2_no_content)
340 self.assertEqual(entry, model2_no_content)
342 elif entry['path'] == file_model_no_content['path']:
341 elif entry['path'] == file_model_no_content['path']:
343 self.assertEqual(entry, file_model_no_content)
342 self.assertEqual(entry, file_model_no_content)
344 else:
343 else:
345 self.fail("Unexpected directory entry: %s" % entry())
344 self.fail("Unexpected directory entry: %s" % entry())
346
345
347 with self.assertRaises(HTTPError):
346 with self.assertRaises(HTTPError):
348 cm.get('foo', type='file')
347 cm.get('foo', type='file')
349
348
350 def test_update(self):
349 def test_update(self):
351 cm = self.contents_manager
350 cm = self.contents_manager
352 # Create a notebook
351 # Create a notebook
353 model = cm.new_untitled(type='notebook')
352 model = cm.new_untitled(type='notebook')
354 name = model['name']
353 name = model['name']
355 path = model['path']
354 path = model['path']
356
355
357 # Change the name in the model for rename
356 # Change the name in the model for rename
358 model['path'] = 'test.ipynb'
357 model['path'] = 'test.ipynb'
359 model = cm.update(model, path)
358 model = cm.update(model, path)
360 assert isinstance(model, dict)
359 assert isinstance(model, dict)
361 self.assertIn('name', model)
360 self.assertIn('name', model)
362 self.assertIn('path', model)
361 self.assertIn('path', model)
363 self.assertEqual(model['name'], 'test.ipynb')
362 self.assertEqual(model['name'], 'test.ipynb')
364
363
365 # Make sure the old name is gone
364 # Make sure the old name is gone
366 self.assertRaises(HTTPError, cm.get, path)
365 self.assertRaises(HTTPError, cm.get, path)
367
366
368 # Test in sub-directory
367 # Test in sub-directory
369 # Create a directory and notebook in that directory
368 # Create a directory and notebook in that directory
370 sub_dir = '/foo/'
369 sub_dir = '/foo/'
371 self.make_dir('foo')
370 self.make_dir('foo')
372 model = cm.new_untitled(path=sub_dir, type='notebook')
371 model = cm.new_untitled(path=sub_dir, type='notebook')
373 path = model['path']
372 path = model['path']
374
373
375 # Change the name in the model for rename
374 # Change the name in the model for rename
376 d = path.rsplit('/', 1)[0]
375 d = path.rsplit('/', 1)[0]
377 new_path = model['path'] = d + '/test_in_sub.ipynb'
376 new_path = model['path'] = d + '/test_in_sub.ipynb'
378 model = cm.update(model, path)
377 model = cm.update(model, path)
379 assert isinstance(model, dict)
378 assert isinstance(model, dict)
380 self.assertIn('name', model)
379 self.assertIn('name', model)
381 self.assertIn('path', model)
380 self.assertIn('path', model)
382 self.assertEqual(model['name'], 'test_in_sub.ipynb')
381 self.assertEqual(model['name'], 'test_in_sub.ipynb')
383 self.assertEqual(model['path'], new_path)
382 self.assertEqual(model['path'], new_path)
384
383
385 # Make sure the old name is gone
384 # Make sure the old name is gone
386 self.assertRaises(HTTPError, cm.get, path)
385 self.assertRaises(HTTPError, cm.get, path)
387
386
388 def test_save(self):
387 def test_save(self):
389 cm = self.contents_manager
388 cm = self.contents_manager
390 # Create a notebook
389 # Create a notebook
391 model = cm.new_untitled(type='notebook')
390 model = cm.new_untitled(type='notebook')
392 name = model['name']
391 name = model['name']
393 path = model['path']
392 path = model['path']
394
393
395 # Get the model with 'content'
394 # Get the model with 'content'
396 full_model = cm.get(path)
395 full_model = cm.get(path)
397
396
398 # Save the notebook
397 # Save the notebook
399 model = cm.save(full_model, path)
398 model = cm.save(full_model, path)
400 assert isinstance(model, dict)
399 assert isinstance(model, dict)
401 self.assertIn('name', model)
400 self.assertIn('name', model)
402 self.assertIn('path', model)
401 self.assertIn('path', model)
403 self.assertEqual(model['name'], name)
402 self.assertEqual(model['name'], name)
404 self.assertEqual(model['path'], path)
403 self.assertEqual(model['path'], path)
405
404
406 # Test in sub-directory
405 # Test in sub-directory
407 # Create a directory and notebook in that directory
406 # Create a directory and notebook in that directory
408 sub_dir = '/foo/'
407 sub_dir = '/foo/'
409 self.make_dir('foo')
408 self.make_dir('foo')
410 model = cm.new_untitled(path=sub_dir, type='notebook')
409 model = cm.new_untitled(path=sub_dir, type='notebook')
411 name = model['name']
410 name = model['name']
412 path = model['path']
411 path = model['path']
413 model = cm.get(path)
412 model = cm.get(path)
414
413
415 # Change the name in the model for rename
414 # Change the name in the model for rename
416 model = cm.save(model, path)
415 model = cm.save(model, path)
417 assert isinstance(model, dict)
416 assert isinstance(model, dict)
418 self.assertIn('name', model)
417 self.assertIn('name', model)
419 self.assertIn('path', model)
418 self.assertIn('path', model)
420 self.assertEqual(model['name'], 'Untitled.ipynb')
419 self.assertEqual(model['name'], 'Untitled.ipynb')
421 self.assertEqual(model['path'], 'foo/Untitled.ipynb')
420 self.assertEqual(model['path'], 'foo/Untitled.ipynb')
422
421
423 def test_delete(self):
422 def test_delete(self):
424 cm = self.contents_manager
423 cm = self.contents_manager
425 # Create a notebook
424 # Create a notebook
426 nb, name, path = self.new_notebook()
425 nb, name, path = self.new_notebook()
427
426
428 # Delete the notebook
427 # Delete the notebook
429 cm.delete(path)
428 cm.delete(path)
430
429
431 # Check that deleting a non-existent path raises an error.
430 # Check that deleting a non-existent path raises an error.
432 self.assertRaises(HTTPError, cm.delete, path)
431 self.assertRaises(HTTPError, cm.delete, path)
433
432
434 # Check that a 'get' on the deleted notebook raises and error
433 # Check that a 'get' on the deleted notebook raises and error
435 self.assertRaises(HTTPError, cm.get, path)
434 self.assertRaises(HTTPError, cm.get, path)
436
435
437 def test_copy(self):
436 def test_copy(self):
438 cm = self.contents_manager
437 cm = self.contents_manager
439 parent = u'Γ₯ b'
438 parent = u'Γ₯ b'
440 name = u'nb √.ipynb'
439 name = u'nb √.ipynb'
441 path = u'{0}/{1}'.format(parent, name)
440 path = u'{0}/{1}'.format(parent, name)
442 self.make_dir(parent)
441 self.make_dir(parent)
443
442
444 orig = cm.new(path=path)
443 orig = cm.new(path=path)
445 # copy with unspecified name
444 # copy with unspecified name
446 copy = cm.copy(path)
445 copy = cm.copy(path)
447 self.assertEqual(copy['name'], orig['name'].replace('.ipynb', '-Copy1.ipynb'))
446 self.assertEqual(copy['name'], orig['name'].replace('.ipynb', '-Copy1.ipynb'))
448
447
449 # copy with specified name
448 # copy with specified name
450 copy2 = cm.copy(path, u'Γ₯ b/copy 2.ipynb')
449 copy2 = cm.copy(path, u'Γ₯ b/copy 2.ipynb')
451 self.assertEqual(copy2['name'], u'copy 2.ipynb')
450 self.assertEqual(copy2['name'], u'copy 2.ipynb')
452 self.assertEqual(copy2['path'], u'Γ₯ b/copy 2.ipynb')
451 self.assertEqual(copy2['path'], u'Γ₯ b/copy 2.ipynb')
453 # copy with specified path
452 # copy with specified path
454 copy2 = cm.copy(path, u'/')
453 copy2 = cm.copy(path, u'/')
455 self.assertEqual(copy2['name'], name)
454 self.assertEqual(copy2['name'], name)
456 self.assertEqual(copy2['path'], name)
455 self.assertEqual(copy2['path'], name)
457
456
458 def test_trust_notebook(self):
457 def test_trust_notebook(self):
459 cm = self.contents_manager
458 cm = self.contents_manager
460 nb, name, path = self.new_notebook()
459 nb, name, path = self.new_notebook()
461
460
462 untrusted = cm.get(path)['content']
461 untrusted = cm.get(path)['content']
463 assert not cm.notary.check_cells(untrusted)
462 assert not cm.notary.check_cells(untrusted)
464
463
465 # print(untrusted)
464 # print(untrusted)
466 cm.trust_notebook(path)
465 cm.trust_notebook(path)
467 trusted = cm.get(path)['content']
466 trusted = cm.get(path)['content']
468 # print(trusted)
467 # print(trusted)
469 assert cm.notary.check_cells(trusted)
468 assert cm.notary.check_cells(trusted)
470
469
471 def test_mark_trusted_cells(self):
470 def test_mark_trusted_cells(self):
472 cm = self.contents_manager
471 cm = self.contents_manager
473 nb, name, path = self.new_notebook()
472 nb, name, path = self.new_notebook()
474
473
475 cm.mark_trusted_cells(nb, path)
474 cm.mark_trusted_cells(nb, path)
476 for cell in nb.cells:
475 for cell in nb.cells:
477 if cell.cell_type == 'code':
476 if cell.cell_type == 'code':
478 assert not cell.metadata.trusted
477 assert not cell.metadata.trusted
479
478
480 cm.trust_notebook(path)
479 cm.trust_notebook(path)
481 nb = cm.get(path)['content']
480 nb = cm.get(path)['content']
482 for cell in nb.cells:
481 for cell in nb.cells:
483 if cell.cell_type == 'code':
482 if cell.cell_type == 'code':
484 assert cell.metadata.trusted
483 assert cell.metadata.trusted
485
484
486 def test_check_and_sign(self):
485 def test_check_and_sign(self):
487 cm = self.contents_manager
486 cm = self.contents_manager
488 nb, name, path = self.new_notebook()
487 nb, name, path = self.new_notebook()
489
488
490 cm.mark_trusted_cells(nb, path)
489 cm.mark_trusted_cells(nb, path)
491 cm.check_and_sign(nb, path)
490 cm.check_and_sign(nb, path)
492 assert not cm.notary.check_signature(nb)
491 assert not cm.notary.check_signature(nb)
493
492
494 cm.trust_notebook(path)
493 cm.trust_notebook(path)
495 nb = cm.get(path)['content']
494 nb = cm.get(path)['content']
496 cm.mark_trusted_cells(nb, path)
495 cm.mark_trusted_cells(nb, path)
497 cm.check_and_sign(nb, path)
496 cm.check_and_sign(nb, path)
498 assert cm.notary.check_signature(nb)
497 assert cm.notary.check_signature(nb)
General Comments 0
You need to be logged in to leave comments. Login now