diff --git a/packages/shared/src/components/cards/squad/SquadList.tsx b/packages/shared/src/components/cards/squad/SquadList.tsx index 76215eab919..a8b9294fa45 100644 --- a/packages/shared/src/components/cards/squad/SquadList.tsx +++ b/packages/shared/src/components/cards/squad/SquadList.tsx @@ -40,7 +40,7 @@ export const SquadList = ({ return (
, }; }) ?? []; diff --git a/packages/shared/src/components/squads/SquadFavoriteButton.spec.tsx b/packages/shared/src/components/squads/SquadFavoriteButton.spec.tsx new file mode 100644 index 00000000000..f0c0eefc5d8 --- /dev/null +++ b/packages/shared/src/components/squads/SquadFavoriteButton.spec.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { SquadFavoriteButton } from './SquadFavoriteButton'; +import { useSquadFavorite } from '../../hooks/squads/useSquadFavorite'; +import { generateTestSquad } from '../../../__tests__/fixture/squads'; +import type { Squad } from '../../graphql/sources'; + +jest.mock('../../hooks/squads/useSquadFavorite', () => ({ + useSquadFavorite: jest.fn(), +})); + +const toggleFavorite = jest.fn(); + +const renderButton = (overrides: Partial = {}) => + render(); + +describe('SquadFavoriteButton', () => { + beforeEach(() => { + jest.clearAllMocks(); + jest.mocked(useSquadFavorite).mockReturnValue({ + toggleFavorite, + isPending: false, + }); + }); + + it('renders an unpressed star with the correct aria label when not favorited', () => { + renderButton({ favoritedAt: null }); + + const button = screen.getByRole('button', { name: 'Favorite squad' }); + expect(button).toBeInTheDocument(); + expect(button).toHaveAttribute('aria-pressed', 'false'); + }); + + it('renders a pressed star with the unfavorite aria label when favorited', () => { + renderButton({ favoritedAt: '2025-01-01T00:00:00.000Z' }); + + const button = screen.getByRole('button', { name: 'Unfavorite squad' }); + expect(button).toBeInTheDocument(); + expect(button).toHaveAttribute('aria-pressed', 'true'); + }); + + it('calls toggleFavorite with the squad when clicked', async () => { + const squad = generateTestSquad({ favoritedAt: null }); + render(); + + await userEvent.click( + screen.getByRole('button', { name: 'Favorite squad' }), + ); + + expect(toggleFavorite).toHaveBeenCalledWith(squad); + }); + + it('applies hover-reveal classes when the squad is not favorited', () => { + renderButton({ favoritedAt: null }); + + const button = screen.getByRole('button', { name: 'Favorite squad' }); + expect(button).toHaveClass('laptop:opacity-0'); + expect(button).toHaveClass('laptop:group-hover/squad-row:opacity-100'); + expect(button).toHaveClass( + 'laptop:group-focus-within/squad-row:opacity-100', + ); + }); + + it('does not apply hover-reveal classes when the squad is already favorited', () => { + renderButton({ favoritedAt: '2025-01-01T00:00:00.000Z' }); + + const button = screen.getByRole('button', { name: 'Unfavorite squad' }); + expect(button).not.toHaveClass('laptop:opacity-0'); + expect(button).not.toHaveClass('laptop:group-hover/squad-row:opacity-100'); + expect(button).not.toHaveClass( + 'laptop:group-focus-within/squad-row:opacity-100', + ); + }); +}); diff --git a/packages/shared/src/components/squads/SquadFavoriteButton.tsx b/packages/shared/src/components/squads/SquadFavoriteButton.tsx index 80138ee553f..ae54876b1da 100644 --- a/packages/shared/src/components/squads/SquadFavoriteButton.tsx +++ b/packages/shared/src/components/squads/SquadFavoriteButton.tsx @@ -38,6 +38,8 @@ export const SquadFavoriteButton = ({ onClick={onClick} className={classNames( 'relative z-1 flex items-center justify-center disabled:opacity-50', + !isFavorited && + 'laptop:opacity-0 laptop:transition-opacity laptop:group-focus-within/squad-row:opacity-100 laptop:group-hover/squad-row:opacity-100', className, )} >