Unescape HTML entities in annotation to avoid showing escaped characters

This commit is contained in:
Hongbo Wu
2023-02-01 12:13:00 +08:00
parent a51eec9489
commit 83c8166b3b
4 changed files with 80 additions and 4 deletions

View File

@ -88,6 +88,7 @@
"ts-loader": "^9.3.0",
"typeorm": "^0.3.4",
"typeorm-naming-strategies": "^4.1.0",
"underscore": "^1.13.6",
"urlsafe-base64": "^1.0.0",
"uuid": "^8.3.1",
"voca": "^1.4.0",

View File

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/no-floating-promises */
import { authorized } from '../../utils/helpers'
import { authorized, unescapeHtml } from '../../utils/helpers'
import {
CreateHighlightError,
CreateHighlightErrorCode,
@ -219,9 +219,14 @@ export const updateHighlightResolver = authorized<
}
}
// unescape HTML entities
const annotation = input.annotation
? unescapeHtml(input.annotation)
: undefined
const updatedHighlight: HighlightData = {
...highlight,
annotation: input.annotation,
annotation,
updatedAt: new Date(),
}

View File

@ -17,6 +17,7 @@ import { updatePage } from '../elastic/pages'
import path from 'path'
import normalizeUrl from 'normalize-url'
import wordsCounter from 'word-counting'
import _ from 'underscore'
interface InputObject {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -283,3 +284,7 @@ export const generateRandomColor = (): string => {
.toUpperCase()
)
}
export const unescapeHtml = (html: string): string => {
return _.unescape(html)
}

View File

@ -12,7 +12,7 @@ import { User } from '../../src/entity/user'
import chaiString from 'chai-string'
import { createPubSubClient } from '../../src/datalayer/pubsub'
import { PageContext } from '../../src/elastic/types'
import { deletePage } from '../../src/elastic/pages'
import { deletePage, updatePage } from '../../src/elastic/pages'
chai.use(chaiString)
@ -101,6 +101,33 @@ const mergeHighlightQuery = (
`
}
const updateHighlightQuery = (
authToken: string,
highlightId: string,
annotation = '_annotation'
) => {
return `
mutation {
updateHighlight(
input: {
annotation: "${annotation}",
highlightId: "${highlightId}",
}
) {
... on UpdateHighlightSuccess {
highlight {
id
annotation
}
}
... on UpdateHighlightError {
errorCodes
}
}
}
`
}
describe('Highlights API', () => {
let authToken: string
let user: User
@ -116,7 +143,7 @@ describe('Highlights API', () => {
authToken = res.body.authToken
pageId = (await createTestElasticPage(user.id)).id
ctx = { pubsub: createPubSubClient(), uid: user.id }
ctx = { pubsub: createPubSubClient(), uid: user.id, refresh: true }
})
after(async () => {
@ -192,4 +219,42 @@ describe('Highlights API', () => {
).to.eq(highlightPositionAnchorIndex)
})
})
describe('updateHighlightMutation', () => {
let highlightId: string
before(async () => {
// create test highlight
highlightId = generateFakeUuid()
await updatePage(
pageId,
{
highlights: [
{
id: highlightId,
shortId: '_short_id_3',
annotation: '',
userId: user.id,
patch: '',
quote: '',
createdAt: new Date(),
updatedAt: new Date(),
},
],
},
ctx
)
})
context('when the annotation has HTML reserved characters', () => {
it('unescapes the annotation and updates', async () => {
const annotation = '> This is a test'
const query = updateHighlightQuery(authToken, highlightId, annotation)
const res = await graphqlRequest(query, authToken).expect(200)
expect(res.body.data.updateHighlight.highlight.annotation).to.eql(
'> This is a test'
)
})
})
})
})