Add sharing
This commit is contained in:
parent
240ce28692
commit
8a11275849
16 changed files with 1996 additions and 10 deletions
|
|
@ -10,6 +10,7 @@ const createMockQuiz = (overrides?: Partial<QuizListItem>): QuizListItem => ({
|
|||
title: 'Test Quiz',
|
||||
source: 'manual',
|
||||
questionCount: 5,
|
||||
isShared: false,
|
||||
createdAt: '2024-01-15T10:00:00.000Z',
|
||||
updatedAt: '2024-01-15T10:00:00.000Z',
|
||||
...overrides,
|
||||
|
|
@ -23,6 +24,7 @@ describe('QuizLibrary', () => {
|
|||
loading: false,
|
||||
loadingQuizId: null,
|
||||
deletingQuizId: null,
|
||||
sharingQuizId: null,
|
||||
exporting: false,
|
||||
error: null,
|
||||
onLoadQuiz: vi.fn(),
|
||||
|
|
@ -30,6 +32,8 @@ describe('QuizLibrary', () => {
|
|||
onExportQuizzes: vi.fn(),
|
||||
onImportClick: vi.fn(),
|
||||
onRetry: vi.fn(),
|
||||
onShareQuiz: vi.fn().mockResolvedValue('mock-token'),
|
||||
onUnshareQuiz: vi.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -519,4 +523,119 @@ describe('QuizLibrary', () => {
|
|||
expect(defaultProps.onRetry).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('share functionality', () => {
|
||||
const mockWriteText = vi.fn().mockResolvedValue(undefined);
|
||||
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(navigator, 'clipboard', {
|
||||
value: {
|
||||
writeText: mockWriteText,
|
||||
},
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
mockWriteText.mockClear();
|
||||
});
|
||||
|
||||
it('shows share button for non-shared quiz', () => {
|
||||
render(<QuizLibrary {...defaultProps} />);
|
||||
expect(screen.getByTitle('Share quiz')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows copy link button and stop sharing button for shared quiz', () => {
|
||||
const quizzes = [createMockQuiz({ isShared: true, shareToken: 'test-token' })];
|
||||
render(<QuizLibrary {...defaultProps} quizzes={quizzes} />);
|
||||
|
||||
expect(screen.getByTitle('Copy share link')).toBeInTheDocument();
|
||||
expect(screen.getByTitle('Stop sharing')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows Shared badge for shared quiz', () => {
|
||||
const quizzes = [createMockQuiz({ isShared: true, shareToken: 'test-token' })];
|
||||
render(<QuizLibrary {...defaultProps} quizzes={quizzes} />);
|
||||
|
||||
expect(screen.getByText('Shared')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls onShareQuiz when share button clicked', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<QuizLibrary {...defaultProps} />);
|
||||
|
||||
await user.click(screen.getByTitle('Share quiz'));
|
||||
|
||||
expect(defaultProps.onShareQuiz).toHaveBeenCalledWith('quiz-1');
|
||||
});
|
||||
|
||||
it('does not call onShareQuiz for already shared quiz', async () => {
|
||||
const user = userEvent.setup();
|
||||
const quizzes = [createMockQuiz({ isShared: true, shareToken: 'existing-token' })];
|
||||
render(<QuizLibrary {...defaultProps} quizzes={quizzes} />);
|
||||
|
||||
await user.click(screen.getByTitle('Copy share link'));
|
||||
|
||||
expect(defaultProps.onShareQuiz).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls onUnshareQuiz when stop sharing button clicked', async () => {
|
||||
const user = userEvent.setup();
|
||||
const quizzes = [createMockQuiz({ isShared: true, shareToken: 'test-token' })];
|
||||
render(<QuizLibrary {...defaultProps} quizzes={quizzes} />);
|
||||
|
||||
await user.click(screen.getByTitle('Stop sharing'));
|
||||
|
||||
expect(defaultProps.onUnshareQuiz).toHaveBeenCalledWith('quiz-1');
|
||||
});
|
||||
|
||||
it('hides share buttons in selection mode', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<QuizLibrary {...defaultProps} />);
|
||||
|
||||
expect(screen.getByTitle('Share quiz')).toBeInTheDocument();
|
||||
|
||||
await user.click(screen.getByTitle('Select for export'));
|
||||
|
||||
expect(screen.queryByTitle('Share quiz')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows loading state when sharing quiz', () => {
|
||||
const quizzes = [createMockQuiz({ id: 'quiz-1' })];
|
||||
render(<QuizLibrary {...defaultProps} quizzes={quizzes} sharingQuizId="quiz-1" />);
|
||||
|
||||
const quizCard = screen.getByText('Test Quiz').closest('[class*="rounded-2xl"]')!;
|
||||
expect(quizCard).toHaveClass('opacity-70');
|
||||
});
|
||||
|
||||
it('share click does not trigger quiz load', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<QuizLibrary {...defaultProps} />);
|
||||
|
||||
await user.click(screen.getByTitle('Share quiz'));
|
||||
|
||||
expect(defaultProps.onLoadQuiz).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('unshare click does not trigger quiz load', async () => {
|
||||
const user = userEvent.setup();
|
||||
const quizzes = [createMockQuiz({ isShared: true, shareToken: 'test-token' })];
|
||||
render(<QuizLibrary {...defaultProps} quizzes={quizzes} />);
|
||||
|
||||
await user.click(screen.getByTitle('Stop sharing'));
|
||||
|
||||
expect(defaultProps.onLoadQuiz).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('displays multiple shared and non-shared quizzes correctly', () => {
|
||||
const quizzes = [
|
||||
createMockQuiz({ id: '1', title: 'Shared Quiz', isShared: true, shareToken: 'token1' }),
|
||||
createMockQuiz({ id: '2', title: 'Private Quiz', isShared: false }),
|
||||
];
|
||||
render(<QuizLibrary {...defaultProps} quizzes={quizzes} />);
|
||||
|
||||
expect(screen.getByText('Shared')).toBeInTheDocument();
|
||||
expect(screen.getAllByTitle('Share quiz')).toHaveLength(1);
|
||||
expect(screen.getAllByTitle('Copy share link')).toHaveLength(1);
|
||||
expect(screen.getAllByTitle('Stop sharing')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue