The Node.js® Website
1import { render, screen } from '@testing-library/react';
2
3import BlogPostCard from '@/components/Common/BlogPostCard';
4
5function renderBlogPostCard({
6 title = 'Blog post title',
7 type = 'vulnerability',
8 description = 'Blog post description',
9 authors = [],
10 date = new Date(),
11 slug = '',
12}) {
13 render(
14 <BlogPostCard
15 title={title}
16 category={type}
17 description={description}
18 authors={authors}
19 date={date}
20 slug={slug}
21 />
22 );
23
24 return { title, type, description, authors, date };
25}
26
27describe('BlogPostCard', () => {
28 describe('Rendering', () => {
29 it('Wraps the entire card within an article', () => {
30 renderBlogPostCard({});
31
32 expect(screen.getByRole('article')).toBeVisible();
33 });
34
35 it('Renders the title prop correctly', () => {
36 const { title } = renderBlogPostCard({});
37
38 expect(screen.getAllByText(title).length).toBe(2);
39
40 // title from preview should be ignored as the one from Links
41 // and blog card/post are what matter
42 expect(screen.getAllByText(title)[0]).toHaveAttribute(
43 'aria-hidden',
44 'true'
45 );
46 });
47
48 it('Renders the description prop correctly', () => {
49 const { description } = renderBlogPostCard({});
50
51 expect(screen.getByText(description)).toBeVisible();
52 });
53
54 it.each([
55 { label: 'layouts.blog.categories.vulnerability', type: 'vulnerability' },
56 { label: 'layouts.blog.categories.announcements', type: 'announcements' },
57 { label: 'layouts.blog.categories.release', type: 'release' },
58 ])(
59 'Renders "%label" text when passing it the type "%type"',
60 ({ label, type }) => {
61 renderBlogPostCard({ type });
62
63 expect(screen.getByText(label)).toBeVisible();
64 }
65 );
66
67 it('Renders all passed authors fullName(s), comma-separated', () => {
68 const authors = [
69 { fullName: 'Jane Doe', src: '' },
70 { fullName: 'John Doe', src: '' },
71 ];
72
73 renderBlogPostCard({ authors });
74
75 const fullNames = authors.reduce((prev, curr, index) => {
76 if (index === 0) {
77 return curr.fullName;
78 }
79
80 return `${prev}, ${curr.fullName}`;
81 }, '');
82
83 expect(screen.getByText(fullNames)).toBeVisible();
84 });
85
86 it('Renders all passed authors fullName(s), comma-separated', () => {
87 const authors = [
88 { fullName: 'Jane Doe', src: '' },
89 { fullName: 'John Doe', src: '' },
90 ];
91
92 renderBlogPostCard({ authors });
93
94 const fullNames = authors.reduce((prev, curr, index) => {
95 if (index === 0) {
96 return curr.fullName;
97 }
98
99 return `${prev}, ${curr.fullName}`;
100 }, '');
101
102 expect(screen.getByText(fullNames)).toBeVisible();
103 });
104
105 it('Renders date prop in short format', () => {
106 const date = new Date();
107
108 renderBlogPostCard({ date });
109
110 const dateTimeFormat = new Intl.DateTimeFormat('en-US', {
111 day: '2-digit',
112 month: 'short',
113 year: 'numeric',
114 });
115
116 expect(screen.getByText(dateTimeFormat.format(date))).toBeVisible();
117 });
118 });
119});