diff --git a/package-lock.json b/package-lock.json
index a828803..1789576 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -37,7 +37,9 @@
"tailwindcss": "^3.4.17",
"typescript": "~5.7.2",
"typescript-eslint": "^8.26.1",
- "vite": "^6.3.5"
+ "vite": "^6.3.5",
+ "@testing-library/react": "^16.0.0",
+ "vitest": "^1.6.0"
}
},
"node_modules/@alloc/quick-lru": {
diff --git a/package.json b/package.json
index 37811fb..f0efb34 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,8 @@
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
- "preview": "vite preview"
+ "preview": "vite preview",
+ "test": "vitest"
},
"dependencies": {
"axios": "^1.9.0",
@@ -39,6 +40,8 @@
"tailwindcss": "^3.4.17",
"typescript": "~5.7.2",
"typescript-eslint": "^8.26.1",
- "vite": "^6.3.5"
+ "vite": "^6.3.5",
+ "@testing-library/react": "^16.0.0",
+ "vitest": "^1.6.0"
}
}
diff --git a/src/components/orders/__tests__/TableCard.test.tsx b/src/components/orders/__tests__/TableCard.test.tsx
new file mode 100644
index 0000000..b88127d
--- /dev/null
+++ b/src/components/orders/__tests__/TableCard.test.tsx
@@ -0,0 +1,55 @@
+import { render, screen } from '@testing-library/react';
+import { describe, it, expect, vi } from 'vitest';
+import TableCard from '../TableCard';
+
+vi.mock('@/stores/booths/tableDetail', () => ({
+ useTableDetail: () => ({
+ getCustomTableNum: (num: number) => num,
+ }),
+}));
+
+vi.mock('@/stores/orders/tableVisualization', () => ({
+ useTableVisualizationDetail: () => ({
+ openTableVisualDetail: vi.fn(),
+ }),
+}));
+
+describe('TableCard', () => {
+ const base = { tableNumIndex: 1 };
+
+ it('renders ready table with correct label and style', () => {
+ const table = { ...base, type: 'ready', orderInfo: { totalPrice: 1000 } as any };
+ render();
+ const status = screen.getByText('입금대기');
+ expect(status.className).toContain('text-danger-800');
+ const container = status.parentElement?.parentElement as HTMLElement;
+ expect(container.className).toContain('bg-danger-50');
+ });
+
+ it('renders cooking table with correct label and style', () => {
+ const table = { ...base, type: 'cooking', orderInfo: { totalPrice: 1000 } as any };
+ render();
+ const status = screen.getByText('조리중');
+ expect(status.className).toContain('text-primary-800');
+ const container = status.parentElement?.parentElement as HTMLElement;
+ expect(container.className).toContain('bg-primary-300');
+ });
+
+ it('renders complete table with correct label and style', () => {
+ const table = { ...base, type: 'complete', orderInfo: { totalPrice: 1000 } as any };
+ render();
+ const status = screen.getByText('조리완료');
+ expect(status.className).toContain('text-success-900');
+ const container = status.parentElement?.parentElement as HTMLElement;
+ expect(container.className).toContain('bg-success-50');
+ });
+
+ it('renders table with no order info', () => {
+ const table = { ...base, type: 'complete', orderInfo: null };
+ render();
+ const status = screen.getByText('주문 건 없음');
+ expect(status.className).toContain('text-secondary-600');
+ const container = status.parentElement?.parentElement as HTMLElement;
+ expect(container.className).toContain('bg-gray-200');
+ });
+});
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 0000000..7afab3a
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,15 @@
+import { defineConfig } from 'vitest/config';
+import react from '@vitejs/plugin-react';
+import path from 'node:path';
+
+export default defineConfig({
+ plugins: [react()],
+ resolve: {
+ alias: {
+ '@': path.resolve(__dirname, './src'),
+ },
+ },
+ test: {
+ environment: 'jsdom',
+ },
+});