@@ -454,6 +464,7 @@ describe('CardDetailsPage', () => {
const mockContributors = [
{
+ id: 'contributor-1',
avatarUrl: 'https://example.com/avatar1.jpg',
login: 'john_doe',
name: 'John Doe',
@@ -461,6 +472,7 @@ describe('CardDetailsPage', () => {
contributionsCount: 50,
},
{
+ id: 'contributor-2',
avatarUrl: 'https://example.com/avatar2.jpg',
login: 'jane_smith',
name: 'Jane Smith',
@@ -552,6 +564,7 @@ describe('CardDetailsPage', () => {
const mockRecentReleases = [
{
+ id: 'release-1',
author: mockUser,
isPreRelease: false,
name: 'v1.0.0',
@@ -1669,6 +1682,7 @@ describe('CardDetailsPage', () => {
contributionStats,
topContributors: [
{
+ id: 'contributor-user1',
login: 'user1',
name: 'User One',
avatarUrl: 'https://example.com/avatar1.png',
diff --git a/frontend/__tests__/unit/components/ContributorAvatar.test.tsx b/frontend/__tests__/unit/components/ContributorAvatar.test.tsx
index e5eecbd315..e59736edd9 100644
--- a/frontend/__tests__/unit/components/ContributorAvatar.test.tsx
+++ b/frontend/__tests__/unit/components/ContributorAvatar.test.tsx
@@ -64,6 +64,7 @@ jest.mock('next/image', () => {
})
const mockAlgoliaContributor: Contributor = {
+ id: 'contributor-johndoe',
login: 'johndoe',
name: 'John Doe',
avatarUrl: 'https://github.com/johndoe.png',
@@ -72,6 +73,7 @@ const mockAlgoliaContributor: Contributor = {
}
const mockGitHubContributor: Contributor = {
+ id: 'contributor-jane-doe',
login: 'jane-doe',
name: 'Jane Doe',
avatarUrl: 'https://avatars.githubusercontent.com/u/12345',
@@ -130,6 +132,7 @@ describe('ContributorAvatar', () => {
it('shows only name when no contributions count', () => {
const contributorWithoutContributions = {
+ id: 'contributor-newbie',
login: 'newbie',
name: 'New Contributor',
avatarUrl: 'https://github.com/newbie.png',
@@ -147,6 +150,7 @@ describe('ContributorAvatar', () => {
it('handles contributor with zero contributions', () => {
const contributorWithZeroContributions: Contributor = {
+ id: 'contributor-newcomer',
login: 'newcomer',
name: 'Brand New User',
avatarUrl: 'https://github.com/newcomer.png',
@@ -165,6 +169,7 @@ describe('ContributorAvatar', () => {
it('handles empty string values gracefully', () => {
const contributorWithEmptyStrings: Contributor = {
+ id: 'contributor-empty-strings',
login: '',
name: '',
avatarUrl: 'https://github.com/default.png',
@@ -182,6 +187,7 @@ describe('ContributorAvatar', () => {
it('handles very long names and contributions', () => {
const contributorWithLongData: Contributor = {
+ id: 'contributor-long-data',
login: 'very-long-username-that-might-break-layouts',
name: 'Someone With A Really Really Long Name That Might Cause Issues',
avatarUrl: 'https://github.com/very-long-username-that-might-break-layouts.png',
diff --git a/frontend/__tests__/unit/components/ItemCardList.test.tsx b/frontend/__tests__/unit/components/ItemCardList.test.tsx
index aab37ed096..1abdcd1c1d 100644
--- a/frontend/__tests__/unit/components/ItemCardList.test.tsx
+++ b/frontend/__tests__/unit/components/ItemCardList.test.tsx
@@ -167,6 +167,7 @@ const mockPullRequest: PullRequest = {
}
const mockRelease: Release = {
+ id: 'release-item-card',
author: {
...mockUser,
login: 'author4',
diff --git a/frontend/__tests__/unit/components/LeadersList.test.tsx b/frontend/__tests__/unit/components/LeadersList.test.tsx
index 55debe9df1..6ad4b546de 100644
--- a/frontend/__tests__/unit/components/LeadersList.test.tsx
+++ b/frontend/__tests__/unit/components/LeadersList.test.tsx
@@ -40,6 +40,7 @@ jest.mock('components/TruncatedText', () => ({
describe('LeadersList Component', () => {
const defaultProps: LeadersListProps = {
+ entityKey: 'test-entity',
leaders: 'John Doe, Jane Smith, Bob Johnson',
}
@@ -49,7 +50,7 @@ describe('LeadersList Component', () => {
describe('Renders successfully with minimal required props', () => {
it('renders with valid leaders string', () => {
- render(
)
+ render(
)
expect(screen.getByText('John Doe')).toBeInTheDocument()
expect(screen.getByTestId('truncated-text')).toBeInTheDocument()
})
@@ -62,31 +63,31 @@ describe('LeadersList Component', () => {
describe('Conditional rendering logic', () => {
it('renders "Unknown" when leaders prop is empty string', () => {
- render(
)
+ render(
)
expect(screen.getByText('Unknown')).toBeInTheDocument()
expect(screen.queryByTestId('truncated-text')).not.toBeInTheDocument()
})
it('renders "Unknown" when leaders prop is null', () => {
- render(
)
+ render(
)
expect(screen.getByText('Unknown')).toBeInTheDocument()
expect(screen.queryByTestId('truncated-text')).not.toBeInTheDocument()
})
it('renders "Unknown" when leaders prop is undefined', () => {
- render(
)
+ render(
)
expect(screen.getByText('Unknown')).toBeInTheDocument()
expect(screen.queryByTestId('truncated-text')).not.toBeInTheDocument()
})
it('renders "Unknown" when leaders prop is only whitespace', () => {
- render(
)
+ render(
)
expect(screen.getByText('Unknown')).toBeInTheDocument()
expect(screen.queryByTestId('truncated-text')).not.toBeInTheDocument()
})
it('renders leaders when valid non-empty string is provided', () => {
- render(
)
+ render(
)
expect(screen.queryByText('Unknown')).not.toBeInTheDocument()
expect(screen.getByTestId('truncated-text')).toBeInTheDocument()
})
@@ -94,7 +95,7 @@ describe('LeadersList Component', () => {
describe('Prop-based behavior', () => {
it('renders single leader correctly', () => {
- render(
)
+ render(
)
expect(screen.getByText('John Doe')).toBeInTheDocument()
expect(screen.getAllByTestId('leader-link')).toHaveLength(1)
})
@@ -108,14 +109,16 @@ describe('LeadersList Component', () => {
})
it('handles leaders with extra whitespace', () => {
- render(
)
+ render(
)
expect(screen.getByText('John Doe')).toBeInTheDocument()
expect(screen.getByText('Jane Smith')).toBeInTheDocument()
expect(screen.getAllByTestId('leader-link')).toHaveLength(2)
})
it('handles leaders with special characters', () => {
- render(
)
+ render(
+
+ )
expect(screen.getByText("John O'Connor")).toBeInTheDocument()
expect(screen.getByText('María García')).toBeInTheDocument()
expect(screen.getByText('Jean-Paul Dubois')).toBeInTheDocument()
@@ -137,7 +140,7 @@ describe('LeadersList Component', () => {
})
it('does not add comma after single leader', () => {
- const { container } = render(
)
+ const { container } = render(
)
const textContent = container.textContent
expect(textContent).toBe('John Doe')
expect(textContent).not.toContain(',')
@@ -151,7 +154,7 @@ describe('LeadersList Component', () => {
})
it('applies correct CSS classes to links', () => {
- render(
)
+ render(
)
const link = screen.getByTestId('leader-link')
expect(link).toHaveClass('text-gray-600', 'hover:underline', 'dark:text-gray-400')
})
@@ -166,7 +169,7 @@ describe('LeadersList Component', () => {
})
it('properly encodes special characters in URLs', () => {
- render(
)
+ render(
)
const links = screen.getAllByTestId('leader-link')
expect(links[0]).toHaveAttribute('href', "/members?q=John%20O'Connor")
@@ -194,7 +197,7 @@ describe('LeadersList Component', () => {
})
it('ensures links are focusable and have proper attributes', () => {
- render(
)
+ render(
)
const link = screen.getByTestId('leader-link')
expect(link).toHaveAttribute('href')
@@ -205,38 +208,37 @@ describe('LeadersList Component', () => {
describe('Handles edge cases and invalid inputs', () => {
it('handles empty array from split (single comma)', () => {
- render(
)
- const { container } = render(
)
- expect(container.textContent).toBe(', ')
+ render(
)
+ expect(screen.getByText('Unknown')).toBeInTheDocument()
})
it('handles multiple consecutive commas', () => {
- render(
)
+ render(
)
const links = screen.getAllByTestId('leader-link')
- expect(links).toHaveLength(3) // John Doe, empty string, Jane Smith
+ expect(links).toHaveLength(2) // John Doe, Jane Smith (empty strings filtered out)
})
it('handles trailing comma', () => {
- render(
)
+ render(
)
const links = screen.getAllByTestId('leader-link')
- expect(links).toHaveLength(3) // John Doe, Jane Smith, empty string
+ expect(links).toHaveLength(2) // John Doe, Jane Smith (empty strings filtered out)
})
it('handles leading comma', () => {
- render(
)
+ render(
)
const links = screen.getAllByTestId('leader-link')
- expect(links).toHaveLength(3) // empty string, John Doe, Jane Smith
+ expect(links).toHaveLength(2) // John Doe, Jane Smith (empty strings filtered out)
})
it('handles very long leader names', () => {
const longName = 'A'.repeat(100)
- render(
)
+ render(
)
expect(screen.getByText(longName)).toBeInTheDocument()
expect(screen.getByTestId('leader-link')).toHaveAttribute('title', longName)
})
it('handles numeric strings as leader names', () => {
- render(
)
+ render(
)
expect(screen.getByText('123')).toBeInTheDocument()
expect(screen.getByText('456')).toBeInTheDocument()
})
@@ -244,17 +246,17 @@ describe('LeadersList Component', () => {
describe('Default values and fallbacks', () => {
it('shows Unknown when no valid leaders are provided', () => {
- render(
)
+ render(
)
expect(screen.getByText('Unknown')).toBeInTheDocument()
})
it('handles undefined gracefully', () => {
- render(
)
+ render(
)
expect(screen.getByText('Unknown')).toBeInTheDocument()
})
it('handles null gracefully', () => {
- render(
)
+ render(
)
expect(screen.getByText('Unknown')).toBeInTheDocument()
})
})
diff --git a/frontend/__tests__/unit/components/LogoCarousel.test.tsx b/frontend/__tests__/unit/components/LogoCarousel.test.tsx
index eee363af11..964334de99 100644
--- a/frontend/__tests__/unit/components/LogoCarousel.test.tsx
+++ b/frontend/__tests__/unit/components/LogoCarousel.test.tsx
@@ -44,18 +44,21 @@ jest.mock('next/image', () => {
const mockSponsors: Sponsor[] = [
{
+ id: 'sponsor-1',
name: 'Test Sponsor 1',
imageUrl: 'https://example.com/logo1.png',
url: 'https://sponsor1.com',
sponsorType: 'Gold',
},
{
+ id: 'sponsor-2',
name: 'Test Sponsor 2',
imageUrl: 'https://example.com/logo2.png',
url: 'https://sponsor2.com',
sponsorType: 'Silver',
},
{
+ id: 'sponsor-3',
name: 'Test Sponsor 3',
imageUrl: '',
url: 'https://sponsor3.com',
@@ -65,6 +68,7 @@ const mockSponsors: Sponsor[] = [
const mockSponsorsWithoutImages: Sponsor[] = [
{
+ id: 'sponsor-no-image',
name: 'No Image Sponsor',
imageUrl: '',
url: 'https://noimage.com',
@@ -129,6 +133,7 @@ describe('MovingLogos (LogoCarousel)', () => {
it('renders different sponsors based on props', () => {
const customSponsors: Sponsor[] = [
{
+ id: 'sponsor-custom',
name: 'Custom Sponsor',
imageUrl: 'https://custom.com/logo.png',
url: 'https://custom.com',
@@ -230,7 +235,13 @@ describe('MovingLogos (LogoCarousel)', () => {
const newSponsors = [
...mockSponsors,
- { name: 'New Sponsor', imageUrl: '', url: 'https://new.com', sponsorType: 'Bronze' },
+ {
+ id: 'sponsor-new',
+ name: 'New Sponsor',
+ imageUrl: '',
+ url: 'https://new.com',
+ sponsorType: 'Bronze',
+ },
]
rerender(
)
@@ -281,6 +292,7 @@ describe('MovingLogos (LogoCarousel)', () => {
it('uses generic fallback alt text when sponsor name is missing', () => {
const sponsorWithoutName: Sponsor[] = [
{
+ id: 'sponsor-no-name',
name: '',
imageUrl: 'https://example.com/logo.png',
url: 'https://example.com',
@@ -338,6 +350,7 @@ describe('MovingLogos (LogoCarousel)', () => {
it('handles sponsors with very long names', () => {
const longNameSponsors: Sponsor[] = [
{
+ id: 'sponsor-long-name',
name: 'A'.repeat(1000),
imageUrl: 'https://example.com/logo.png',
url: 'https://example.com',
@@ -355,6 +368,7 @@ describe('MovingLogos (LogoCarousel)', () => {
it('handles sponsors with special characters in names', () => {
const specialCharSponsors: Sponsor[] = [
{
+ id: 'sponsor-special-chars',
name: 'Sponsor & Co. (Ltd.) - "Special"
',
imageUrl: 'https://example.com/logo.png',
url: 'https://example.com',
@@ -378,6 +392,7 @@ describe('MovingLogos (LogoCarousel)', () => {
it('handles invalid URLs gracefully', () => {
const invalidUrlSponsors: Sponsor[] = [
{
+ id: 'sponsor-invalid-url',
name: 'Invalid URL Sponsor',
imageUrl: 'not-a-valid-url',
url: 'also-not-valid',
@@ -398,6 +413,7 @@ describe('MovingLogos (LogoCarousel)', () => {
it('handles very large number of sponsors', () => {
const manySponsors: Sponsor[] = Array.from({ length: 100 }, (_, i) => ({
+ id: `sponsor-${i}`,
name: `Sponsor ${i}`,
imageUrl: `https://example.com/logo${i}.png`,
url: `https://sponsor${i}.com`,
diff --git a/frontend/__tests__/unit/components/MultiSearch.test.tsx b/frontend/__tests__/unit/components/MultiSearch.test.tsx
index 7d268cd19b..5ac489b8cb 100644
--- a/frontend/__tests__/unit/components/MultiSearch.test.tsx
+++ b/frontend/__tests__/unit/components/MultiSearch.test.tsx
@@ -324,11 +324,35 @@ describe('Rendering', () => {
})
it('filters event data based on query', async () => {
- const eventData = [
- { name: 'JavaScript Conference', url: 'https://example.com/js' },
- { name: 'Python Workshop', url: 'https://example.com/py' },
- { name: 'React Meetup', url: 'https://example.com/react' },
- ] as Event[]
+ const eventData: Event[] = [
+ {
+ id: 'event-1',
+ name: 'JavaScript Conference',
+ url: 'https://example.com/js',
+ objectID: 'event-1',
+ key: 'js-conf',
+ category: 'other',
+ startDate: '2024-01-01',
+ },
+ {
+ id: 'event-2',
+ name: 'Python Workshop',
+ url: 'https://example.com/py',
+ objectID: 'event-2',
+ key: 'py-workshop',
+ category: 'other',
+ startDate: '2024-02-01',
+ },
+ {
+ id: 'event-3',
+ name: 'React Meetup',
+ url: 'https://example.com/react',
+ objectID: 'event-3',
+ key: 'react-meetup',
+ category: 'other',
+ startDate: '2024-03-01',
+ },
+ ]
const user = userEvent.setup()
render()
diff --git a/frontend/__tests__/unit/components/RecentRelease.test.tsx b/frontend/__tests__/unit/components/RecentRelease.test.tsx
index 380e611bb4..5108750b20 100644
--- a/frontend/__tests__/unit/components/RecentRelease.test.tsx
+++ b/frontend/__tests__/unit/components/RecentRelease.test.tsx
@@ -67,6 +67,7 @@ jest.mock('next/image', () => ({
const now = Date.now()
const mockReleases: Release[] = [
{
+ id: 'release-recent-1',
name: 'v1.0 The First Release',
publishedAt: now,
repositoryName: 'our-awesome-project',
@@ -87,6 +88,7 @@ const mockReleases: Release[] = [
},
},
{
+ id: 'release-recent-2',
name: 'v2.0 The Second Release',
publishedAt: now,
repositoryName: 'another-cool-project',
diff --git a/frontend/__tests__/unit/components/Release.test.tsx b/frontend/__tests__/unit/components/Release.test.tsx
index 7e324c56c9..83037dbdea 100644
--- a/frontend/__tests__/unit/components/Release.test.tsx
+++ b/frontend/__tests__/unit/components/Release.test.tsx
@@ -71,6 +71,7 @@ jest.mock('next/image', () => ({
const now = Date.now()
const mockReleases: ReleaseType[] = [
{
+ id: 'release-test-1',
name: 'v1.0 The First Release',
publishedAt: now,
repositoryName: 'our-awesome-project',
@@ -91,6 +92,7 @@ const mockReleases: ReleaseType[] = [
},
},
{
+ id: 'release-test-2',
name: 'v2.0 The Second Release',
publishedAt: now,
repositoryName: 'another-cool-project',
diff --git a/frontend/__tests__/unit/components/SingleModuleCard.test.tsx b/frontend/__tests__/unit/components/SingleModuleCard.test.tsx
index e356e6bf13..91e1adc393 100644
--- a/frontend/__tests__/unit/components/SingleModuleCard.test.tsx
+++ b/frontend/__tests__/unit/components/SingleModuleCard.test.tsx
@@ -93,11 +93,13 @@ const mockModule: Module = {
experienceLevel: ExperienceLevelEnum.Intermediate,
mentors: [
{
+ id: 'mentor-user1',
name: 'user1',
login: 'user1',
avatarUrl: 'https://example.com/avatar1.jpg',
},
{
+ id: 'mentor-user2',
name: 'user2',
login: 'user2',
avatarUrl: 'https://example.com/avatar2.jpg',
diff --git a/frontend/__tests__/unit/components/ToggleableList.test.tsx b/frontend/__tests__/unit/components/ToggleableList.test.tsx
index 55876d51d8..32a45f4c8a 100644
--- a/frontend/__tests__/unit/components/ToggleableList.test.tsx
+++ b/frontend/__tests__/unit/components/ToggleableList.test.tsx
@@ -37,7 +37,7 @@ describe('ToggleableList', () => {
})
it('renders with limited props initially', () => {
- render()
+ render()
// First 10 items should be visible
for (const item of mockItems.slice(0, 10)) {
@@ -51,7 +51,7 @@ describe('ToggleableList', () => {
})
it('renders with an icon', () => {
- render()
+ render()
const iconElement = screen.getByTestId('react-icon')
expect(iconElement).toBeInTheDocument()
@@ -59,7 +59,7 @@ describe('ToggleableList', () => {
})
it('respects custom limit prop', () => {
- render()
+ render()
expect(screen.getByText('Item 1')).toBeInTheDocument()
expect(screen.getByText('Item 2')).toBeInTheDocument()
@@ -69,19 +69,19 @@ describe('ToggleableList', () => {
it('does not show Show More button when item count is less than the limit', () => {
const limitedItems = mockItems.slice(0, 5)
- render()
+ render()
expect(screen.queryByTestId('show-more-button')).not.toBeInTheDocument()
})
it('shows Show More button when items exceed limit', () => {
- render()
+ render()
expect(screen.getByRole('button', { name: /show more/i })).toBeInTheDocument()
})
it('expands to show all items when ShowMoreButton is clicked', () => {
- render()
+ render()
// Initially hidden items
expect(screen.queryByText('Item 6')).not.toBeInTheDocument()
@@ -96,7 +96,9 @@ describe('ToggleableList', () => {
})
it('collapses back to limited view when ShowMoreButton is clicked again', () => {
- render()
+ render(
+
+ )
// Expand
fireEvent.click(screen.getByRole('button', { name: /show more/i }))
@@ -109,21 +111,28 @@ describe('ToggleableList', () => {
})
it('navigates on item button click', () => {
- render()
+ render(
+
+ )
const button = screen.getByText('React')
fireEvent.click(button)
expect(mockPush).toHaveBeenCalledWith('/projects?q=React')
})
it('handles empty items array', () => {
- render()
+ render()
expect(screen.getByText('Empty List')).toBeInTheDocument()
expect(screen.queryByTestId('show-more-button')).not.toBeInTheDocument()
})
it('handles single item', () => {
- render()
+ render()
expect(screen.getByText('Single Item')).toBeInTheDocument()
expect(screen.queryByTestId('show-more-button')).not.toBeInTheDocument()
@@ -131,14 +140,14 @@ describe('ToggleableList', () => {
it('handles items exactly equal to limit', () => {
const exactItems = Array.from({ length: 5 }, (_, i) => `Item ${i + 1}`)
- render()
+ render()
expect(screen.getByText('Item 5')).toBeInTheDocument()
expect(screen.queryByTestId('show-more-button')).not.toBeInTheDocument()
})
it('handles limit of 0', () => {
- render()
+ render()
// Should show ShowMoreButton since limit is exceeded
expect(screen.getByRole('button', { name: /show more/i })).toBeInTheDocument()
for (const item of mockItems) {
@@ -148,7 +157,7 @@ describe('ToggleableList', () => {
it('properly encodes special character in item names', () => {
const itemsWithSpecialChars = ['C++', 'C#', 'Node.js & Express']
- render()
+ render()
const specialButton = screen.getByText('C++')
fireEvent.click(specialButton)
@@ -156,20 +165,22 @@ describe('ToggleableList', () => {
})
it('applies correct CSS classes to main container', () => {
- const { container } = render()
+ const { container } = render(
+
+ )
const mainDiv = container.firstChild
expect(mainDiv).toHaveClass('rounded-lg', 'bg-gray-100', 'p-6', 'shadow-md', 'dark:bg-gray-800')
})
it('applies correct CSS classes to header', () => {
- render()
+ render()
const header = screen.getByRole('heading', { level: 2 })
expect(header).toHaveClass('mb-4', 'text-2xl', 'font-semibold')
})
it('applies correct CSS to button items (no underline, no transition, only hover background)', () => {
const randomItems = ['React', 'Vue', 'Angular']
- render()
+ render()
const button = screen.getByText('React')
expect(button).toHaveClass(
'rounded-lg',
diff --git a/frontend/__tests__/unit/components/TopContributorsList.test.tsx b/frontend/__tests__/unit/components/TopContributorsList.test.tsx
index 83d374cf7f..1ac8d2ec00 100644
--- a/frontend/__tests__/unit/components/TopContributorsList.test.tsx
+++ b/frontend/__tests__/unit/components/TopContributorsList.test.tsx
@@ -156,6 +156,7 @@ jest.mock('react-icons/fa6', () => ({
const mockContributors: Contributor[] = [
{
+ id: 'contributor-developer1',
avatarUrl: 'https://github.com/developer1.avatar',
login: 'developer1',
name: 'Alex Developer',
@@ -163,6 +164,7 @@ const mockContributors: Contributor[] = [
contributionsCount: 50,
},
{
+ id: 'contributor-contributor2',
avatarUrl: 'https://github.com/contributor2.avatar',
login: 'contributor2',
name: 'Jane Developer',
@@ -170,6 +172,7 @@ const mockContributors: Contributor[] = [
contributionsCount: 30,
},
{
+ id: 'contributor-user3',
avatarUrl: 'https://github.com/user3.avatar',
login: 'user3',
name: '',
@@ -256,12 +259,14 @@ describe('TopContributorsList Component', () => {
it('renders contributor name when available, falls back to login', () => {
const contributorsWithMissingNames: Contributor[] = [
{
+ id: 'contributor-dev1',
avatarUrl: 'https://github.com/developer1.avatar',
login: 'developer1',
name: 'Alex Developer',
projectKey: 'project1',
},
{
+ id: 'contributor-contrib2',
avatarUrl: 'https://github.com/contributor2.avatar',
login: 'contributor2',
name: '',
@@ -438,6 +443,7 @@ describe('TopContributorsList Component', () => {
it('falls back to login when name is empty or missing', () => {
const contributorWithoutName: Contributor[] = [
{
+ id: 'contributor-testuser',
avatarUrl: 'https://github.com/user1.avatar',
login: 'testuser',
name: '',
@@ -453,6 +459,7 @@ describe('TopContributorsList Component', () => {
it('handles missing avatar URL gracefully', () => {
const contributorWithEmptyAvatar: Contributor[] = [
{
+ id: 'contributor-dev1-empty-avatar',
avatarUrl: '',
login: 'developer1',
name: 'Alex Developer',
@@ -505,12 +512,14 @@ describe('TopContributorsList Component', () => {
it('handles contributors with missing required fields', () => {
const incompleteContributors: Contributor[] = [
{
+ id: 'contributor-incomplete1',
avatarUrl: 'https://github.com/user1.avatar',
login: '',
name: '',
projectKey: 'project1',
},
{
+ id: 'contributor-incomplete2',
avatarUrl: '',
login: 'user2',
name: 'User 2',
diff --git a/frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx b/frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
index 95c7256f9d..058c8565bf 100644
--- a/frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
+++ b/frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
@@ -25,7 +25,7 @@ jest.mock('app/global-error', () => ({
// Mock components
jest.mock('components/LabelList', () => ({
- LabelList: ({ labels }: { labels: string[] }) => (
+ LabelList: ({ labels, entityKey: _entityKey }: { labels: string[]; entityKey: string }) => (
{labels.join(', ')}
),
}))
diff --git a/frontend/eslint.config.mjs b/frontend/eslint.config.mjs
index d183cf8088..4a2192d198 100644
--- a/frontend/eslint.config.mjs
+++ b/frontend/eslint.config.mjs
@@ -160,6 +160,7 @@ const eslintConfig = [
'nest/no-global-nan': 'error',
'nest/no-global-parsefloat': 'error',
'nest/no-global-parseint': 'error',
+ 'react/no-array-index-key': 'error',
quotes: ['error', 'single', { avoidEscape: true }],
},
},
@@ -169,6 +170,12 @@ const eslintConfig = [
'no-console': 'off',
},
},
+ {
+ files: ['**/skeletons/**/*.{ts,tsx,js,jsx}', '**/*.skeleton.{ts,tsx,js,jsx}'],
+ rules: {
+ 'react/no-array-index-key': 'off',
+ },
+ },
]
export default eslintConfig
diff --git a/frontend/src/app/chapters/page.tsx b/frontend/src/app/chapters/page.tsx
index 03236429e4..2c050132f2 100644
--- a/frontend/src/app/chapters/page.tsx
+++ b/frontend/src/app/chapters/page.tsx
@@ -64,6 +64,7 @@ const ChaptersPage = () => {
return (
{
return (
{
return (
{
return (
{
/>
- {snapshot.newChapters.filter((chapter) => chapter.isActive).map(renderChapterCard)}
+ {snapshot.newChapters
+ .filter((chapter) => chapter.isActive)
+ .map((chapter) => (
+ {renderChapterCard(chapter)}
+ ))}