Support trusted books in new version of Jupyter Books (#12874)

* Fix path gor v1 and v2 boooks

* Add tests and address PR comments

* fix failing tests

* Address pr comments

* address pr comments
This commit is contained in:
Barbara Valdez
2020-10-27 20:57:44 -07:00
committed by GitHub
parent e2c9d3899b
commit 42e16b1752
3 changed files with 349 additions and 266 deletions

View File

@@ -92,7 +92,7 @@ export class BookTreeViewProvider implements vscode.TreeDataProvider<BookTreeIte
trustBook(bookTreeItem?: BookTreeItem): void { trustBook(bookTreeItem?: BookTreeItem): void {
let bookPathToTrust: string = bookTreeItem ? bookTreeItem.root : this.currentBook?.bookPath; let bookPathToTrust: string = bookTreeItem ? bookTreeItem.root : this.currentBook?.bookPath;
if (bookPathToTrust) { if (bookPathToTrust) {
let trustChanged = this._bookTrustManager.setBookAsTrusted(bookPathToTrust); let trustChanged = this._bookTrustManager.setBookAsTrusted(bookPathToTrust, true);
if (trustChanged) { if (trustChanged) {
let notebookDocuments = azdata.nb.notebookDocuments; let notebookDocuments = azdata.nb.notebookDocuments;
if (notebookDocuments) { if (notebookDocuments) {

View File

@@ -6,11 +6,11 @@ import * as path from 'path';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as constants from './../common/constants'; import * as constants from './../common/constants';
import { BookTreeItem } from './bookTreeItem'; import { BookTreeItem } from './bookTreeItem';
import { BookModel } from './bookModel'; import { BookModel, BookVersion } from './bookModel';
export interface IBookTrustManager { export interface IBookTrustManager {
isNotebookTrustedByDefault(notebookUri: string): boolean; isNotebookTrustedByDefault(notebookUri: string): boolean;
setBookAsTrusted(bookRootPath: string): boolean; setBookAsTrusted(bookRootPath: string, isTrusted: boolean): boolean;
} }
enum TrustBookOperation { enum TrustBookOperation {
@@ -27,7 +27,7 @@ export class BookTrustManager implements IBookTrustManager {
let trustableBookPaths = this.getTrustableBookPaths(); let trustableBookPaths = this.getTrustableBookPaths();
let hasTrustedBookPath: boolean = treeBookItems let hasTrustedBookPath: boolean = treeBookItems
.filter(bookItem => trustableBookPaths.some(trustableBookPath => trustableBookPath === path.join(bookItem.book.root, path.sep))) .filter(bookItem => trustableBookPaths.some(trustableBookPath => trustableBookPath === path.join(bookItem.book.root, path.sep)))
.some(bookItem => normalizedNotebookUri.startsWith(path.join(bookItem.root, 'content', path.sep))); .some(bookItem => normalizedNotebookUri.startsWith(bookItem.version === BookVersion.v1 ? path.join(bookItem.book.root, 'content', path.sep) : path.join(bookItem.book.root, path.sep)));
let isNotebookTrusted = hasTrustedBookPath && this.books.some(bookModel => bookModel.getNotebook(normalizedNotebookUri)); let isNotebookTrusted = hasTrustedBookPath && this.books.some(bookModel => bookModel.getNotebook(normalizedNotebookUri));
return isNotebookTrusted; return isNotebookTrusted;
} }
@@ -57,8 +57,11 @@ export class BookTrustManager implements IBookTrustManager {
.reduce((accumulator, currentBookItemList) => accumulator.concat(currentBookItemList), []); .reduce((accumulator, currentBookItemList) => accumulator.concat(currentBookItemList), []);
} }
setBookAsTrusted(bookRootPath: string): boolean { setBookAsTrusted(bookRootPath: string, isTrusted: boolean): boolean {
return this.updateTrustedBooks(bookRootPath, TrustBookOperation.Add); if (isTrusted) {
return this.updateTrustedBooks(bookRootPath, TrustBookOperation.Add);
}
return this.updateTrustedBooks(bookRootPath, TrustBookOperation.Remove);
} }
getTrustedBookPathsInConfig(): string[] { getTrustedBookPathsInConfig(): string[] {

View File

@@ -19,309 +19,389 @@ describe('BookTrustManagerTests', function () {
let bookTrustManager: IBookTrustManager; let bookTrustManager: IBookTrustManager;
let trustedSubFolders: string[]; let trustedSubFolders: string[];
let books: BookModel[]; let books: BookModel[];
let runs = [
afterEach(function (): void { {
sinon.restore(); it: 'using the jupyter-book legacy version < 0.7.0',
}); book1: {
'notebook1': path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb'),
beforeEach(() => { 'notebook2': path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook2.ipynb'),
trustedSubFolders = ['/SubFolder/']; 'notebook3': path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb'),
'notInTocNb': path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notInToc.ipynb')
// Mock Workspace Configuration
let workspaceConfigurtionMock: TypeMoq.IMock<vscode.WorkspaceConfiguration> = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
workspaceConfigurtionMock.setup(config => config.get(TypeMoq.It.isValue(constants.trustedBooksConfigKey))).returns(() => [].concat(trustedSubFolders));
workspaceConfigurtionMock.setup(config => config.update(TypeMoq.It.isValue(constants.trustedBooksConfigKey), TypeMoq.It.isAny(), TypeMoq.It.isValue(false))).returns((key: string, newValues: string[]) => {
trustedSubFolders.splice(0, trustedSubFolders.length, ...newValues); // Replace
return Promise.resolve();
});
sinon.replaceGetter(vscode.workspace, 'workspaceFolders', () => {
return <vscode.WorkspaceFolder[]>[{
uri: {
fsPath: '/temp/'
},
}, },
{ book2: {
uri: { 'notebook1': path.join(path.sep, 'temp2', 'SubFolder', 'content', 'sample', 'notebook.ipynb')
fsPath: '/temp2/'
}
}, },
]; unknownBook: {
}); 'unknownNotebook': path.join(path.sep, 'randomfolder', 'randomsubfolder', 'content', 'randomnotebook.ipynb')
}
}, {
it: 'using jupyter-book versions >= 0.7.0',
book1: {
'notebook1': path.join(path.sep, 'temp', 'SubFolder', 'sample', 'notebook.ipynb'),
'notebook2': path.join(path.sep, 'temp', 'SubFolder', 'sample', 'notebook2.ipynb'),
'notebook3': path.join(path.sep, 'temp', 'SubFolder2', 'sample', 'notebook.ipynb'),
'notInTocNb': path.join(path.sep, 'temp', 'SubFolder', 'sample', 'notInToc.ipynb')
},
book2: {
'notebook1': path.join(path.sep, 'temp2', 'SubFolder', 'sample', 'notebook.ipynb')
},
unknownBook: {
'unknownNotebook': path.join(path.sep, 'randomfolder', 'randomsubfolder', 'randomnotebook.ipynb')
}
}
];
runs.forEach(function (run) {
describe('Trusting in Workspaces ' + run.it, function (): void {
sinon.stub(vscode.workspace, 'getConfiguration').returns(workspaceConfigurtionMock.object); afterEach(function (): void {
sinon.restore();
});
// Mock Book Data beforeEach(() => {
let bookTreeItemFormat1: BookTreeItemFormat = { trustedSubFolders = ['/SubFolder/'];
contentPath: undefined,
root: '/temp/SubFolder/', // Mock Workspace Configuration
tableOfContents: { let workspaceConfigurtionMock: TypeMoq.IMock<vscode.WorkspaceConfiguration> = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
sections: [ workspaceConfigurtionMock.setup(config => config.get(TypeMoq.It.isValue(constants.trustedBooksConfigKey))).returns(() => [].concat(trustedSubFolders));
{ workspaceConfigurtionMock.setup(config => config.update(TypeMoq.It.isValue(constants.trustedBooksConfigKey), TypeMoq.It.isAny(), TypeMoq.It.isValue(false))).returns((key: string, newValues: string[]) => {
url: path.join(path.sep, 'sample', 'notebook') trustedSubFolders.splice(0, trustedSubFolders.length, ...newValues); // Replace
return Promise.resolve();
});
sinon.replaceGetter(vscode.workspace, 'workspaceFolders', () => {
return <vscode.WorkspaceFolder[]>[{
uri: {
fsPath: '/temp/'
},
}, },
{ {
url: path.join(path.sep, 'sample', 'notebook2') uri: {
} fsPath: '/temp2/'
] }
}, },
isUntitled: undefined, ];
page: undefined, });
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookTreeItemFormat2: BookTreeItemFormat = { sinon.stub(vscode.workspace, 'getConfiguration').returns(workspaceConfigurtionMock.object);
contentPath: undefined,
root: '/temp/SubFolder2/',
tableOfContents: {
sections: [
{
url: path.join(path.sep, 'sample', 'notebook')
}
]
},
isUntitled: undefined,
page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookTreeItemFormat3: BookTreeItemFormat = { // Mock Book Data
contentPath: undefined, let bookTreeItemFormat1: BookTreeItemFormat = {
root: '/temp2/SubFolder3/', contentPath: undefined,
tableOfContents: { root: '/temp/SubFolder/',
sections: [ tableOfContents: {
{ sections: [
url: path.join(path.sep, 'sample', 'notebook') {
} url: path.join(path.sep, 'sample', 'notebook')
] },
}, {
isUntitled: undefined, url: path.join(path.sep, 'sample', 'notebook2')
page: undefined, }
title: undefined, ]
treeItemCollapsibleState: undefined, },
type: BookTreeItemType.Book isUntitled: undefined,
}; page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookModel1Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>(); let bookTreeItemFormat2: BookTreeItemFormat = {
bookModel1Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat1, undefined), new BookTreeItem(bookTreeItemFormat2, undefined)]); contentPath: undefined,
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object); root: '/temp/SubFolder2/',
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook2.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object); tableOfContents: {
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object); sections: [
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined); {
url: path.join(path.sep, 'sample', 'notebook')
}
]
},
isUntitled: undefined,
page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookModel2Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>(); let bookTreeItemFormat3: BookTreeItemFormat = {
bookModel2Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat3, undefined)]); contentPath: undefined,
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp2', 'SubFolder', 'content', 'sample', 'notebook.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object); root: '/temp2/SubFolder3/',
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined); tableOfContents: {
sections: [
{
url: path.join(path.sep, 'sample', 'notebook')
}
]
},
isUntitled: undefined,
page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
books = [bookModel1Mock.object, bookModel2Mock.object]; let bookModel1Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>();
bookModel1Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat1, undefined), new BookTreeItem(bookTreeItemFormat2, undefined)]);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book1.notebook1))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book1.notebook2))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book1.notebook3))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined);
bookTrustManager = new BookTrustManager(books); let bookModel2Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>();
}); bookModel2Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat3, undefined)]);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book2.notebook1))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined);
it('should trust notebooks in a trusted book within a workspace', async () => { books = [bookModel1Mock.object, bookModel2Mock.object];
let notebookUri1 = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb');
let notebookUri2 = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook2.ipynb');
let isNotebook1Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri1); bookTrustManager = new BookTrustManager(books);
let isNotebook2Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri2); });
should(isNotebook1Trusted).be.true('Notebook 1 should be trusted'); it('should trust notebooks in a trusted book within a workspace', async () => {
should(isNotebook2Trusted).be.true('Notebook 2 should be trusted'); let notebookUri1 = run.book1.notebook1;
let notebookUri2 = run.book1.notebook2;
}); let isNotebook1Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri1);
let isNotebook2Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri2);
it('should NOT trust a notebook in an untrusted book within a workspace', async () => { should(isNotebook1Trusted).be.true('Notebook 1 should be trusted');
let notebookUri = path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb'); should(isNotebook2Trusted).be.true('Notebook 2 should be trusted');
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri); });
should(isNotebookTrusted).be.false('Notebook should be trusted'); it('should NOT trust a notebook in an untrusted book within a workspace', async () => {
}); let notebookUri = run.book1.notebook3;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
it('should trust notebook after book has been trusted within a workspace', async () => { should(isNotebookTrusted).be.false('Notebook should not be trusted');
let notebookUri = path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb'); });
let isNotebookTrustedBeforeChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrustedBeforeChange).be.false('Notebook should NOT be trusted'); it('should trust notebook after book has been trusted within a workspace', async () => {
let notebookUri = run.book1.notebook3;
let isNotebookTrustedBeforeChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
// add another book subfolder should(isNotebookTrustedBeforeChange).be.false('Notebook should NOT be trusted');
bookTrustManager.setBookAsTrusted('/SubFolder2/');
let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri); // add another book subfolder
bookTrustManager.setBookAsTrusted('/SubFolder2/', true);
should(isNotebookTrustedAfterChange).be.true('Notebook should be trusted'); let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
});
it('should NOT trust a notebook when untrusting a book within a workspace', async () => { should(isNotebookTrustedAfterChange).be.true('Notebook should be trusted');
let notebookUri = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb'); });
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.true('Notebook should be trusted'); it('should NOT trust a notebook when untrusting a book within a workspace', async () => {
let notebookUri = run.book1.notebook1;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
// remove trusted subfolders should(isNotebookTrusted).be.true('Notebook should be trusted');
trustedSubFolders = [];
let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri); // remove trusted subfolders
trustedSubFolders = [];
should(isNotebookTrustedAfterChange).be.false('Notebook should not be trusted after book removal'); let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
});
it('should NOT trust an unknown book within a workspace', async () => { should(isNotebookTrustedAfterChange).be.false('Notebook should not be trusted after book removal');
let notebookUri = path.join(path.sep, 'randomfolder', 'randomsubfolder', 'content', 'randomnotebook.ipynb'); });
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Random notebooks should not be trusted'); it('should NOT trust an unknown book within a workspace', async () => {
}); let notebookUri = run.unknownBook.unknownNotebook;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
it('should NOT trust notebook inside trusted subfolder when absent in table of contents ', async () => { should(isNotebookTrusted).be.false('Random notebooks should not be trusted');
bookTrustManager.setBookAsTrusted('/temp/SubFolder/'); });
let notebookUri = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notInToc.ipynb'); it('should NOT trust notebook inside trusted subfolder when absent in table of contents ', async () => {
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri); bookTrustManager.setBookAsTrusted('/temp/SubFolder/', true);
should(isNotebookTrusted).be.false('Notebook should NOT be trusted'); let notebookUri = run.book1.notInTocNb;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Notebook should NOT be trusted');
});
});
}); });
}); });
describe('TrustingInFolder', () => { describe('TrustingInFolder', () => {
let bookTrustManager: IBookTrustManager; let bookTrustManager: IBookTrustManager;
let books: BookModel[]; let books: BookModel[];
let trustedFolders: string[] = []; let trustedFolders: string[] = [];
beforeEach(() => { let runs = [
// Mock Workspace Configuration {
let workspaceConfigurtionMock: TypeMoq.IMock<vscode.WorkspaceConfiguration> = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>(); it: 'using the jupyter-book legacy version < 0.7.0',
workspaceConfigurtionMock.setup(config => config.get(TypeMoq.It.isValue(constants.trustedBooksConfigKey))).returns(() => [].concat(trustedFolders)); book1: {
workspaceConfigurtionMock.setup(config => config.update(TypeMoq.It.isValue(constants.trustedBooksConfigKey), TypeMoq.It.isAny(), TypeMoq.It.isValue(vscode.ConfigurationTarget.Global))).returns((key: string, newValues: string[], target: vscode.ConfigurationTarget) => { 'notebook1': path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb'),
trustedFolders.splice(0, trustedFolders.length, ...newValues); // Replace 'notebook2': path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook2.ipynb'),
return Promise.resolve(); 'notInTocNb': path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notInToc.ipynb')
},
book2: {
'notebook1': path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb'),
'notebook2': path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook2.ipynb')
},
unknownBook: {
'unknownNotebook': path.join(path.sep, 'randomfolder', 'randomsubfolder', 'content', 'randomnotebook.ipynb')
}
}, {
it: 'using jupyter-book versions >= 0.7.0',
book1: {
'notebook1': path.join(path.sep, 'temp', 'SubFolder', 'sample', 'notebook.ipynb'),
'notebook2': path.join(path.sep, 'temp', 'SubFolder', 'sample', 'notebook2.ipynb'),
'notInTocNb': path.join(path.sep, 'temp', 'SubFolder', 'sample', 'notInToc.ipynb')
},
book2: {
'notebook1': path.join(path.sep, 'temp', 'SubFolder2', 'sample', 'notebook.ipynb'),
'notebook2': path.join(path.sep, 'temp', 'SubFolder2', 'sample', 'notebook2.ipynb')
},
unknownBook: {
'unknownNotebook': path.join(path.sep, 'randomfolder', 'randomsubfolder', 'randomnotebook.ipynb')
}
}
];
runs.forEach(function (run) {
describe('Trusting in Workspaces ' + run.it, function (): void {
beforeEach(() => {
trustedFolders = [];
// Mock Workspace Configuration
let workspaceConfigurtionMock: TypeMoq.IMock<vscode.WorkspaceConfiguration> = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
workspaceConfigurtionMock.setup(config => config.get(TypeMoq.It.isValue(constants.trustedBooksConfigKey))).returns(() => [].concat(trustedFolders));
workspaceConfigurtionMock.setup(config => config.update(TypeMoq.It.isValue(constants.trustedBooksConfigKey), TypeMoq.It.isAny(), TypeMoq.It.isValue(vscode.ConfigurationTarget.Global))).returns((key: string, newValues: string[], target: vscode.ConfigurationTarget) => {
trustedFolders.splice(0, trustedFolders.length, ...newValues); // Replace
return Promise.resolve();
});
let bookTreeItemFormat1: BookTreeItemFormat = {
contentPath: undefined,
root: '/temp/SubFolder/',
tableOfContents: {
sections: [
{
url: path.join(path.sep, 'sample', 'notebook')
},
{
url: path.join(path.sep, 'sample', 'notebook2')
}
]
},
isUntitled: undefined,
page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookTreeItemFormat2: BookTreeItemFormat = {
contentPath: undefined,
root: '/temp/SubFolder2/',
tableOfContents: {
sections: [
{
url: path.join(path.sep, 'sample', 'notebook')
},
{
url: path.join(path.sep, 'sample', 'notebook2')
}
]
},
isUntitled: undefined,
page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookModel1Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>();
bookModel1Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat1, undefined)]);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book1.notebook1))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book1.notebook2))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined);
let bookModel2Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>();
bookModel2Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat2, undefined)]);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book2.notebook1))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(run.book2.notebook2))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined);
books = [bookModel1Mock.object, bookModel2Mock.object];
bookTrustManager = new BookTrustManager(books);
});
it('should trust notebooks in a trusted book in a folder', async () => {
bookTrustManager.setBookAsTrusted('/temp/SubFolder/', true);
let notebookUri1 = run.book1.notebook1;
let notebookUri2 = run.book1.notebook2;
let isNotebook1Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri1);
let isNotebook2Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri2);
should(isNotebook1Trusted).be.true('Notebook 1 should be trusted');
should(isNotebook2Trusted).be.true('Notebook 2 should be trusted');
});
it('should NOT trust a notebook in an untrusted book in a folder', async () => {
//Set book as not trusted before running test
bookTrustManager.setBookAsTrusted('/temp/SubFolder2/', false);
let notebookUri = run.book2.notebook1;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Notebook not should be trusted');
});
it('should trust notebook after book has been added to a folder', async () => {
let notebookUri = run.book2.notebook1;
let isNotebookTrustedBeforeChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrustedBeforeChange).be.false('Notebook should NOT be trusted');
bookTrustManager.setBookAsTrusted('/temp/SubFolder2/', true);
let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrustedAfterChange).be.true('Notebook should be trusted');
});
it('should NOT trust a notebook when removing all books from folders', async () => {
bookTrustManager.setBookAsTrusted('/temp/SubFolder/', true);
bookTrustManager.setBookAsTrusted('/temp/SubFolder2/', true);
let notebookUri = run.book1.notebook1;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
let notebook2Uri = run.book2.notebook1;
let isNotebook2Trusted = bookTrustManager.isNotebookTrustedByDefault(notebook2Uri);
should(isNotebookTrusted).be.true('Notebook should be trusted');
should(isNotebook2Trusted).be.true('Notebook2 should be trusted');
trustedFolders = [];
let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
let isNotebook2TrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebook2Uri);
should(isNotebookTrustedAfterChange).be.false('Notebook should not be trusted after book removal');
should(isNotebook2TrustedAfterChange).be.false('Notebook2 should not be trusted after book removal');
});
it('should NOT trust an unknown book', async () => {
let notebookUri = run.unknownBook.unknownNotebook;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Random notebooks should not be trusted');
});
it('should NOT trust notebook inside trusted subfolder when absent in table of contents ', async () => {
bookTrustManager.setBookAsTrusted('/temp/SubFolder/', true);
let notebookUri = run.book1.notInTocNb;
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Notebook should NOT be trusted');
});
}); });
let bookTreeItemFormat1: BookTreeItemFormat = {
contentPath: undefined,
root: '/temp/SubFolder/',
tableOfContents: {
sections: [
{
url: path.join(path.sep, 'sample', 'notebook')
},
{
url: path.join(path.sep, 'sample', 'notebook2')
}
]
},
isUntitled: undefined,
page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookTreeItemFormat2: BookTreeItemFormat = {
contentPath: undefined,
root: '/temp/SubFolder2/',
tableOfContents: {
sections: [
{
url: path.join(path.sep, 'sample', 'notebook')
},
{
url: path.join(path.sep, 'sample', 'notebook2')
}
]
},
isUntitled: undefined,
page: undefined,
title: undefined,
treeItemCollapsibleState: undefined,
type: BookTreeItemType.Book
};
let bookModel1Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>();
bookModel1Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat1, undefined)]);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook2.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel1Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined);
let bookModel2Mock: TypeMoq.IMock<BookModel> = TypeMoq.Mock.ofType<BookModel>();
bookModel2Mock.setup(model => model.bookItems).returns(() => [new BookTreeItem(bookTreeItemFormat2, undefined)]);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isValue(path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook2.ipynb')))).returns((uri: string) => TypeMoq.Mock.ofType<BookTreeItem>().object);
bookModel2Mock.setup(model => model.getNotebook(TypeMoq.It.isAnyString())).returns((uri: string) => undefined);
books = [bookModel1Mock.object, bookModel2Mock.object];
bookTrustManager = new BookTrustManager(books);
}); });
it('should trust notebooks in a trusted book in a folder', async () => {
bookTrustManager.setBookAsTrusted('/temp/SubFolder/');
let notebookUri1 = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb');
let notebookUri2 = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook2.ipynb');
let isNotebook1Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri1);
let isNotebook2Trusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri2);
should(isNotebook1Trusted).be.true('Notebook 1 should be trusted');
should(isNotebook2Trusted).be.true('Notebook 2 should be trusted');
});
it('should NOT trust a notebook in an untrusted book in a folder', async () => {
let notebookUri = path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb');
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Notebook should be trusted');
});
it('should trust notebook after book has been added to a folder', async () => {
let notebookUri = path.join(path.sep, 'temp', 'SubFolder2', 'content', 'sample', 'notebook.ipynb');
let isNotebookTrustedBeforeChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrustedBeforeChange).be.false('Notebook should NOT be trusted');
bookTrustManager.setBookAsTrusted('/temp/SubFolder2/');
let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrustedAfterChange).be.true('Notebook should be trusted');
});
it('should NOT trust a notebook when untrusting a book in folder', async () => {
bookTrustManager.setBookAsTrusted('/temp/SubFolder/');
let notebookUri = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notebook.ipynb');
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.true('Notebook should be trusted');
trustedFolders = [];
let isNotebookTrustedAfterChange = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrustedAfterChange).be.false('Notebook should not be trusted after book removal');
});
it('should NOT trust an unknown book', async () => {
let notebookUri = path.join(path.sep, 'randomfolder', 'randomsubfolder', 'content', 'randomnotebook.ipynb');
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Random notebooks should not be trusted');
});
it('should NOT trust notebook inside trusted subfolder when absent in table of contents ', async () => {
bookTrustManager.setBookAsTrusted('/temp/SubFolder/');
let notebookUri = path.join(path.sep, 'temp', 'SubFolder', 'content', 'sample', 'notInToc.ipynb');
let isNotebookTrusted = bookTrustManager.isNotebookTrustedByDefault(notebookUri);
should(isNotebookTrusted).be.false('Notebook should NOT be trusted');
});
}); });
}); });