Skip to content

Commit 4a84d2d

Browse files
Merge branch 'nodejs:main' into main
2 parents 3e48178 + 280c12b commit 4a84d2d

42 files changed

Lines changed: 1476 additions & 945 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.postcssrc.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"plugins": {
3+
"postcss-mixins": {},
4+
"postcss-simple-vars": {},
5+
"postcss-calc": {},
6+
"postcss-import": {},
7+
"tailwindcss/nesting": {},
8+
"tailwindcss": {},
9+
"autoprefixer": {}
10+
}
11+
}

COLLABORATOR_GUIDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ They also allow Developers to preview Components and be able to test them manual
287287

288288
```tsx
289289
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
290-
import NameOfComponent from './index';
290+
import NameOfComponent from '@components/PathTo/YourComponent';
291291

292292
type Story = StoryObj<typeof NameOfComponent>;
293293
type Meta = MetaObj<typeof NameOfComponent>;

components/Common/AvatarGroup/Avatar/index.module.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@
1818

1919
.avatarRoot {
2020
@apply -ml-2
21+
h-8
22+
w-8
23+
flex-shrink-0
2124
first:ml-0;
2225
}

components/Common/AvatarGroup/Avatar/index.stories.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
22

3+
import Avatar from '@/components/Common/AvatarGroup/Avatar';
34
import { githubProfileAvatarUrl } from '@/util/gitHubUtils';
45

5-
import Avatar from './';
6-
76
type Story = StoryObj<typeof Avatar>;
87
type Meta = MetaObj<typeof Avatar>;
98

components/Common/AvatarGroup/index.stories.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
22

3+
import AvatarGroup from '@/components/Common/AvatarGroup';
34
import { githubProfileAvatarUrl } from '@/util/gitHubUtils';
45

5-
import AvatarGroup from './';
6-
76
type Story = StoryObj<typeof AvatarGroup>;
87
type Meta = MetaObj<typeof AvatarGroup>;
98

components/Common/AvatarGroup/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import classNames from 'classnames';
22
import type { ComponentProps, FC } from 'react';
33
import { useState, useMemo } from 'react';
44

5+
import Avatar from '@/components/Common/AvatarGroup/Avatar';
6+
import avatarstyles from '@/components/Common/AvatarGroup/Avatar/index.module.css';
57
import { getAcronymFromString } from '@/util/stringUtils';
68

7-
import Avatar from './Avatar';
8-
import avatarstyles from './Avatar/index.module.css';
99
import styles from './index.module.css';
1010

1111
type AvatarGroupProps = {

components/Common/Badge/index.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
22

3-
import Badge from './index';
3+
import Badge from '@/components/Common/Badge';
44

55
type Story = StoryObj<typeof Badge>;
66
type Meta = MetaObj<typeof Badge>;

components/Common/Banner/index.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
22

3-
import Banner from './index';
3+
import Banner from '@/components/Common/Banner';
44

55
type Story = StoryObj<typeof Banner>;
66
type Meta = MetaObj<typeof Banner>;

components/Common/Blockquote/index.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
22

3-
import Blockquote from './index';
3+
import Blockquote from '@/components/Common/Blockquote';
44

55
type Story = StoryObj<typeof Blockquote>;
66
type Meta = MetaObj<typeof Blockquote>;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import { render, screen } from '@testing-library/react';
2+
3+
import BlogPostCard from '@/components/Common/BlogPostCard';
4+
import { LocaleProvider } from '@/providers/localeProvider';
5+
6+
function renderBlogPostCard({
7+
title = 'Blog post title',
8+
type = 'vulnerability',
9+
description = 'Blog post description',
10+
authors = [],
11+
date = new Date(),
12+
}) {
13+
render(
14+
<LocaleProvider>
15+
<BlogPostCard
16+
title={title}
17+
type={type}
18+
description={description}
19+
authors={authors}
20+
date={date}
21+
/>
22+
</LocaleProvider>
23+
);
24+
25+
return { title, type, description, authors, date };
26+
}
27+
28+
describe('BlogPostCard', () => {
29+
describe('Rendering', () => {
30+
it('Wraps the entire card within an article', () => {
31+
renderBlogPostCard({});
32+
33+
expect(screen.getByRole('article')).toBeVisible();
34+
});
35+
36+
it('Renders the title prop correctly', () => {
37+
const { title } = renderBlogPostCard({});
38+
39+
// Title from Preview component
40+
expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent(
41+
title
42+
);
43+
44+
// The second title should be hidden for screen-readers
45+
// to prevent them from reading it twice
46+
expect(screen.getAllByText(title)[1]).toHaveAttribute(
47+
'aria-hidden',
48+
'true'
49+
);
50+
});
51+
52+
it('Renders the description prop correctly', () => {
53+
const { description } = renderBlogPostCard({});
54+
55+
expect(screen.getByText(description)).toBeVisible();
56+
});
57+
58+
it.each([
59+
{ label: 'Vulnerabilities', type: 'vulnerability' },
60+
{ label: 'Announcements', type: 'announcement' },
61+
{ label: 'Releases', type: 'release' },
62+
])(
63+
'Renders "%label" text when passing it the type "%type"',
64+
({ label, type }) => {
65+
renderBlogPostCard({ type });
66+
67+
expect(screen.getByText(label)).toBeVisible();
68+
}
69+
);
70+
71+
it('Renders all passed authors fullName(s), comma-separated', () => {
72+
const authors = [
73+
{ fullName: 'Jane Doe', src: '' },
74+
{ fullName: 'John Doe', src: '' },
75+
];
76+
77+
renderBlogPostCard({ authors });
78+
79+
const fullNames = authors.reduce((prev, curr, index) => {
80+
if (index === 0) {
81+
return curr.fullName;
82+
}
83+
84+
return `${prev}, ${curr.fullName}`;
85+
}, '');
86+
87+
expect(screen.getByText(fullNames)).toBeVisible();
88+
});
89+
90+
it('Renders all passed authors fullName(s), comma-separated', () => {
91+
const authors = [
92+
{ fullName: 'Jane Doe', src: '' },
93+
{ fullName: 'John Doe', src: '' },
94+
];
95+
96+
renderBlogPostCard({ authors });
97+
98+
const fullNames = authors.reduce((prev, curr, index) => {
99+
if (index === 0) {
100+
return curr.fullName;
101+
}
102+
103+
return `${prev}, ${curr.fullName}`;
104+
}, '');
105+
106+
expect(screen.getByText(fullNames)).toBeVisible();
107+
});
108+
109+
it('Renders date prop in short format', () => {
110+
const date = new Date();
111+
112+
renderBlogPostCard({ date });
113+
114+
const dateTimeFormat = new Intl.DateTimeFormat(navigator.language, {
115+
day: 'numeric',
116+
month: 'short',
117+
year: 'numeric',
118+
});
119+
120+
expect(screen.getByText(dateTimeFormat.format(date))).toBeVisible();
121+
});
122+
});
123+
});

0 commit comments

Comments
 (0)