Skip to content

Commit

Permalink
feat(tooltip): add unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
adenvt committed Oct 27, 2022
1 parent b7c3eab commit d6dfed3
Show file tree
Hide file tree
Showing 9 changed files with 757 additions and 29 deletions.
2 changes: 2 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
defaults and supports es6-module
maintained node versions
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"@rushstack/eslint-patch": "1.2.0",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/vue": "6.6.0",
"@types/dompurify": "^2",
"@types/lodash-es": "4.17.6",
"@types/marked": "^4",
"@types/testing-library__jest-dom": "5.14.5",
Expand Down Expand Up @@ -71,9 +70,9 @@
"chart.js": "3.9.1",
"date-fns": "2.29.3",
"defu": "6.1.0",
"dompurify": "^2.4.0",
"fuse.js": "6.6.2",
"interactjs": "1.10.17",
"isomorphic-dompurify": "^0.23.0",
"lodash-es": "4.17.21",
"marked": "^4.1.1",
"p-queue": "^7.3.0",
Expand Down
102 changes: 102 additions & 0 deletions src/components/markdown/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { render } from '@testing-library/vue'
import {
markdown,
pMd,
vPMd,
} from '.'

describe('markdown', () => {
it('should able render markdown', () => {
const result = markdown('**Hello** _world_')

expect(result).toBe('<p><strong>Hello</strong> <em>world</em></p>\n')
})

it('should sanitize result by default', () => {
const result = markdown("123<a href='javascript:alert(1)'>I am a dolphin!</a>")

expect(result).toBe('<p>123<a>I am a dolphin!</a></p>\n')
})

it('should render inline when options.inline set to true', () => {
const result = markdown('**Hello** _world_', { inline: true })

expect(result).toBe('<strong>Hello</strong> <em>world</em>')
})

it('should not sanitize when options.unsecure set to true', () => {
const result = markdown("123<a href='javascript:alert(1)'>I am a dolphin!</a>", { unsecure: true })

expect(result).toBe("<p>123<a href='javascript:alert(1)'>I am a dolphin!</a></p>\n")
})
})

describe('v-p-md', () => {
it('should able render markdown', () => {
const screen = render({
directives: { pMd },
template : `
<div
data-testid="sample"
v-p-md="'**Hello** _world_'"
/>
`,
})

const sample = screen.getByTestId('sample')

expect(sample.innerHTML).toBe('<p><strong>Hello</strong> <em>world</em></p>\n')
})

it('should sanitize result by default', () => {
const screen = render({
directives: { pMd },
template : `
<div
data-testid="sample"
v-p-md="'123<a href=\\'javascript:alert(1)\\'>I am a dolphin!</a>'"
/>
`,
})

const sample = screen.getByTestId('sample')

expect(sample.innerHTML).toBe('<p>123<a>I am a dolphin!</a></p>\n')
})

it('should render inline when add modifiers `inline`', () => {
const screen = render({
directives: { pMd },
template : `
<div
data-testid="sample"
v-p-md.inline="'**Hello** _world_'"
/>
`,
})

const sample = screen.getByTestId('sample')

expect(sample.innerHTML).toBe('<strong>Hello</strong> <em>world</em>')
})

it('should not sanitize when add modifiers `unsecure`', () => {
const screen = render({
directives: { pMd },
template : `
<div
data-testid="sample"
v-p-md.unsecure="'123<a href=\\'javascript:alert(1)\\'>I am a dolphin!</a>'"
/>
`,
})

const sample = screen.getByTestId('sample')

expect(sample.innerHTML).toBe('<p>123<a href="javascript:alert(1)">I am a dolphin!</a></p>\n')
})

it('should export alias vPMd', () => {
expect(pMd).toBe(vPMd)
})
})
32 changes: 27 additions & 5 deletions src/components/markdown/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
import { Directive } from 'vue-demi'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
import { sanitize } from 'isomorphic-dompurify'

export function markdown (text: string, { inline = false, sanitize = true }) {
const html = inline
export interface MarkdownOption {
/**
* Use inline parsing
* @default false
* @link https://marked.js.org/using_advanced#inline
*/
inline: boolean,
/**
* Disabled sanitize HTML result
* @default false
*/
unsecure: boolean,
}

/**
* Parse markdown to html string
* @param text markdown string
* @param options parsing options
*/
export function markdown (text: string = '', options: Partial<MarkdownOption> = {}) {
const html = options.inline
? marked.parseInline(text)
: marked.parse(text)

return sanitize ? DOMPurify.sanitize(html) : html
if (html && !options.unsecure)
return sanitize(html)

return html ?? ''
}

export const pMd: Directive<HTMLElement, string> = (el, { value, modifiers }) => {
el.innerHTML = markdown(value, {
inline : modifiers.inline,
sanitize: !modifiers.unsecure,
unsecure: modifiers.unsecure,
})
}

Expand Down
Loading

0 comments on commit d6dfed3

Please sign in to comment.