From ab09263c52518f9acd949e4f28de20ec24d2e03c Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Tue, 12 Sep 2023 10:41:50 -0700 Subject: [PATCH] linkify tests --- extensions/notebook-renderers/src/linkify.ts | 22 +++++++--- .../src/test/linkify.test.ts | 44 +++++++++++++++++++ .../src/test/notebookRenderer.test.ts | 2 + 3 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 extensions/notebook-renderers/src/test/linkify.test.ts diff --git a/extensions/notebook-renderers/src/linkify.ts b/extensions/notebook-renderers/src/linkify.ts index 9d2ea0f211a..49fdc4edf8c 100644 --- a/extensions/notebook-renderers/src/linkify.ts +++ b/extensions/notebook-renderers/src/linkify.ts @@ -27,9 +27,21 @@ type LinkPart = { }; export class LinkDetector { - constructor( - ) { - // noop + + // used by unit tests + static injectedHtmlCreator: (value: string) => string; + + private shouldGenerateHtml(trustHtml: boolean) { + return trustHtml && (!!LinkDetector.injectedHtmlCreator || !!ttPolicy); + } + + private createHtml(value: string) { + if (LinkDetector.injectedHtmlCreator) { + return LinkDetector.injectedHtmlCreator(value); + } + else { + return ttPolicy?.createHTML(value).toString(); + } } /** @@ -71,9 +83,9 @@ export class LinkDetector { container.appendChild(this.createWebLink(part.value)); break; case 'html': - if (ttPolicy && trustHtml) { + if (this.shouldGenerateHtml(!!trustHtml)) { const span = document.createElement('span'); - span.innerHTML = ttPolicy.createHTML(part.value).toString(); + span.innerHTML = this.createHtml(part.value)!; container.appendChild(span); } else { container.appendChild(document.createTextNode(part.value)); diff --git a/extensions/notebook-renderers/src/test/linkify.test.ts b/extensions/notebook-renderers/src/test/linkify.test.ts new file mode 100644 index 00000000000..7ee5487a84b --- /dev/null +++ b/extensions/notebook-renderers/src/test/linkify.test.ts @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { JSDOM } from "jsdom"; +import { LinkDetector, linkify } from '../linkify'; + +const dom = new JSDOM(); +global.document = dom.window.document; + +suite('Notebook builtin output link detection', () => { + + LinkDetector.injectedHtmlCreator = (value: string) => value; + + test('no links', () => { + const htmlWithLinks = linkify('hello', true, undefined, true); + assert.equal(htmlWithLinks.innerHTML, 'hello'); + }); + + test('web link detection', () => { + const htmlWithLinks = linkify('something www.example.com something', true, undefined, true); + + assert.equal(htmlWithLinks.innerHTML, 'something www.example.com something'); + assert.equal(htmlWithLinks.textContent, 'something www.example.com something'); + }); + + test('html link detection', () => { + const htmlWithLinks = linkify('something link something', true, undefined, true); + + assert.equal(htmlWithLinks.innerHTML, 'something link something'); + assert.equal(htmlWithLinks.textContent, 'something link something'); + }); + + test('html link without trust', () => { + const trustHtml = false; + const htmlWithLinks = linkify('something link something', true, undefined, trustHtml); + + assert.equal(htmlWithLinks.innerHTML, 'something <a href="file.py">link</a> something'); + assert.equal(htmlWithLinks.textContent, 'something link something'); + }); +}); + diff --git a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts index 5c24b4f494a..7c92a5a01f4 100644 --- a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts +++ b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts @@ -8,6 +8,7 @@ import { activate } from '..'; import { RendererApi } from 'vscode-notebook-renderer'; import { IDisposable, IRichRenderContext, OutputWithAppend, RenderOptions } from '../rendererTypes'; import { JSDOM } from "jsdom"; +import { LinkDetector } from '../linkify'; const dom = new JSDOM(); global.document = dom.window.document; @@ -273,6 +274,7 @@ suite('Notebook builtin output renderer', () => { }); test(`Render with wordwrap and scrolling for error output`, async () => { + LinkDetector.injectedHtmlCreator = (value: string) => value; const context = createContext({ outputWordWrap: true, outputScrolling: true }); const renderer = await activate(context); assert.ok(renderer, 'Renderer not created');