##// END OF EJS Templates
test upload of v2 notebooks
MinRK -
Show More
@@ -1,295 +1,312
1 # coding: utf-8
1 # coding: utf-8
2 """Test the notebooks webservice API."""
2 """Test the notebooks webservice API."""
3
3
4 import io
4 import io
5 import json
5 import json
6 import os
6 import os
7 import shutil
7 import shutil
8 from unicodedata import normalize
8 from unicodedata import normalize
9
9
10 pjoin = os.path.join
10 pjoin = os.path.join
11
11
12 import requests
12 import requests
13
13
14 from IPython.html.utils import url_path_join, url_escape
14 from IPython.html.utils import url_path_join, url_escape
15 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
15 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
16 from IPython.nbformat import current
16 from IPython.nbformat.current import (new_notebook, write, read, new_worksheet,
17 from IPython.nbformat.current import (new_notebook, write, read, new_worksheet,
17 new_heading_cell, to_notebook_json)
18 new_heading_cell, to_notebook_json)
19 from IPython.nbformat import v2
18 from IPython.utils import py3compat
20 from IPython.utils import py3compat
19 from IPython.utils.data import uniq_stable
21 from IPython.utils.data import uniq_stable
20
22
21
23
22 class NBAPI(object):
24 class NBAPI(object):
23 """Wrapper for notebook API calls."""
25 """Wrapper for notebook API calls."""
24 def __init__(self, base_url):
26 def __init__(self, base_url):
25 self.base_url = base_url
27 self.base_url = base_url
26
28
27 def _req(self, verb, path, body=None):
29 def _req(self, verb, path, body=None):
28 response = requests.request(verb,
30 response = requests.request(verb,
29 url_path_join(self.base_url, 'api/notebooks', path),
31 url_path_join(self.base_url, 'api/notebooks', path),
30 data=body,
32 data=body,
31 )
33 )
32 response.raise_for_status()
34 response.raise_for_status()
33 return response
35 return response
34
36
35 def list(self, path='/'):
37 def list(self, path='/'):
36 return self._req('GET', path)
38 return self._req('GET', path)
37
39
38 def read(self, name, path='/'):
40 def read(self, name, path='/'):
39 return self._req('GET', url_path_join(path, name))
41 return self._req('GET', url_path_join(path, name))
40
42
41 def create_untitled(self, path='/'):
43 def create_untitled(self, path='/'):
42 return self._req('POST', path)
44 return self._req('POST', path)
43
45
44 def upload_untitled(self, body, path='/'):
46 def upload_untitled(self, body, path='/'):
45 return self._req('POST', path, body)
47 return self._req('POST', path, body)
46
48
47 def copy_untitled(self, copy_from, path='/'):
49 def copy_untitled(self, copy_from, path='/'):
48 body = json.dumps({'copy_from':copy_from})
50 body = json.dumps({'copy_from':copy_from})
49 return self._req('POST', path, body)
51 return self._req('POST', path, body)
50
52
51 def create(self, name, path='/'):
53 def create(self, name, path='/'):
52 return self._req('PUT', url_path_join(path, name))
54 return self._req('PUT', url_path_join(path, name))
53
55
54 def upload(self, name, body, path='/'):
56 def upload(self, name, body, path='/'):
55 return self._req('PUT', url_path_join(path, name), body)
57 return self._req('PUT', url_path_join(path, name), body)
56
58
57 def copy(self, copy_from, copy_to, path='/'):
59 def copy(self, copy_from, copy_to, path='/'):
58 body = json.dumps({'copy_from':copy_from})
60 body = json.dumps({'copy_from':copy_from})
59 return self._req('PUT', url_path_join(path, copy_to), body)
61 return self._req('PUT', url_path_join(path, copy_to), body)
60
62
61 def save(self, name, body, path='/'):
63 def save(self, name, body, path='/'):
62 return self._req('PUT', url_path_join(path, name), body)
64 return self._req('PUT', url_path_join(path, name), body)
63
65
64 def delete(self, name, path='/'):
66 def delete(self, name, path='/'):
65 return self._req('DELETE', url_path_join(path, name))
67 return self._req('DELETE', url_path_join(path, name))
66
68
67 def rename(self, name, path, new_name):
69 def rename(self, name, path, new_name):
68 body = json.dumps({'name': new_name})
70 body = json.dumps({'name': new_name})
69 return self._req('PATCH', url_path_join(path, name), body)
71 return self._req('PATCH', url_path_join(path, name), body)
70
72
71 def get_checkpoints(self, name, path):
73 def get_checkpoints(self, name, path):
72 return self._req('GET', url_path_join(path, name, 'checkpoints'))
74 return self._req('GET', url_path_join(path, name, 'checkpoints'))
73
75
74 def new_checkpoint(self, name, path):
76 def new_checkpoint(self, name, path):
75 return self._req('POST', url_path_join(path, name, 'checkpoints'))
77 return self._req('POST', url_path_join(path, name, 'checkpoints'))
76
78
77 def restore_checkpoint(self, name, path, checkpoint_id):
79 def restore_checkpoint(self, name, path, checkpoint_id):
78 return self._req('POST', url_path_join(path, name, 'checkpoints', checkpoint_id))
80 return self._req('POST', url_path_join(path, name, 'checkpoints', checkpoint_id))
79
81
80 def delete_checkpoint(self, name, path, checkpoint_id):
82 def delete_checkpoint(self, name, path, checkpoint_id):
81 return self._req('DELETE', url_path_join(path, name, 'checkpoints', checkpoint_id))
83 return self._req('DELETE', url_path_join(path, name, 'checkpoints', checkpoint_id))
82
84
83 class APITest(NotebookTestBase):
85 class APITest(NotebookTestBase):
84 """Test the kernels web service API"""
86 """Test the kernels web service API"""
85 dirs_nbs = [('', 'inroot'),
87 dirs_nbs = [('', 'inroot'),
86 ('Directory with spaces in', 'inspace'),
88 ('Directory with spaces in', 'inspace'),
87 (u'unicodé', 'innonascii'),
89 (u'unicodé', 'innonascii'),
88 ('foo', 'a'),
90 ('foo', 'a'),
89 ('foo', 'b'),
91 ('foo', 'b'),
90 ('foo', 'name with spaces'),
92 ('foo', 'name with spaces'),
91 ('foo', u'unicodé'),
93 ('foo', u'unicodé'),
92 ('foo/bar', 'baz'),
94 ('foo/bar', 'baz'),
93 (u'å b', u'ç d')
95 (u'å b', u'ç d')
94 ]
96 ]
95
97
96 dirs = uniq_stable([d for (d,n) in dirs_nbs])
98 dirs = uniq_stable([d for (d,n) in dirs_nbs])
97 del dirs[0] # remove ''
99 del dirs[0] # remove ''
98
100
99 def setUp(self):
101 def setUp(self):
100 nbdir = self.notebook_dir.name
102 nbdir = self.notebook_dir.name
101
103
102 for d in self.dirs:
104 for d in self.dirs:
103 if not os.path.isdir(pjoin(nbdir, d)):
105 if not os.path.isdir(pjoin(nbdir, d)):
104 os.mkdir(pjoin(nbdir, d))
106 os.mkdir(pjoin(nbdir, d))
105
107
106 for d, name in self.dirs_nbs:
108 for d, name in self.dirs_nbs:
107 with io.open(pjoin(nbdir, d, '%s.ipynb' % name), 'w') as f:
109 with io.open(pjoin(nbdir, d, '%s.ipynb' % name), 'w') as f:
108 nb = new_notebook(name=name)
110 nb = new_notebook(name=name)
109 write(nb, f, format='ipynb')
111 write(nb, f, format='ipynb')
110
112
111 self.nb_api = NBAPI(self.base_url())
113 self.nb_api = NBAPI(self.base_url())
112
114
113 def tearDown(self):
115 def tearDown(self):
114 nbdir = self.notebook_dir.name
116 nbdir = self.notebook_dir.name
115
117
116 for dname in ['foo', 'Directory with spaces in', u'unicodé', u'å b']:
118 for dname in ['foo', 'Directory with spaces in', u'unicodé', u'å b']:
117 shutil.rmtree(pjoin(nbdir, dname), ignore_errors=True)
119 shutil.rmtree(pjoin(nbdir, dname), ignore_errors=True)
118
120
119 if os.path.isfile(pjoin(nbdir, 'inroot.ipynb')):
121 if os.path.isfile(pjoin(nbdir, 'inroot.ipynb')):
120 os.unlink(pjoin(nbdir, 'inroot.ipynb'))
122 os.unlink(pjoin(nbdir, 'inroot.ipynb'))
121
123
122 def test_list_notebooks(self):
124 def test_list_notebooks(self):
123 nbs = self.nb_api.list().json()
125 nbs = self.nb_api.list().json()
124 self.assertEqual(len(nbs), 1)
126 self.assertEqual(len(nbs), 1)
125 self.assertEqual(nbs[0]['name'], 'inroot.ipynb')
127 self.assertEqual(nbs[0]['name'], 'inroot.ipynb')
126
128
127 nbs = self.nb_api.list('/Directory with spaces in/').json()
129 nbs = self.nb_api.list('/Directory with spaces in/').json()
128 self.assertEqual(len(nbs), 1)
130 self.assertEqual(len(nbs), 1)
129 self.assertEqual(nbs[0]['name'], 'inspace.ipynb')
131 self.assertEqual(nbs[0]['name'], 'inspace.ipynb')
130
132
131 nbs = self.nb_api.list(u'/unicodé/').json()
133 nbs = self.nb_api.list(u'/unicodé/').json()
132 self.assertEqual(len(nbs), 1)
134 self.assertEqual(len(nbs), 1)
133 self.assertEqual(nbs[0]['name'], 'innonascii.ipynb')
135 self.assertEqual(nbs[0]['name'], 'innonascii.ipynb')
134 self.assertEqual(nbs[0]['path'], u'unicodé')
136 self.assertEqual(nbs[0]['path'], u'unicodé')
135
137
136 nbs = self.nb_api.list('/foo/bar/').json()
138 nbs = self.nb_api.list('/foo/bar/').json()
137 self.assertEqual(len(nbs), 1)
139 self.assertEqual(len(nbs), 1)
138 self.assertEqual(nbs[0]['name'], 'baz.ipynb')
140 self.assertEqual(nbs[0]['name'], 'baz.ipynb')
139 self.assertEqual(nbs[0]['path'], 'foo/bar')
141 self.assertEqual(nbs[0]['path'], 'foo/bar')
140
142
141 nbs = self.nb_api.list('foo').json()
143 nbs = self.nb_api.list('foo').json()
142 self.assertEqual(len(nbs), 4)
144 self.assertEqual(len(nbs), 4)
143 nbnames = { normalize('NFC', n['name']) for n in nbs }
145 nbnames = { normalize('NFC', n['name']) for n in nbs }
144 expected = [ u'a.ipynb', u'b.ipynb', u'name with spaces.ipynb', u'unicodé.ipynb']
146 expected = [ u'a.ipynb', u'b.ipynb', u'name with spaces.ipynb', u'unicodé.ipynb']
145 expected = { normalize('NFC', name) for name in expected }
147 expected = { normalize('NFC', name) for name in expected }
146 self.assertEqual(nbnames, expected)
148 self.assertEqual(nbnames, expected)
147
149
148 def test_list_nonexistant_dir(self):
150 def test_list_nonexistant_dir(self):
149 with assert_http_error(404):
151 with assert_http_error(404):
150 self.nb_api.list('nonexistant')
152 self.nb_api.list('nonexistant')
151
153
152 def test_get_contents(self):
154 def test_get_contents(self):
153 for d, name in self.dirs_nbs:
155 for d, name in self.dirs_nbs:
154 nb = self.nb_api.read('%s.ipynb' % name, d+'/').json()
156 nb = self.nb_api.read('%s.ipynb' % name, d+'/').json()
155 self.assertEqual(nb['name'], u'%s.ipynb' % name)
157 self.assertEqual(nb['name'], u'%s.ipynb' % name)
156 self.assertIn('content', nb)
158 self.assertIn('content', nb)
157 self.assertIn('metadata', nb['content'])
159 self.assertIn('metadata', nb['content'])
158 self.assertIsInstance(nb['content']['metadata'], dict)
160 self.assertIsInstance(nb['content']['metadata'], dict)
159
161
160 # Name that doesn't exist - should be a 404
162 # Name that doesn't exist - should be a 404
161 with assert_http_error(404):
163 with assert_http_error(404):
162 self.nb_api.read('q.ipynb', 'foo')
164 self.nb_api.read('q.ipynb', 'foo')
163
165
164 def _check_nb_created(self, resp, name, path):
166 def _check_nb_created(self, resp, name, path):
165 self.assertEqual(resp.status_code, 201)
167 self.assertEqual(resp.status_code, 201)
166 location_header = py3compat.str_to_unicode(resp.headers['Location'])
168 location_header = py3compat.str_to_unicode(resp.headers['Location'])
167 self.assertEqual(location_header, url_escape(url_path_join(u'/api/notebooks', path, name)))
169 self.assertEqual(location_header, url_escape(url_path_join(u'/api/notebooks', path, name)))
168 self.assertEqual(resp.json()['name'], name)
170 self.assertEqual(resp.json()['name'], name)
169 assert os.path.isfile(pjoin(self.notebook_dir.name, path, name))
171 assert os.path.isfile(pjoin(self.notebook_dir.name, path, name))
170
172
171 def test_create_untitled(self):
173 def test_create_untitled(self):
172 resp = self.nb_api.create_untitled(path=u'å b')
174 resp = self.nb_api.create_untitled(path=u'å b')
173 self._check_nb_created(resp, 'Untitled0.ipynb', u'å b')
175 self._check_nb_created(resp, 'Untitled0.ipynb', u'å b')
174
176
175 # Second time
177 # Second time
176 resp = self.nb_api.create_untitled(path=u'å b')
178 resp = self.nb_api.create_untitled(path=u'å b')
177 self._check_nb_created(resp, 'Untitled1.ipynb', u'å b')
179 self._check_nb_created(resp, 'Untitled1.ipynb', u'å b')
178
180
179 # And two directories down
181 # And two directories down
180 resp = self.nb_api.create_untitled(path='foo/bar')
182 resp = self.nb_api.create_untitled(path='foo/bar')
181 self._check_nb_created(resp, 'Untitled0.ipynb', pjoin('foo', 'bar'))
183 self._check_nb_created(resp, 'Untitled0.ipynb', pjoin('foo', 'bar'))
182
184
183 def test_upload_untitled(self):
185 def test_upload_untitled(self):
184 nb = new_notebook(name='Upload test')
186 nb = new_notebook(name='Upload test')
185 nbmodel = {'content': nb}
187 nbmodel = {'content': nb}
186 resp = self.nb_api.upload_untitled(path=u'å b',
188 resp = self.nb_api.upload_untitled(path=u'å b',
187 body=json.dumps(nbmodel))
189 body=json.dumps(nbmodel))
188 self._check_nb_created(resp, 'Untitled0.ipynb', u'å b')
190 self._check_nb_created(resp, 'Untitled0.ipynb', u'å b')
189
191
190 def test_upload(self):
192 def test_upload(self):
191 nb = new_notebook(name=u'ignored')
193 nb = new_notebook(name=u'ignored')
192 nbmodel = {'content': nb}
194 nbmodel = {'content': nb}
193 resp = self.nb_api.upload(u'Upload tést.ipynb', path=u'å b',
195 resp = self.nb_api.upload(u'Upload tést.ipynb', path=u'å b',
194 body=json.dumps(nbmodel))
196 body=json.dumps(nbmodel))
195 self._check_nb_created(resp, u'Upload tést.ipynb', u'å b')
197 self._check_nb_created(resp, u'Upload tést.ipynb', u'å b')
196
198
199 def test_upload_v2(self):
200 nb = v2.new_notebook()
201 ws = v2.new_worksheet()
202 nb.worksheets.append(ws)
203 ws.cells.append(v2.new_code_cell(input='print("hi")'))
204 nbmodel = {'content': nb}
205 resp = self.nb_api.upload(u'Upload tést.ipynb', path=u'å b',
206 body=json.dumps(nbmodel))
207 self._check_nb_created(resp, u'Upload tést.ipynb', u'å b')
208 resp = self.nb_api.read(u'Upload tést.ipynb', u'å b')
209 data = resp.json()
210 self.assertEqual(data['content']['nbformat'], current.nbformat)
211 self.assertEqual(data['content']['orig_nbformat'], 2)
212
197 def test_copy_untitled(self):
213 def test_copy_untitled(self):
198 resp = self.nb_api.copy_untitled(u'ç d.ipynb', path=u'å b')
214 resp = self.nb_api.copy_untitled(u'ç d.ipynb', path=u'å b')
199 self._check_nb_created(resp, u'ç d-Copy0.ipynb', u'å b')
215 self._check_nb_created(resp, u'ç d-Copy0.ipynb', u'å b')
200
216
201 def test_copy(self):
217 def test_copy(self):
202 resp = self.nb_api.copy(u'ç d.ipynb', u'cøpy.ipynb', path=u'å b')
218 resp = self.nb_api.copy(u'ç d.ipynb', u'cøpy.ipynb', path=u'å b')
203 self._check_nb_created(resp, u'cøpy.ipynb', u'å b')
219 self._check_nb_created(resp, u'cøpy.ipynb', u'å b')
204
220
205 def test_delete(self):
221 def test_delete(self):
206 for d, name in self.dirs_nbs:
222 for d, name in self.dirs_nbs:
207 resp = self.nb_api.delete('%s.ipynb' % name, d)
223 resp = self.nb_api.delete('%s.ipynb' % name, d)
208 self.assertEqual(resp.status_code, 204)
224 self.assertEqual(resp.status_code, 204)
209
225
210 for d in self.dirs + ['/']:
226 for d in self.dirs + ['/']:
211 nbs = self.nb_api.list(d).json()
227 nbs = self.nb_api.list(d).json()
212 self.assertEqual(len(nbs), 0)
228 self.assertEqual(len(nbs), 0)
213
229
214 def test_rename(self):
230 def test_rename(self):
215 resp = self.nb_api.rename('a.ipynb', 'foo', 'z.ipynb')
231 resp = self.nb_api.rename('a.ipynb', 'foo', 'z.ipynb')
216 self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb')
232 self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb')
217 self.assertEqual(resp.json()['name'], 'z.ipynb')
233 self.assertEqual(resp.json()['name'], 'z.ipynb')
218 assert os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'z.ipynb'))
234 assert os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'z.ipynb'))
219
235
220 nbs = self.nb_api.list('foo').json()
236 nbs = self.nb_api.list('foo').json()
221 nbnames = set(n['name'] for n in nbs)
237 nbnames = set(n['name'] for n in nbs)
222 self.assertIn('z.ipynb', nbnames)
238 self.assertIn('z.ipynb', nbnames)
223 self.assertNotIn('a.ipynb', nbnames)
239 self.assertNotIn('a.ipynb', nbnames)
224
240
225 def test_save(self):
241 def test_save(self):
226 resp = self.nb_api.read('a.ipynb', 'foo')
242 resp = self.nb_api.read('a.ipynb', 'foo')
227 nbcontent = json.loads(resp.text)['content']
243 nbcontent = json.loads(resp.text)['content']
228 nb = to_notebook_json(nbcontent)
244 nb = to_notebook_json(nbcontent)
229 ws = new_worksheet()
245 ws = new_worksheet()
230 nb.worksheets = [ws]
246 nb.worksheets = [ws]
231 ws.cells.append(new_heading_cell(u'Created by test ³'))
247 ws.cells.append(new_heading_cell(u'Created by test ³'))
232
248
233 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
249 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
234 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
250 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
235
251
236 nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb')
252 nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb')
237 with io.open(nbfile, 'r', encoding='utf-8') as f:
253 with io.open(nbfile, 'r', encoding='utf-8') as f:
238 newnb = read(f, format='ipynb')
254 newnb = read(f, format='ipynb')
239 self.assertEqual(newnb.worksheets[0].cells[0].source,
255 self.assertEqual(newnb.worksheets[0].cells[0].source,
240 u'Created by test ³')
256 u'Created by test ³')
241 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
257 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
242 newnb = to_notebook_json(nbcontent)
258 newnb = to_notebook_json(nbcontent)
243 self.assertEqual(newnb.worksheets[0].cells[0].source,
259 self.assertEqual(newnb.worksheets[0].cells[0].source,
244 u'Created by test ³')
260 u'Created by test ³')
245
261
246 # Save and rename
262 # Save and rename
247 nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb}
263 nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb}
248 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
264 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
249 saved = resp.json()
265 saved = resp.json()
250 self.assertEqual(saved['name'], 'a2.ipynb')
266 self.assertEqual(saved['name'], 'a2.ipynb')
251 self.assertEqual(saved['path'], 'foo/bar')
267 self.assertEqual(saved['path'], 'foo/bar')
252 assert os.path.isfile(pjoin(self.notebook_dir.name,'foo','bar','a2.ipynb'))
268 assert os.path.isfile(pjoin(self.notebook_dir.name,'foo','bar','a2.ipynb'))
253 assert not os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'a.ipynb'))
269 assert not os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'a.ipynb'))
254 with assert_http_error(404):
270 with assert_http_error(404):
255 self.nb_api.read('a.ipynb', 'foo')
271 self.nb_api.read('a.ipynb', 'foo')
256
272
257 def test_checkpoints(self):
273 def test_checkpoints(self):
258 resp = self.nb_api.read('a.ipynb', 'foo')
274 resp = self.nb_api.read('a.ipynb', 'foo')
259 r = self.nb_api.new_checkpoint('a.ipynb', 'foo')
275 r = self.nb_api.new_checkpoint('a.ipynb', 'foo')
260 self.assertEqual(r.status_code, 201)
276 self.assertEqual(r.status_code, 201)
261 cp1 = r.json()
277 cp1 = r.json()
262 self.assertEqual(set(cp1), {'id', 'last_modified'})
278 self.assertEqual(set(cp1), {'id', 'last_modified'})
263 self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])
279 self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])
264
280
265 # Modify it
281 # Modify it
266 nbcontent = json.loads(resp.text)['content']
282 nbcontent = json.loads(resp.text)['content']
267 nb = to_notebook_json(nbcontent)
283 nb = to_notebook_json(nbcontent)
268 ws = new_worksheet()
284 ws = new_worksheet()
269 nb.worksheets = [ws]
285 nb.worksheets = [ws]
270 hcell = new_heading_cell('Created by test')
286 hcell = new_heading_cell('Created by test')
271 ws.cells.append(hcell)
287 ws.cells.append(hcell)
272 # Save
288 # Save
273 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
289 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
274 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
290 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
275
291
276 # List checkpoints
292 # List checkpoints
277 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
293 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
278 self.assertEqual(cps, [cp1])
294 self.assertEqual(cps, [cp1])
279
295
280 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
296 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
281 nb = to_notebook_json(nbcontent)
297 nb = to_notebook_json(nbcontent)
282 self.assertEqual(nb.worksheets[0].cells[0].source, 'Created by test')
298 self.assertEqual(nb.worksheets[0].cells[0].source, 'Created by test')
283
299
284 # Restore cp1
300 # Restore cp1
285 r = self.nb_api.restore_checkpoint('a.ipynb', 'foo', cp1['id'])
301 r = self.nb_api.restore_checkpoint('a.ipynb', 'foo', cp1['id'])
286 self.assertEqual(r.status_code, 204)
302 self.assertEqual(r.status_code, 204)
287 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
303 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
288 nb = to_notebook_json(nbcontent)
304 nb = to_notebook_json(nbcontent)
289 self.assertEqual(nb.worksheets, [])
305 self.assertEqual(nb.worksheets, [])
290
306
291 # Delete cp1
307 # Delete cp1
292 r = self.nb_api.delete_checkpoint('a.ipynb', 'foo', cp1['id'])
308 r = self.nb_api.delete_checkpoint('a.ipynb', 'foo', cp1['id'])
293 self.assertEqual(r.status_code, 204)
309 self.assertEqual(r.status_code, 204)
294 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
310 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
295 self.assertEqual(cps, [])
311 self.assertEqual(cps, [])
312
General Comments 0
You need to be logged in to leave comments. Login now