/**
* Component: BookDate Card Stack Tests
* Documentation: documentation/features/bookdate-animations.md
*/
// @vitest-environment jsdom
import React from 'react';
import { act, fireEvent, render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
vi.mock('@/components/bookdate/RecommendationCard', () => ({
RecommendationCard: ({
recommendation,
onSwipe,
stackPosition,
isDraggable,
}: {
recommendation: { id: string; title: string };
onSwipe: (action: 'left' | 'right' | 'up') => void;
stackPosition: number;
isDraggable: boolean;
}) => (
),
}));
const recommendations = [
{ id: 'rec-1', title: 'Rec One' },
{ id: 'rec-2', title: 'Rec Two' },
{ id: 'rec-3', title: 'Rec Three' },
{ id: 'rec-4', title: 'Rec Four' },
];
describe('CardStack', () => {
it('renders up to three cards and only the top card is draggable', async () => {
const { CardStack } = await import('@/components/bookdate/CardStack');
render(
);
expect(screen.getByTestId('card-rec-1')).toHaveAttribute('data-stack', '0');
expect(screen.getByTestId('card-rec-1')).toHaveAttribute('data-draggable', 'true');
expect(screen.getByTestId('card-rec-2')).toHaveAttribute('data-stack', '1');
expect(screen.getByTestId('card-rec-3')).toHaveAttribute('data-stack', '2');
expect(screen.queryByTestId('card-rec-4')).toBeNull();
});
it('locks swipes during animations and calls onSwipeComplete', async () => {
vi.useFakeTimers();
const onSwipe = vi.fn();
const onSwipeComplete = vi.fn();
const { CardStack } = await import('@/components/bookdate/CardStack');
render(
);
const topCard = screen.getByTestId('card-rec-1');
fireEvent.click(topCard);
fireEvent.click(topCard);
expect(onSwipe).toHaveBeenCalledTimes(1);
await act(async () => {
vi.advanceTimersByTime(750);
});
expect(onSwipeComplete).toHaveBeenCalledTimes(1);
vi.useRealTimers();
});
});