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