test_nbmanager.py
288 lines
| 11.5 KiB
| text/x-python
|
PythonLexer
MinRK
|
r7637 | """Tests for the notebook manager.""" | ||
import os | ||||
Zachary Sailer
|
r13046 | |||
from tornado.web import HTTPError | ||||
MinRK
|
r7637 | from unittest import TestCase | ||
from tempfile import NamedTemporaryFile | ||||
from IPython.utils.tempdir import TemporaryDirectory | ||||
from IPython.utils.traitlets import TraitError | ||||
Zachary Sailer
|
r13046 | from IPython.html.utils import url_path_join | ||
MinRK
|
r7637 | |||
Brian E. Granger
|
r10661 | from ..filenbmanager import FileNotebookManager | ||
Paul Ivanov
|
r13025 | from ..nbmanager import NotebookManager | ||
MinRK
|
r7637 | |||
Paul Ivanov
|
r13025 | class TestFileNotebookManager(TestCase): | ||
MinRK
|
r7637 | |||
def test_nb_dir(self): | ||||
with TemporaryDirectory() as td: | ||||
Paul Ivanov
|
r13034 | fm = FileNotebookManager(notebook_dir=td) | ||
self.assertEqual(fm.notebook_dir, td) | ||||
MinRK
|
r7637 | |||
def test_create_nb_dir(self): | ||||
with TemporaryDirectory() as td: | ||||
nbdir = os.path.join(td, 'notebooks') | ||||
Paul Ivanov
|
r13034 | fm = FileNotebookManager(notebook_dir=nbdir) | ||
self.assertEqual(fm.notebook_dir, nbdir) | ||||
MinRK
|
r7637 | |||
def test_missing_nb_dir(self): | ||||
with TemporaryDirectory() as td: | ||||
nbdir = os.path.join(td, 'notebook', 'dir', 'is', 'missing') | ||||
Brian Granger
|
r8180 | self.assertRaises(TraitError, FileNotebookManager, notebook_dir=nbdir) | ||
MinRK
|
r7637 | |||
def test_invalid_nb_dir(self): | ||||
with NamedTemporaryFile() as tf: | ||||
Brian Granger
|
r8180 | self.assertRaises(TraitError, FileNotebookManager, notebook_dir=tf.name) | ||
MinRK
|
r7637 | |||
Zachary Sailer
|
r13032 | def test_get_os_path(self): | ||
# full filesystem path should be returned with correct operating system | ||||
# separators. | ||||
with TemporaryDirectory() as td: | ||||
nbdir = os.path.join(td, 'notebooks') | ||||
Paul Ivanov
|
r13034 | fm = FileNotebookManager(notebook_dir=nbdir) | ||
path = fm.get_os_path('test.ipynb', '/path/to/notebook/') | ||||
rel_path_list = '/path/to/notebook/test.ipynb'.split('/') | ||||
fs_path = os.path.join(fm.notebook_dir, *rel_path_list) | ||||
self.assertEqual(path, fs_path) | ||||
fm = FileNotebookManager(notebook_dir=nbdir) | ||||
path = fm.get_os_path('test.ipynb') | ||||
fs_path = os.path.join(fm.notebook_dir, 'test.ipynb') | ||||
self.assertEqual(path, fs_path) | ||||
fm = FileNotebookManager(notebook_dir=nbdir) | ||||
path = fm.get_os_path('test.ipynb', '////') | ||||
fs_path = os.path.join(fm.notebook_dir, 'test.ipynb') | ||||
self.assertEqual(path, fs_path) | ||||
Zachary Sailer
|
r13032 | |||
Paul Ivanov
|
r13025 | class TestNotebookManager(TestCase): | ||
Zachary Sailer
|
r13046 | |||
def make_dir(self, abs_path, rel_path): | ||||
"""make subdirectory, rel_path is the relative path | ||||
to that directory from the location where the server started""" | ||||
os_path = os.path.join(abs_path, rel_path) | ||||
try: | ||||
os.makedirs(os_path) | ||||
except OSError: | ||||
print "Directory already exists." | ||||
Paul Ivanov
|
r13025 | def test_named_notebook_path(self): | ||
Zachary Sailer
|
r13053 | """the `named_notebook_path` method takes a URL path to | ||
a notebook and returns a url path split into nb and path""" | ||||
Paul Ivanov
|
r13025 | nm = NotebookManager() | ||
Zachary Sailer
|
r13031 | |||
Paul Ivanov
|
r13025 | # doesn't end with ipynb, should just be path | ||
name, path = nm.named_notebook_path('hello') | ||||
self.assertEqual(name, None) | ||||
Paul Ivanov
|
r13028 | self.assertEqual(path, '/hello/') | ||
Zachary Sailer
|
r13031 | |||
Zachary Sailer
|
r13053 | # Root path returns just the root slash | ||
Paul Ivanov
|
r13027 | name, path = nm.named_notebook_path('/') | ||
self.assertEqual(name, None) | ||||
Paul Ivanov
|
r13028 | self.assertEqual(path, '/') | ||
Paul Ivanov
|
r13025 | |||
Zachary Sailer
|
r13053 | # get notebook, and return the path as '/' | ||
name, path = nm.named_notebook_path('notebook.ipynb') | ||||
self.assertEqual(name, 'notebook.ipynb') | ||||
Paul Ivanov
|
r13027 | self.assertEqual(path, '/') | ||
Zachary Sailer
|
r13031 | |||
Zachary Sailer
|
r13053 | # Test a notebook name with leading slash returns | ||
# the same as above | ||||
name, path = nm.named_notebook_path('/notebook.ipynb') | ||||
self.assertEqual(name, 'notebook.ipynb') | ||||
Paul Ivanov
|
r13027 | self.assertEqual(path, '/') | ||
Zachary Sailer
|
r13031 | |||
Zachary Sailer
|
r13053 | # Multiple path arguments splits the notebook name | ||
# and returns path with leading and trailing '/' | ||||
name, path = nm.named_notebook_path('/this/is/a/path/notebook.ipynb') | ||||
self.assertEqual(name, 'notebook.ipynb') | ||||
Paul Ivanov
|
r13025 | self.assertEqual(path, '/this/is/a/path/') | ||
Zachary Sailer
|
r13031 | |||
Zachary Sailer
|
r13053 | # path without leading slash is returned with leading slash | ||
name, path = nm.named_notebook_path('path/without/leading/slash/notebook.ipynb') | ||||
self.assertEqual(name, 'notebook.ipynb') | ||||
Paul Ivanov
|
r13028 | self.assertEqual(path, '/path/without/leading/slash/') | ||
Paul Ivanov
|
r13025 | |||
Zachary Sailer
|
r13053 | # path with spaces and no leading or trailing '/' | ||
name, path = nm.named_notebook_path('foo / bar% path& to# @/ notebook name.ipynb') | ||||
self.assertEqual(name, ' notebook name.ipynb') | ||||
self.assertEqual(path, '/foo / bar% path& to# @/') | ||||
Zachary Sailer
|
r13031 | def test_url_encode(self): | ||
nm = NotebookManager() | ||||
# changes path or notebook name with special characters to url encoding | ||||
# these tests specifically encode paths with spaces | ||||
path = nm.url_encode('/this is a test/for spaces/') | ||||
self.assertEqual(path, '/this%20is%20a%20test/for%20spaces/') | ||||
path = nm.url_encode('notebook with space.ipynb') | ||||
self.assertEqual(path, 'notebook%20with%20space.ipynb') | ||||
path = nm.url_encode('/path with a/notebook and space.ipynb') | ||||
self.assertEqual(path, '/path%20with%20a/notebook%20and%20space.ipynb') | ||||
Zachary Sailer
|
r13053 | |||
path = nm.url_encode('/ !@$#%^&* / test %^ notebook @#$ name.ipynb') | ||||
self.assertEqual(path, | ||||
'/%20%21%40%24%23%25%5E%26%2A%20/%20test%20%25%5E%20notebook%20%40%23%24%20name.ipynb') | ||||
MinRK
|
r7637 | |||
Zachary Sailer
|
r13031 | def test_url_decode(self): | ||
nm = NotebookManager() | ||||
Zachary Sailer
|
r13046 | |||
Zachary Sailer
|
r13031 | # decodes a url string to a plain string | ||
# these tests decode paths with spaces | ||||
path = nm.url_decode('/this%20is%20a%20test/for%20spaces/') | ||||
self.assertEqual(path, '/this is a test/for spaces/') | ||||
Zachary Sailer
|
r13046 | |||
Zachary Sailer
|
r13031 | path = nm.url_decode('notebook%20with%20space.ipynb') | ||
self.assertEqual(path, 'notebook with space.ipynb') | ||||
Zachary Sailer
|
r13046 | |||
Zachary Sailer
|
r13031 | path = nm.url_decode('/path%20with%20a/notebook%20and%20space.ipynb') | ||
self.assertEqual(path, '/path with a/notebook and space.ipynb') | ||||
Zachary Sailer
|
r13046 | |||
Zachary Sailer
|
r13053 | path = nm.url_decode( | ||
'/%20%21%40%24%23%25%5E%26%2A%20/%20test%20%25%5E%20notebook%20%40%23%24%20name.ipynb') | ||||
self.assertEqual(path, '/ !@$#%^&* / test %^ notebook @#$ name.ipynb') | ||||
Zachary Sailer
|
r13046 | def test_create_notebook_model(self): | ||
with TemporaryDirectory() as td: | ||||
# Test in root directory | ||||
nm = FileNotebookManager(notebook_dir=td) | ||||
model = nm.create_notebook_model() | ||||
assert isinstance(model, dict) | ||||
self.assertIn('name', model) | ||||
self.assertIn('path', model) | ||||
self.assertEqual(model['name'], 'Untitled0.ipynb') | ||||
self.assertEqual(model['path'], '/') | ||||
# Test in sub-directory | ||||
sub_dir = '/foo/' | ||||
self.make_dir(nm.notebook_dir, 'foo') | ||||
model = nm.create_notebook_model(None, sub_dir) | ||||
assert isinstance(model, dict) | ||||
self.assertIn('name', model) | ||||
self.assertIn('path', model) | ||||
self.assertEqual(model['name'], 'Untitled0.ipynb') | ||||
self.assertEqual(model['path'], sub_dir) | ||||
def test_get_notebook_model(self): | ||||
with TemporaryDirectory() as td: | ||||
# Test in root directory | ||||
# Create a notebook | ||||
nm = FileNotebookManager(notebook_dir=td) | ||||
model = nm.create_notebook_model() | ||||
name = model['name'] | ||||
path = model['path'] | ||||
# Check that we 'get' on the notebook we just created | ||||
model2 = nm.get_notebook_model(name, path) | ||||
assert isinstance(model2, dict) | ||||
self.assertIn('name', model2) | ||||
self.assertIn('path', model2) | ||||
self.assertEqual(model['name'], name) | ||||
self.assertEqual(model['path'], path) | ||||
# Test in sub-directory | ||||
sub_dir = '/foo/' | ||||
self.make_dir(nm.notebook_dir, 'foo') | ||||
model = nm.create_notebook_model(None, sub_dir) | ||||
model2 = nm.get_notebook_model(name, sub_dir) | ||||
assert isinstance(model2, dict) | ||||
self.assertIn('name', model2) | ||||
self.assertIn('path', model2) | ||||
self.assertIn('content', model2) | ||||
self.assertEqual(model2['name'], 'Untitled0.ipynb') | ||||
self.assertEqual(model2['path'], sub_dir) | ||||
def test_update_notebook_model(self): | ||||
with TemporaryDirectory() as td: | ||||
# Test in root directory | ||||
# Create a notebook | ||||
nm = FileNotebookManager(notebook_dir=td) | ||||
model = nm.create_notebook_model() | ||||
name = model['name'] | ||||
path = model['path'] | ||||
# Change the name in the model for rename | ||||
model['name'] = 'test.ipynb' | ||||
model = nm.update_notebook_model(model, name, path) | ||||
assert isinstance(model, dict) | ||||
self.assertIn('name', model) | ||||
self.assertIn('path', model) | ||||
self.assertEqual(model['name'], 'test.ipynb') | ||||
# Make sure the old name is gone | ||||
self.assertRaises(HTTPError, nm.get_notebook_model, name, path) | ||||
# Test in sub-directory | ||||
# Create a directory and notebook in that directory | ||||
sub_dir = '/foo/' | ||||
self.make_dir(nm.notebook_dir, 'foo') | ||||
model = nm.create_notebook_model(None, sub_dir) | ||||
name = model['name'] | ||||
path = model['path'] | ||||
# Change the name in the model for rename | ||||
model['name'] = 'test_in_sub.ipynb' | ||||
model = nm.update_notebook_model(model, name, path) | ||||
assert isinstance(model, dict) | ||||
self.assertIn('name', model) | ||||
self.assertIn('path', model) | ||||
self.assertEqual(model['name'], 'test_in_sub.ipynb') | ||||
self.assertEqual(model['path'], sub_dir) | ||||
# Make sure the old name is gone | ||||
self.assertRaises(HTTPError, nm.get_notebook_model, name, path) | ||||
def test_save_notebook_model(self): | ||||
with TemporaryDirectory() as td: | ||||
# Test in the root directory | ||||
# Create a notebook | ||||
nm = FileNotebookManager(notebook_dir=td) | ||||
model = nm.create_notebook_model() | ||||
name = model['name'] | ||||
path = model['path'] | ||||
# Get the model with 'content' | ||||
full_model = nm.get_notebook_model(name, path) | ||||
# Save the notebook | ||||
model = nm.save_notebook_model(full_model, name, path) | ||||
assert isinstance(model, dict) | ||||
self.assertIn('name', model) | ||||
self.assertIn('path', model) | ||||
self.assertEqual(model['name'], name) | ||||
self.assertEqual(model['path'], path) | ||||
# Test in sub-directory | ||||
# Create a directory and notebook in that directory | ||||
sub_dir = '/foo/' | ||||
self.make_dir(nm.notebook_dir, 'foo') | ||||
model = nm.create_notebook_model(None, sub_dir) | ||||
name = model['name'] | ||||
path = model['path'] | ||||
model = nm.get_notebook_model(name, path) | ||||
# Change the name in the model for rename | ||||
model = nm.save_notebook_model(model, name, path) | ||||
assert isinstance(model, dict) | ||||
self.assertIn('name', model) | ||||
self.assertIn('path', model) | ||||
self.assertEqual(model['name'], 'Untitled0.ipynb') | ||||
self.assertEqual(model['path'], sub_dir) | ||||
def test_delete_notebook_model(self): | ||||
with TemporaryDirectory() as td: | ||||
# Test in the root directory | ||||
# Create a notebook | ||||
nm = FileNotebookManager(notebook_dir=td) | ||||
model = nm.create_notebook_model() | ||||
name = model['name'] | ||||
path = model['path'] | ||||
# Delete the notebook | ||||
nm.delete_notebook_model(name, path) | ||||
# Check that a 'get' on the deleted notebook raises and error | ||||
self.assertRaises(HTTPError, nm.get_notebook_model, name, path) | ||||