Pārlūkot izejas kodu

Update notebook trust handler and tests

Steven Silvester 9 gadi atpakaļ
vecāks
revīzija
78b9d997be

+ 2 - 2
src/notebook/notebook/trust.ts

@@ -29,7 +29,7 @@ const TRUST_MESSAGE = '<p>A trusted Jupyter notebook may execute hidden maliciou
 export
 function trustNotebook(model: INotebookModel, host?: HTMLElement): Promise<void> {
   if (!model) {
-    return;
+    return Promise.resolve(void 0);
   }
   // Do nothing if already trusted.
   let cells = model.cells;
@@ -48,7 +48,7 @@ function trustNotebook(model: INotebookModel, host?: HTMLElement): Promise<void>
     body: TRUST_MESSAGE,
     title: 'Trust this notebook?'
   }).then(result => {
-    if (result.text === 'OK') {
+    if (result && result.text === 'OK') {
       for (let i = 0; i < cells.length; i++) {
         let cell = cells.get(i);
         cell.getMetadata('trusted').setValue(true);

+ 11 - 8
test/src/dialog/dialog.spec.ts

@@ -3,16 +3,19 @@
 
 import expect = require('expect.js');
 
+import {
+  simulate
+} from 'simulate-event';
+
 import {
   showDialog, okButton
 } from '../../../lib/dialog';
 
 import {
-  triggerMouseEvent, triggerKeyEvent, acceptDialog, dismissDialog
+  acceptDialog, dismissDialog
 } from '../utils';
 
 
-
 describe('jupyter-ui', () => {
 
   describe('showDialog()', () => {
@@ -24,7 +27,7 @@ describe('jupyter-ui', () => {
       });
       Promise.resolve().then(() => {
         let node = document.body.getElementsByClassName('jp-Dialog')[0];
-        triggerKeyEvent(node as HTMLElement, 'keydown', { keyCode: 27 });
+        simulate(node as HTMLElement, 'keydown', { keyCode: 27 });
       });
     });
 
@@ -37,14 +40,14 @@ describe('jupyter-ui', () => {
         host: node,
         buttons: [okButton],
         okText: 'Yep'
-      }
+      };
       showDialog(options).then(result => {
         expect(result).to.be(null);
         done();
       });
       Promise.resolve().then(() => {
         let target = document.body.getElementsByClassName('jp-Dialog')[0];
-        triggerKeyEvent(target as HTMLElement, 'keydown', { keyCode: 27 });
+        simulate(target as HTMLElement, 'keydown', { keyCode: 27 });
       });
     });
 
@@ -84,7 +87,7 @@ describe('jupyter-ui', () => {
         text: 'foo',
         className: 'bar',
         icon: 'baz'
-      }
+      };
       showDialog({ buttons: [button] }).then(result => {
         expect(result.text).to.be('foo');
         done();
@@ -103,8 +106,8 @@ describe('jupyter-ui', () => {
       });
       Promise.resolve().then(() => {
         let node = document.body.getElementsByClassName('jp-Dialog')[0];
-        triggerMouseEvent(node as HTMLElement, 'contextmenu');
-        triggerKeyEvent(node as HTMLElement, 'keydown', { keyCode: 27 });
+        simulate(node as HTMLElement, 'contextmenu');
+        simulate(node as HTMLElement, 'keydown', { keyCode: 27 });
       });
     });
 

+ 1 - 0
test/src/index.ts

@@ -11,6 +11,7 @@ import './notebook/notebook/nbformat.spec';
 import './notebook/notebook/model.spec';
 import './notebook/notebook/modelfactory.spec';
 import './notebook/notebook/toolbar.spec';
+import './notebook/notebook/trust.spec';
 import './notebook/notebook/widget.spec';
 import './notebook/notebook/widgetfactory.spec';
 

+ 3 - 2
test/src/notebook/notebook/model.spec.ts

@@ -19,8 +19,9 @@ import {
   NotebookModel
 } from '../../../../lib/notebook/notebook/model';
 
-
-const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;
+import {
+  DEFAULT_CONTENT
+} from '../utils';
 
 
 describe('notebook/notebook', () => {

+ 70 - 0
test/src/notebook/notebook/trust.spec.ts

@@ -0,0 +1,70 @@
+// Copyright (c) Jupyter Development Team.
+// Distributed under the terms of the Modified BSD License.
+
+import expect = require('expect.js');
+
+import {
+ NotebookModel
+} from '../../../../lib/notebook/notebook/model';
+
+import {
+  trustNotebook
+} from '../../../../lib/notebook/notebook/trust';
+
+import {
+  acceptDialog, dismissDialog
+} from '../../utils';
+
+import {
+  DEFAULT_CONTENT
+} from '../utils';
+
+
+describe('notebook/notebook/trust', () => {
+
+  describe('#trustNotebook()', () => {
+
+    it('should trust the notebook cells if the user accepts', (done) => {
+      let model = new NotebookModel();
+      model.fromJSON(DEFAULT_CONTENT);
+      let cell = model.cells.get(0);
+      let cursor = cell.getMetadata('trusted');
+      expect(cursor.getValue()).to.not.be(true);
+      trustNotebook(model).then(() => {
+        expect(cursor.getValue()).to.be(true);
+        done();
+      });
+      acceptDialog();
+    });
+
+    it('should not trust the notebook cells if the user aborts', (done) => {
+      let model = new NotebookModel();
+      model.fromJSON(DEFAULT_CONTENT);
+      let cell = model.cells.get(0);
+      let cursor = cell.getMetadata('trusted');
+      expect(cursor.getValue()).to.not.be(true);
+      trustNotebook(model).then(() => {
+        expect(cursor.getValue()).to.not.be(true);
+        done();
+      });
+      dismissDialog();
+    });
+
+    it('should bail if the model is `null`', (done) => {
+      trustNotebook(null).then(() => { done(); });
+    });
+
+    it('should bail if all of the cells are trusted', (done) => {
+      let model = new NotebookModel();
+      model.fromJSON(DEFAULT_CONTENT);
+      for (let i = 0; i < model.cells.length; i++) {
+        let cell = model.cells.get(i);
+        let cursor = cell.getMetadata('trusted');
+        cursor.setValue(true);
+      }
+      trustNotebook(model).then(() => { done(); });
+    });
+
+  });
+
+});

+ 4 - 6
test/src/notebook/notebook/widget.spec.ts

@@ -32,18 +32,16 @@ import {
   Notebook, StaticNotebook
 } from '../../../../lib/notebook/notebook/widget';
 
-import {
-  nbformat
-} from '../../../../lib/notebook/notebook/nbformat';
-
 import {
   defaultRenderMime
 } from '../../rendermime/rendermime.spec';
 
+import {
+  DEFAULT_CONTENT
+} from '../utils';
 
-const rendermime = defaultRenderMime();
 
-const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;
+const rendermime = defaultRenderMime();
 
 
 function createWidget(): LogStaticNotebook {

+ 13 - 0
test/src/notebook/utils.ts

@@ -0,0 +1,13 @@
+// Copyright (c) Jupyter Development Team.
+// Distributed under the terms of the Modified BSD License.
+
+import {
+  nbformat
+} from '../../../lib/notebook/notebook/nbformat';
+
+
+/**
+ * The default notebook content.
+ */
+export
+const DEFAULT_CONTENT: nbformat.INotebookContent = require('../../../examples/notebook/test.ipynb') as nbformat.INotebookContent;

+ 19 - 21
test/src/utils.ts

@@ -1,24 +1,14 @@
 // Copyright (c) Jupyter Development Team.
 // Distributed under the terms of the Modified BSD License.
 
-export
-function triggerMouseEvent(node: HTMLElement, eventType: string, options: any = {}) {
-  let evt = new MouseEvent(eventType, options);
-  node.dispatchEvent(evt);
-}
-
-
-export
-function triggerKeyEvent(node: HTMLElement, eventType: string, options: any = {}) {
-  let evt = new KeyboardEvent(eventType, options);
-  // Work around bug in Chrome that zeros out the keyCode.
-  if ('keyCode' in options) {
-    Object.defineProperty(evt, 'keyCode', { value: options['keyCode'] });
-  }
-  node.dispatchEvent(evt);
-}
+import {
+  simulate
+} from 'simulate-event';
 
 
+/**
+ * Wait for a dialog to be attached to an element.
+ */
 export
 function waitForDialog(host: HTMLElement = document.body): Promise<void> {
   return new Promise<void>((resolve, reject) => {
@@ -29,27 +19,35 @@ function waitForDialog(host: HTMLElement = document.body): Promise<void> {
         return;
       }
       setTimeout(refresh, 10);
-    }
+    };
     refresh();
   });
 }
 
 
+/**
+ * Accept a dialog after it is attached if it has an OK button.
+ */
 export
 function acceptDialog(host: HTMLElement = document.body): Promise<void> {
-  return waitForDialog().then(() => {
+  return waitForDialog(host).then(() => {
     let node = host.getElementsByClassName('jp-Dialog-okButton')[0];
-    if (node) (node as HTMLElement).click();
+    if (node) {
+      (node as HTMLElement).click();
+    }
   });
 }
 
 
+/**
+ * Dismiss a dialog after it is attached.
+ */
 export
 function dismissDialog(host: HTMLElement = document.body): Promise<void> {
-  return waitForDialog().then(() => {
+  return waitForDialog(host).then(() => {
     let node = host.getElementsByClassName('jp-Dialog')[0];
     if (node) {
-      triggerKeyEvent(node as HTMLElement, 'keydown', { keyCode: 27 });
+      simulate(node as HTMLElement, 'keydown', { keyCode: 27 });
     }
   });
 }