diff --git a/__tests__/board-title-form.test.tsx b/__tests__/board-title-form.test.tsx index 030c124..1f40c18 100644 --- a/__tests__/board-title-form.test.tsx +++ b/__tests__/board-title-form.test.tsx @@ -1,21 +1,9 @@ -import '@testing-library/jest-dom'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { toast } from 'sonner'; import { BoardTitleForm } from '@/app/(platform)/(dashboard)/board/[boardId]/_components/board-title-form'; import { Board } from '@prisma/client'; -jest.mock('sonner', () => ({ - toast: { - success: jest.fn(), - error: jest.fn(), - }, -})); - -jest.mock('@/actions/update-board', () => ({ - updateBoard: jest.fn(), -})); - jest.mock('@/hooks/use-action', () => ({ useAction: jest.fn().mockImplementation(() => ({ execute: jest.fn().mockImplementation(({ title }) => { diff --git a/__tests__/index.test.tsx b/__tests__/index.test.tsx index 3d6d58e..915b218 100644 --- a/__tests__/index.test.tsx +++ b/__tests__/index.test.tsx @@ -1,4 +1,3 @@ -import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/react'; import Page from '@/app/(main)/page'; diff --git a/__tests__/list-header.test.tsx b/__tests__/list-header.test.tsx new file mode 100644 index 0000000..3ecb92e --- /dev/null +++ b/__tests__/list-header.test.tsx @@ -0,0 +1,80 @@ +import '@testing-library/jest-dom'; +import { + render, + screen, + fireEvent, + act, + waitFor, +} from '@testing-library/react'; +import { toast } from 'sonner'; + +import { ListHeader } from '@/app/(platform)/(dashboard)/board/[boardId]/_components/list-header'; + +jest.mock('@/hooks/use-action', () => ({ + useAction: jest.fn().mockImplementation(() => ({ + execute: jest.fn().mockImplementation(({ title }) => { + Promise.resolve().then(() => { + toast.success(`Renamed to "${title}"`); + }); + }), + })), +})); + +const mockList = { + id: '1', + title: 'Test List', + boardId: 'board1', + order: 1, + createdAt: new Date(), + updatedAt: new Date(), +}; + +const mockOnAddCard = jest.fn(); + +describe('ListHeader', () => { + it('should render correctly in browser environment', () => { + render(); + + expect(screen.getByText('Test List')).toBeInTheDocument(); + }); + + it('should switch to edit mode when clicked', async () => { + render(); + + const listButton = screen.getByText('Test List'); + fireEvent.click(listButton); + + const editableInput = await screen.findByDisplayValue('Test List'); + expect(editableInput).toBeInTheDocument(); + }); + + it('should update list title when form is blurred', async () => { + render(); + + const listButton = screen.getByText('Test List'); + fireEvent.click(listButton); + + const editableInput = await screen.findByDisplayValue('Test List'); + fireEvent.change(editableInput, { target: { value: 'Updated Title' } }); + fireEvent.blur(editableInput); + + await waitFor(() => { + expect(toast.success).toHaveBeenCalledWith('Renamed to "Updated Title"'); + }); + }); + + it('should update list title when escape key is pressed', async () => { + render(); + + const listButton = screen.getByText('Test List'); + fireEvent.click(listButton); + + const editableInput = await screen.findByDisplayValue('Test List'); + fireEvent.change(editableInput, { target: { value: 'Updated Title' } }); + fireEvent.keyDown(editableInput, { key: 'Escape', code: 'Escape' }); + + await waitFor(() => { + expect(toast.success).toHaveBeenCalledWith('Renamed to "Updated Title"'); + }); + }); +}); diff --git a/app/(platform)/(dashboard)/board/[boardId]/_components/list-header.tsx b/app/(platform)/(dashboard)/board/[boardId]/_components/list-header.tsx index 41f2242..c174a1d 100644 --- a/app/(platform)/(dashboard)/board/[boardId]/_components/list-header.tsx +++ b/app/(platform)/(dashboard)/board/[boardId]/_components/list-header.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, useRef } from 'react'; +import { useState, useRef, useEffect } from 'react'; import { useEventListener } from 'usehooks-ts'; import { List } from '@prisma/client'; import { toast } from 'sonner'; @@ -20,7 +20,10 @@ export const ListHeader = ({ data, onAddCard }: ListHeaderProps) => { const [title, setTitle] = useState(data.title); const [isEditing, setIsEditing] = useState(false); - const formRef = useRef(document.createElement('form')); + const formRef = useRef(null); + useEffect(() => { + formRef.current = document.createElement('form'); + }, []); const inputRef = useRef(null); const enableEditing = () => { @@ -72,8 +75,13 @@ export const ListHeader = ({ data, onAddCard }: ListHeaderProps) => {
{isEditing ? (
- - + + { orderBy: { order: 'asc', }, - cacheStrategy: { ttl: 30, swr: 60 }, }); return ( diff --git a/app/api/cards/[cardId]/logs/route.ts b/app/api/cards/[cardId]/logs/route.ts index 7b89f3c..b79b270 100644 --- a/app/api/cards/[cardId]/logs/route.ts +++ b/app/api/cards/[cardId]/logs/route.ts @@ -35,11 +35,6 @@ export async function GET( return new NextResponse(JSON.stringify(auditLogs), { status: 200, - headers: { - 'Cache-Control': 'public, s-maxage=1', - 'CDN-Cache-Control': 'public, s-maxage=30', - 'Vercel-CDN-Cache-Control': 'public, s-maxage=60', - }, }); } catch (error) { return new NextResponse(JSON.stringify(error), { status: 500 }); diff --git a/app/api/cards/[cardId]/route.ts b/app/api/cards/[cardId]/route.ts index 5b472e1..3ec585d 100644 --- a/app/api/cards/[cardId]/route.ts +++ b/app/api/cards/[cardId]/route.ts @@ -40,11 +40,6 @@ export async function GET( return new NextResponse(JSON.stringify(card), { status: 200, - headers: { - 'Cache-Control': 'public, s-maxage=1', - 'CDN-Cache-Control': 'public, s-maxage=30', - 'Vercel-CDN-Cache-Control': 'public, s-maxage=60', - }, }); } catch (error) { return new NextResponse(JSON.stringify(error), { status: 500 }); diff --git a/jest.setup.ts b/jest.setup.ts index 7b0828b..b926457 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -1 +1,25 @@ import '@testing-library/jest-dom'; +import { toast } from 'sonner'; + +jest.mock('sonner', () => ({ + toast: { + success: jest.fn(), + error: jest.fn(), + }, +})); + +jest.mock('@/actions/update-list', () => ({ + updateList: jest.fn(), +})); + +jest.mock('@/actions/delete-list', () => ({ + deleteList: jest.fn(), +})); + +jest.mock('@/actions/copy-list', () => ({ + copyList: jest.fn(), +})); + +jest.mock('@/actions/update-board', () => ({ + updateBoard: jest.fn(), +}));