Deal with HTML entities when editing a collection (#4447)

This commit is contained in:
Kumar McMillan 2018-02-26 11:43:58 -06:00 коммит произвёл GitHub
Родитель 2bff1f7e8f
Коммит 4ac75f44e8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 47 добавлений и 3 удалений

Просмотреть файл

@ -167,6 +167,7 @@
"full-icu": "1.2.0",
"helmet": "3.11.0",
"hot-shots": "5.0.1",
"html-entities": "1.2.1",
"humps": "2.0.1",
"isomorphic-fetch": "2.2.1",
"jed": "1.1.1",

Просмотреть файл

@ -7,6 +7,7 @@ import config from 'config';
import { updateCollection } from 'amo/reducers/collections';
import { withFixedErrorHandler } from 'core/errorHandler';
import translate from 'core/i18n/translate';
import { decodeHtmlEntities } from 'core/utils';
import FormOverlay from 'ui/components/FormOverlay';
import type { CollectionType } from 'amo/reducers/collections';
import type { ApiStateType } from 'core/reducers/api';
@ -107,9 +108,11 @@ export class CollectionManagerBase extends React.Component<Props, State> {
}
propsToState(props: Props) {
// Decode HTML entities so the user sees real symbols in the form.
return {
description: props.collection && props.collection.description,
name: props.collection && props.collection.name,
description: props.collection &&
decodeHtmlEntities(props.collection.description),
name: props.collection && decodeHtmlEntities(props.collection.name),
slug: props.collection && props.collection.slug,
};
}

Просмотреть файл

@ -1,6 +1,7 @@
/* eslint-disable react/prop-types */
import url from 'url';
import { AllHtmlEntities } from 'html-entities';
import config from 'config';
import * as React from 'react';
@ -299,3 +300,11 @@ export function addonHasVersionHistory(addon) {
ADDON_TYPE_THEME,
].includes(addon.type);
}
/*
* Decodes HTML entities into their respective symbols.
*/
export const decodeHtmlEntities = (string) => {
const entities = new AllHtmlEntities();
return entities.decode(string);
};

Просмотреть файл

@ -8,6 +8,7 @@ import {
} from 'amo/reducers/collections';
import { setLang } from 'core/actions';
import { setErrorMessage } from 'core/actions/errors';
import { decodeHtmlEntities } from 'core/utils';
import {
createFakeEvent,
createStubErrorHandler,
@ -95,6 +96,24 @@ describe(__filename, () => {
.toHaveProp('value', collection.slug);
});
it('strips HTML entities from name and description', () => {
const collection = createInternalCollection({
detail: createFakeCollectionDetail({
// This is how the API returns data.
name: 'Things &amp; Stuff',
description: 'Extensions about things &amp; stuff',
}),
});
const root = render({ collection });
const { description, name } = collection;
expect(root.find('#collectionName'))
.toHaveProp('value', decodeHtmlEntities(name));
expect(root.find('#collectionDescription'))
.toHaveProp('defaultValue', decodeHtmlEntities(description));
});
it('does not populate form when updating to the same collection', () => {
const firstCollection = createInternalCollection({
detail: createFakeCollectionDetail({

Просмотреть файл

@ -42,6 +42,7 @@ import {
safePromise,
sanitizeHTML,
sanitizeUserHTML,
decodeHtmlEntities,
visibleAddonType,
trimAndAddProtocolToUrl,
} from 'core/utils';
@ -700,4 +701,15 @@ describe(__filename, () => {
});
});
});
describe('decodeHtmlEntities', () => {
it('decodes entities', () => {
expect(decodeHtmlEntities('&lt;&gt;&quot;&amp;&copy;&reg;'))
.toEqual('<>"&©®');
});
it('passes through anything else', () => {
expect(decodeHtmlEntities('just whatever')).toEqual('just whatever');
});
});
});

Просмотреть файл

@ -4176,7 +4176,7 @@ html-encoding-sniffer@^1.0.2:
dependencies:
whatwg-encoding "^1.0.1"
html-entities@^1.2.0:
html-entities@1.2.1, html-entities@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"