[single-article] Refactor class components to be functional component (#17681)

* refactor(single-article): migrates class to use pure components

* test(single-article): removes repeated test from file
This commit is contained in:
Viviane Dias 2022-05-26 08:59:06 -03:00 committed by GitHub
parent 0960b36d92
commit 94c431afb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 95 deletions

View file

@ -1,8 +1,8 @@
/* eslint-disable jest/expect-expect */
import { h, Fragment } from 'preact';
import { axe } from 'jest-axe';
import { render, getNodeText, waitFor } from '@testing-library/preact';
import { SingleArticle } from '../index';
import '@testing-library/jest-dom';
const getTestArticle = () => ({
id: 1,
@ -39,9 +39,10 @@ describe('<SingleArticle />', () => {
});
it('renders the article title', () => {
const { queryByText } = render(
const articleProps = getTestArticle();
const { getByRole } = render(
<Fragment>
<SingleArticle {...getTestArticle()} toggleArticle={jest.fn()} />
<SingleArticle {...articleProps} toggleArticle={jest.fn()} />
<div
data-testid="flag-user-modal"
class="flag-user-modal-container hidden"
@ -49,27 +50,13 @@ describe('<SingleArticle />', () => {
</Fragment>,
);
expect(queryByText(getTestArticle().title)).toBeDefined();
});
it('renders the new clickable article title', () => {
const { container } = render(
<Fragment>
<SingleArticle {...getTestArticle()} toggleArticle={jest.fn()} />
<div
data-testid="flag-user-modal"
class="flag-user-modal-container hidden"
/>
</Fragment>,
);
const text = getNodeText(
container.getElementsByClassName('article-title-heading')[0],
);
expect(text).toContain(getTestArticle().title);
expect(
getByRole('heading', { name: articleProps.title, level: 3 }),
).toBeInTheDocument();
});
it('renders the tags', () => {
const { queryByText } = render(
const { getByText } = render(
<Fragment>
<SingleArticle {...getTestArticle()} toggleArticle={jest.fn()} />
<div
@ -79,9 +66,9 @@ describe('<SingleArticle />', () => {
</Fragment>,
);
expect(queryByText('discuss')).toBeDefined();
expect(queryByText('javascript')).toBeDefined();
expect(queryByText('beginners')).toBeDefined();
expect(getByText('discuss')).toBeInTheDocument();
expect(getByText('javascript')).toBeInTheDocument();
expect(getByText('beginners')).toBeInTheDocument();
});
it('renders no tags or # symbol when article has no tags', () => {
@ -145,7 +132,7 @@ describe('<SingleArticle />', () => {
});
it('renders the correct formatted published date', () => {
const { queryByText } = render(
const { getByText } = render(
<Fragment>
<SingleArticle {...getTestArticle()} toggleArticle={jest.fn()} />
<div
@ -155,7 +142,7 @@ describe('<SingleArticle />', () => {
</Fragment>,
);
expect(queryByText('Jun 22')).toBeDefined();
expect(getByText('Jun 22')).toBeInTheDocument();
});
it('renders the correct formatted published date as a time if the date is the same day', () => {

View file

@ -1,17 +1,23 @@
import PropTypes from 'prop-types';
import { h, Component, Fragment } from 'preact';
import { h, Fragment } from 'preact';
import { createPortal } from 'preact/compat';
import { FlagUserModal } from '../../packs/flagUserModal';
import { formatDate } from './util';
export class SingleArticle extends Component {
activateToggle = () => {
const { id, title, path, toggleArticle } = this.props;
export const SingleArticle = ({
id,
title,
publishedAt,
cachedTagList,
user,
key,
articleOpened,
path,
toggleArticle,
}) => {
const activateToggle = () => toggleArticle(id, title, path);
toggleArticle(id, title, path);
};
tagsFormat = (tag, key) => {
const tagsFormat = (tag, key) => {
if (tag) {
return (
<span className="crayons-tag" key={key}>
@ -22,69 +28,55 @@ export class SingleArticle extends Component {
}
};
render() {
const {
id,
title,
publishedAt,
cachedTagList,
user,
key,
articleOpened,
path,
} = this.props;
const tags = cachedTagList.split(', ').map((tag) => {
this.tagsFormat(tag, key);
});
const tags = cachedTagList.split(', ').map((tag) => tagsFormat(tag, key));
const newAuthorNotification = user.articles_count <= 3 ? '👋 ' : '';
const modContainer = id
? document.getElementById(`mod-iframe-${id}`)
: document.getElementById('mod-container');
const newAuthorNotification = user.articles_count <= 3 ? '👋 ' : '';
const modContainer = id
? document.getElementById(`mod-iframe-${id}`)
: document.getElementById('mod-container');
return (
<Fragment>
{modContainer &&
createPortal(
<FlagUserModal moderationUrl={path} authorId={user.id} />,
document.getElementsByClassName('flag-user-modal-container')[0],
)}
<details
id={`mod-article-${id}`}
data-testid={`mod-article-${id}`}
className="moderation-single-article"
onToggle={this.activateToggle}
>
<summary>
<div className="article-details-container">
<span className="article-title">
<header>
<h3 className="fs-base fw-bold lh-tight article-title-heading">
{title}
</h3>
</header>
{tags}
</span>
<span className="article-author">
{newAuthorNotification}
{user.name}
</span>
<span className="article-published-at">
<time dateTime={publishedAt}>{formatDate(publishedAt)}</time>
</span>
</div>
</summary>
<div
className={`article-iframes-container${
articleOpened ? ' opened' : ''
}`}
id={`article-iframe-${id}`}
/>
</details>
</Fragment>
);
}
}
return (
<Fragment>
{modContainer &&
createPortal(
<FlagUserModal moderationUrl={path} authorId={user.id} />,
document.getElementsByClassName('flag-user-modal-container')[0],
)}
<details
id={`mod-article-${id}`}
data-testid={`mod-article-${id}`}
className="moderation-single-article"
onToggle={activateToggle}
>
<summary>
<div className="article-details-container">
<span className="article-title">
<header>
<h3 className="fs-base fw-bold lh-tight article-title-heading">
{title}
</h3>
</header>
{tags}
</span>
<span className="article-author">
{newAuthorNotification}
{user.name}
</span>
<span className="article-published-at">
<time dateTime={publishedAt}>{formatDate(publishedAt)}</time>
</span>
</div>
</summary>
<div
className={`article-iframes-container${
articleOpened ? ' opened' : ''
}`}
id={`article-iframe-${id}`}
/>
</details>
</Fragment>
);
};
SingleArticle.propTypes = {
id: PropTypes.number.isRequired,