Updated component tests to use best practices and improved syntax
This commit is contained in:
parent
504f088f00
commit
edbf8244df
@ -4,7 +4,7 @@ interface SecondsAgoProps {
|
|||||||
date: string | undefined;
|
date: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SecondsAgo = ({ date }: SecondsAgoProps) => {
|
export const SecondsAgo = ({ date, ...props }: SecondsAgoProps) => {
|
||||||
const [now, setNow] = useState(Date.now());
|
const [now, setNow] = useState(Date.now());
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -18,10 +18,16 @@ export const SecondsAgo = ({ date }: SecondsAgoProps) => {
|
|||||||
return <>Date unknown</>;
|
return <>Date unknown</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`now: ${now}, before: ${new Date(
|
||||||
|
date
|
||||||
|
).getTime()}, date getting passed in: ${date}`
|
||||||
|
);
|
||||||
|
|
||||||
const timeAgoInSeconds = Math.floor((now - new Date(date).getTime()) / 1000);
|
const timeAgoInSeconds = Math.floor((now - new Date(date).getTime()) / 1000);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div {...props}>
|
||||||
{timeAgoInSeconds === 1 ? '1 second' : `${timeAgoInSeconds} seconds`} ago
|
{timeAgoInSeconds === 1 ? '1 second' : `${timeAgoInSeconds} seconds`} ago
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,24 +1,37 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen, act } from '@testing-library/react';
|
||||||
|
|
||||||
import { SecondsAgo } from './index';
|
import { SecondsAgo } from './index';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.useRealTimers();
|
||||||
|
});
|
||||||
|
|
||||||
describe('Seconds ago', () => {
|
describe('Seconds ago', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
const dateInString = Date.now().toString();
|
const dateInString = new Date().toString();
|
||||||
const { baseElement } = render(<SecondsAgo date={dateInString} />);
|
render(<SecondsAgo data-testid="test-seconds-ago" date={dateInString} />);
|
||||||
expect(baseElement).toBeTruthy();
|
|
||||||
|
expect(screen.getByTestId('test-seconds-ago')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show the correct amount of seconds ago', async () => {
|
it('should show the correct amount of seconds ago', (done) => {
|
||||||
const secondsToWait = 2;
|
const secondsToWait = 10;
|
||||||
const dateInString = new Date().toString();
|
const dateInString = new Date().toString();
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, secondsToWait * 1000));
|
act(() => {
|
||||||
|
jest.advanceTimersByTime(secondsToWait * 1000);
|
||||||
|
});
|
||||||
|
|
||||||
render(<SecondsAgo date={dateInString} />);
|
jest.runOnlyPendingTimers();
|
||||||
|
done();
|
||||||
|
|
||||||
expect(
|
render(<SecondsAgo data-testid="test-seconds-ago" date={dateInString} />);
|
||||||
screen.getByText(`${secondsToWait} seconds ago`)
|
|
||||||
).toBeInTheDocument();
|
expect(screen.getByTestId('test-seconds-ago')).toHaveTextContent(
|
||||||
|
`${secondsToWait} seconds ago`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,15 @@ interface StatusMessageProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StatusMessage = ({ children, className }: StatusMessageProps) => {
|
export const StatusMessage = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: StatusMessageProps) => {
|
||||||
const classes = classnames('font-alpha text-h4 mb-28', className);
|
const classes = classnames('font-alpha text-h4 mb-28', className);
|
||||||
return <h3 className={classes}>{children}</h3>;
|
return (
|
||||||
|
<h3 className={classes} {...props}>
|
||||||
|
{children}
|
||||||
|
</h3>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
import { StatusMessage } from './index';
|
import { StatusMessage } from './index';
|
||||||
|
|
||||||
describe('Status message', () => {
|
describe('Status message', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
const { baseElement } = render(<StatusMessage>test</StatusMessage>);
|
render(
|
||||||
expect(baseElement).toBeTruthy();
|
<StatusMessage data-testid="status-message-test">test</StatusMessage>
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('status-message-test')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
import { Table, TableRow, TableHeader, TableCell } from './index';
|
import { Table, TableRow, TableHeader, TableCell } from './index';
|
||||||
|
|
||||||
describe('Renders all table components', () => {
|
describe('Renders all table components', () => {
|
||||||
const { container } = render(
|
render(
|
||||||
<Table data-testid="test-table">
|
<Table data-testid="test-table">
|
||||||
<TableRow data-testid="test-tr">
|
<TableRow data-testid="test-tr">
|
||||||
<TableHeader data-testid="test-th">Title</TableHeader>
|
<TableHeader data-testid="test-th">Title</TableHeader>
|
||||||
@ -12,110 +12,68 @@ describe('Renders all table components', () => {
|
|||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
|
|
||||||
const table = container.querySelector('[data-testid="test-table"]');
|
expect(screen.getByTestId('test-table')).toBeInTheDocument();
|
||||||
const tr = container.querySelector('[data-testid="test-tr"]');
|
expect(screen.getByTestId('test-tr')).toBeInTheDocument();
|
||||||
const th = container.querySelector('[data-testid="test-th"]');
|
expect(screen.getByTestId('test-th')).toHaveTextContent('Title');
|
||||||
const td = container.querySelector('[data-testid="test-td"]');
|
expect(screen.getByTestId('test-td')).toHaveTextContent('Content');
|
||||||
|
|
||||||
expect(table).toBeInTheDocument();
|
|
||||||
expect(th).toBeInTheDocument();
|
|
||||||
expect(tr).toBeInTheDocument();
|
|
||||||
expect(td).toBeInTheDocument();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Table row', () => {
|
describe('Table row', () => {
|
||||||
it('should include classes based on custom "modifier" prop', () => {
|
it('should include classes based on custom "modifier" prop', () => {
|
||||||
const { baseElement: withoutModifier } = render(
|
render(
|
||||||
<Table>
|
<Table>
|
||||||
<TableRow>
|
<TableRow data-testid="modifier-test" modifier="bordered">
|
||||||
<TableCell>Without modifier</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</Table>
|
|
||||||
);
|
|
||||||
|
|
||||||
const { baseElement: withModifier } = render(
|
|
||||||
<Table>
|
|
||||||
<TableRow modifier="bordered">
|
|
||||||
<TableCell>With modifier</TableCell>
|
<TableCell>With modifier</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
|
|
||||||
const noModifierTr = withoutModifier.querySelector('tr');
|
expect(screen.getByTestId('modifier-test')).toHaveClass('border-white-40');
|
||||||
const modifierTr = withModifier.querySelector('tr');
|
|
||||||
const classNameToCheck = 'border-white-40';
|
|
||||||
|
|
||||||
expect(noModifierTr && !noModifierTr.classList.contains(classNameToCheck));
|
|
||||||
expect(modifierTr && modifierTr.classList.contains(classNameToCheck));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Table header', () => {
|
describe('Table header', () => {
|
||||||
it('should accept props i.e. scope="row"', () => {
|
it('should accept props i.e. scope="row"', () => {
|
||||||
const { baseElement } = render(
|
render(
|
||||||
<Table>
|
<Table>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHeader scope="row">Test</TableHeader>
|
<TableHeader data-testid="props-test" scope="row">
|
||||||
|
Test
|
||||||
|
</TableHeader>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
|
|
||||||
const th = baseElement.querySelector('th');
|
expect(screen.getByTestId('props-test')).toHaveAttribute('scope');
|
||||||
|
|
||||||
expect(th && th.hasAttribute('scope'));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include custom class based on scope="row"', () => {
|
it('should include custom class based on scope="row"', () => {
|
||||||
const { baseElement: withoutScope } = render(
|
render(
|
||||||
<Table>
|
<Table>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHeader>Without scope attribute</TableHeader>
|
<TableHeader data-testid="scope-class-test" scope="row">
|
||||||
|
With scope attribute
|
||||||
|
</TableHeader>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
|
|
||||||
const { baseElement: withScope } = render(
|
expect(screen.getByTestId('scope-class-test')).toHaveClass('text-left');
|
||||||
<Table>
|
|
||||||
<TableRow>
|
|
||||||
<TableHeader scope="row">With scope attribute</TableHeader>
|
|
||||||
</TableRow>
|
|
||||||
</Table>
|
|
||||||
);
|
|
||||||
|
|
||||||
const withoutScopeTr = withoutScope.querySelector('tr');
|
|
||||||
const withScopeTr = withScope.querySelector('tr');
|
|
||||||
const classNameToCheck = 'text-left';
|
|
||||||
|
|
||||||
expect(
|
|
||||||
withoutScopeTr && !withoutScopeTr.classList.contains(classNameToCheck)
|
|
||||||
);
|
|
||||||
expect(withScopeTr && withScopeTr.classList.contains(classNameToCheck));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Table cell', () => {
|
describe('Table cell', () => {
|
||||||
it('should include class based on custom "modifier" prop', () => {
|
it('should include class based on custom "modifier" prop', () => {
|
||||||
const { baseElement: withoutModifier } = render(
|
render(
|
||||||
<Table>
|
<Table>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>Without modifier</TableCell>
|
<TableCell data-testid="modifier-class-test" modifier="bordered">
|
||||||
|
With modifier
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</Table>
|
</Table>
|
||||||
);
|
);
|
||||||
|
|
||||||
const { baseElement: withModifier } = render(
|
expect(screen.getByTestId('modifier-class-test')).toHaveClass('py-4');
|
||||||
<Table>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell modifier="bordered">With modifier</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</Table>
|
|
||||||
);
|
|
||||||
|
|
||||||
const noModifierTd = withoutModifier.querySelector('td');
|
|
||||||
const modifierTd = withModifier.querySelector('td');
|
|
||||||
const classNameToCheck = 'py-4';
|
|
||||||
|
|
||||||
expect(noModifierTd && !noModifierTd.classList.contains(classNameToCheck));
|
|
||||||
expect(modifierTd && modifierTd.classList.contains(classNameToCheck));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -3,11 +3,11 @@ import { TruncateInline } from './truncate';
|
|||||||
|
|
||||||
describe('Truncate', () => {
|
describe('Truncate', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
const { baseElement } = render(
|
render(
|
||||||
<TruncateInline text={'Texty McTextFace'} />
|
<TruncateInline data-testid="truncate-test" text={'Texty McTextFace'} />
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(baseElement).toBeTruthy();
|
expect(screen.getByTestId('truncate-test')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it truncates as expected', () => {
|
it('it truncates as expected', () => {
|
||||||
|
@ -22,6 +22,7 @@ export function TruncateInline({
|
|||||||
children,
|
children,
|
||||||
startChars,
|
startChars,
|
||||||
endChars,
|
endChars,
|
||||||
|
...props
|
||||||
}: TruncateInlineProps) {
|
}: TruncateInlineProps) {
|
||||||
if (text === null) {
|
if (text === null) {
|
||||||
return <span data-testid="empty-truncation" />;
|
return <span data-testid="empty-truncation" />;
|
||||||
@ -31,6 +32,7 @@ export function TruncateInline({
|
|||||||
const wrapperProps = {
|
const wrapperProps = {
|
||||||
title: text,
|
title: text,
|
||||||
className,
|
className,
|
||||||
|
...props,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (children !== undefined) {
|
if (children !== undefined) {
|
||||||
|
Loading…
Reference in New Issue
Block a user