Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

56 changes: 28 additions & 28 deletions client/src/components/HtmlReadonlyField/HtmlReadonlyField.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
import React, { Component } from 'react';
import React from 'react';
import fieldHolder from 'components/FieldHolder/FieldHolder';
import { Input } from 'reactstrap';
import PropTypes from 'prop-types';

class HtmlReadonlyField extends Component {
const HtmlReadonlyField = (_props) => {
const defaultProps = {
// React considers "undefined" as an uncontrolled component.
extraClass: '',
className: '',
};
const props = {
...defaultProps,
..._props,
};

/**
* Fetches the properties for the text field
*
* @returns {object} properties
*/
getInputProps() {
return {
// The extraClass property is defined on both the holder and element
// for legacy reasons (same behaviour as PHP rendering)
className: `${this.props.className} ${this.props.extraClass}`,
id: this.props.id,
name: this.props.name,
};
}
const getInputProps = () => ({
// The extraClass property is defined on both the holder and element
// for legacy reasons (same behaviour as PHP rendering)
className: `${props.className} ${props.extraClass}`,
id: props.id,
name: props.name,
});

render() {
return (
<Input
plaintext
tag="p"
dangerouslySetInnerHTML={{ __html: this.props.value }}
{...this.getInputProps()}
/>
);
}
}
return (
<Input
plaintext
tag="p"
dangerouslySetInnerHTML={{ __html: props.value }}
{...getInputProps()}
/>
);
};

HtmlReadonlyField.propTypes = {
id: PropTypes.string,
Expand All @@ -38,12 +44,6 @@ HtmlReadonlyField.propTypes = {
value: PropTypes.string,
};

HtmlReadonlyField.defaultProps = {
// React considers "undefined" as an uncontrolled component.
extraClass: '',
className: '',
};

export { HtmlReadonlyField as Component };

export default fieldHolder(HtmlReadonlyField);
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* global jest, test, expect */

import React from 'react';
import { render } from '@testing-library/react';
import WrappedHtmlReadonlyField, { Component as HtmlReadonlyField } from '../HtmlReadonlyField';

function makeProps(obj = {}) {
return {
id: 'my-id',
name: 'MyName',
extraClass: '',
className: '',
value: '<b>Hello</b>',
...obj
};
}

test('HtmlReadonlyField renders without errors with minimal props', () => {
const { container } = render(<HtmlReadonlyField {...makeProps()} />);
expect(container.querySelectorAll('p')).toHaveLength(1);
});

test('HtmlReadonlyField renders a p tag with plaintext class', () => {
const { container } = render(<HtmlReadonlyField {...makeProps()} />);
const p = container.querySelector('p');
expect(p).not.toBeNull();
expect(p.classList.contains('form-control-plaintext')).toBe(true);
});

test('HtmlReadonlyField renders the value as inner HTML', () => {
const { container } = render(
<HtmlReadonlyField {...makeProps({ value: '<em>Test</em>' })} />
);
const p = container.querySelector('p');
expect(p.innerHTML).toBe('<em>Test</em>');
});

test('HtmlReadonlyField applies id to the element', () => {
const { container } = render(
<HtmlReadonlyField {...makeProps({ id: 'field-123' })} />
);
const p = container.querySelector('p');
expect(p.getAttribute('id')).toBe('field-123');
});

test('HtmlReadonlyField applies name to the element', () => {
const { container } = render(
<HtmlReadonlyField {...makeProps({ name: 'FieldName' })} />
);
const p = container.querySelector('p');
expect(p.getAttribute('name')).toBe('FieldName');
});

test('HtmlReadonlyField applies className and extraClass to the element', () => {
const { container } = render(
<HtmlReadonlyField {...makeProps({ className: 'foo', extraClass: 'bar' })} />
);
const p = container.querySelector('p');
expect(p.classList.contains('foo')).toBe(true);
expect(p.classList.contains('bar')).toBe(true);
});

test('HtmlReadonlyField renders with empty value', () => {
const { container } = render(
<HtmlReadonlyField {...makeProps({ value: '' })} />
);
const p = container.querySelector('p');
expect(p).not.toBeNull();
expect(p.innerHTML).toBe('');
});

test('HtmlReadonlyField renders with undefined value', () => {
const { container } = render(
<HtmlReadonlyField {...makeProps({ value: undefined })} />
);
expect(container.querySelectorAll('p')).toHaveLength(1);
});

test('HtmlReadonlyField default export is wrapped with fieldHolder', () => {
expect(typeof WrappedHtmlReadonlyField).toBe('function');
});
Loading
Loading