mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
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:
@@ -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) {
|
||||||
|
|||||||
@@ -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[] {
|
||||||
|
|||||||
@@ -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');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user