Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[6팀 손유민] [Chapter 2-2] 디자인 패턴과 함수형 프로그래밍 #24

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6f25b9e
basic cart.ts, hooks 작업중
fdgh134 Jan 13, 2025
6575e8a
useCart
fdgh134 Jan 13, 2025
5022b3d
usdCoupons
fdgh134 Jan 13, 2025
f0ba2f1
쿠폰 적용 안됨. 처리중..
fdgh134 Jan 13, 2025
0eb7b60
쿠폰 적용 처리 완료 basic 통과
fdgh134 Jan 14, 2025
3f610fc
공백 제거
fdgh134 Jan 14, 2025
305cb9c
adminPage 상품추가에 할인율 추가 해보기
fdgh134 Jan 14, 2025
e661547
adminPage 상품추가에 할인율 추가 해보기
fdgh134 Jan 14, 2025
fa7985a
할인 추가 작업중
fdgh134 Jan 14, 2025
60bfb41
일단 초기화
fdgh134 Jan 14, 2025
0df2511
Merge branch 'main' of https://github.com/fdgh134/front_4th_chapter2-2
fdgh134 Jan 15, 2025
0bf2c6a
cartPage 컴포넌트 세분화
fdgh134 Jan 15, 2025
16dce59
useCallback, useMemo 써보기
fdgh134 Jan 15, 2025
1e75fb9
interface 정리
fdgh134 Jan 15, 2025
acfac0b
adminpage 컴포넌트 분리 및 폴더 구조 변경, 파일명 변경
fdgh134 Jan 15, 2025
07fae3e
adminProductList저장
fdgh134 Jan 15, 2025
b74582f
제품추가 오류 수정
fdgh134 Jan 15, 2025
e9afc67
accordion hook 분리
fdgh134 Jan 15, 2025
4501bbe
edit hook 추가
fdgh134 Jan 15, 2025
b8d9390
hook 추가중 관리자페이지 에러 수정
fdgh134 Jan 15, 2025
743c0af
관리자 페이지 에러 수정
fdgh134 Jan 15, 2025
ce98c9f
불필요한 파일 제거
fdgh134 Jan 15, 2025
a89a13a
util 재생성, useDiscount 제거
fdgh134 Jan 15, 2025
3de3935
검색기능 추가
fdgh134 Jan 16, 2025
81ebb63
테스트코드 추가
fdgh134 Jan 16, 2025
c2efde3
테스트아이디 추가
fdgh134 Jan 16, 2025
f02fc80
test가 왜 안될까
fdgh134 Jan 22, 2025
905953b
advanced -> advacned 원복
fdgh134 Jan 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,963 changes: 3,963 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
"@types/react-dom": "^18.3.1",
"@typescript-eslint/eslint-plugin": "^8.10.0",
"@typescript-eslint/parser": "^8.10.0",
"@vitejs/plugin-react-swc": "^3.7.1",
"@vitejs/plugin-react-swc": "^3.7.2",
"@vitest/ui": "^2.1.3",
"eslint": "^9.12.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.12",
"jsdom": "^26.0.0",
"typescript": "^5.6.3",
"vite": "^5.4.9",
"vitest": "^2.1.3"
"vite": "^5.4.11",
"vitest": "^2.1.8"
}
}
76 changes: 70 additions & 6 deletions src/advanced/__tests__/advanced.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useState } from "react";
import { describe, expect, test } from 'vitest';
import { act, fireEvent, render, screen, within } from '@testing-library/react';
import { act, fireEvent, render, renderHook, screen, within } from '@testing-library/react';
import { CartPage } from '../../refactoring/components/CartPage';
import { AdminPage } from "../../refactoring/components/AdminPage";
import { Coupon, Product } from '../../types';
import { useCart } from "../../refactoring/hooks";

const mockProducts: Product[] = [
{
Expand Down Expand Up @@ -232,12 +233,75 @@
})

describe('자유롭게 작성해보세요.', () => {
test('새로운 유틸 함수를 만든 후에 테스트 코드를 작성해서 실행해보세요', () => {
expect(true).toBe(false);
})
test('장바구니 테스트', () => {
const product: Product = {
id: "1",
name: "Product 1",
price: 100,
stock: 10,
discounts: [],
};
const { result } = renderHook(() => useCart());

// 처음에는 재고가 10이어야 함
expect(result.current.getRemainingStock(product)).toBe(10);

// 카트에 상품 추가
act(() => {
result.current.addToCart(product);
});

// 카트에 1개 추가된 후 재고는 9여야 함
expect(result.current.getRemainingStock(product)).toBe(9);

// 카트에 상품 1개 더 추가
act(() => {
result.current.addToCart(product);
});

// 카트에 2개 추가된 후 재고는 8이어야 함
expect(result.current.getRemainingStock(product)).toBe(8);
});

test('검색기능 테스트', async () => {
render(<CartPage products={mockProducts} coupons={mockCoupons}/>);

test('새로운 hook 함수르 만든 후에 테스트 코드를 작성해서 실행해보세요', () => {
expect(true).toBe(false);
// 1. 검색 입력창 가져오기
const searchInput = await screen.getByTestId('search-bar');

Check failure on line 270 in src/advanced/__tests__/advanced.test.tsx

View workflow job for this annotation

GitHub Actions / advacned

src/advanced/__tests__/advanced.test.tsx > advanced > > 자유롭게 작성해보세요. > 검색기능 테스트

TestingLibraryElementError: Unable to find an element by: [data-testid="search-bar"] Ignored nodes: comments, script, style <body> <div> <div class="container mx-auto p-4" > <h1 class="text-3xl font-bold mb-6" > 장바구니 </h1> <div class="grid grid-cols-1 md:grid-cols-2 gap-6" > <div> <h2 class="text-2xl font-semibold mb-4" > 상품 목록 </h2> <input class="w-full mb-4 p-2 border rounded" placeholder="검색어를 입력하세요" type="text" value="" /> <div class="space-y-2" > <div class="bg-white p-3 rounded shadow" data-testid="product-p1" > <div class="flex justify-between items-center mb-2" > <span class="font-semibold" > 상품1 </span> <span class="text-gray-600" > 10,000 원 </span> </div> <div class="text-sm text-gray-500 mb-2" > <span class="font-medium text-green-600" > 재고: 20 개 </span> <span class="ml-2 font-medium text-blue-600" > 최대 10 % 할인 </span> </div> <ul class="list-disc list-inside text-sm text-gray-500 mb-2" > <li> 10 개 이상: 10 % 할인 </li> </ul> <button class="w-full px-3 py-1 rounded bg-blue-500 text-white hover:bg-blue-600" > 장바구니에 추가 </button> </div> <div class="bg-white p-3 rounded shadow" data-testid="product-p2" > <div class="flex justify-between items-center mb-2" > <span class="font-semibold" > 상품2 </span> <span class="text-gray-600" > 20,000 원 </span> </div> <div class="text-sm text-gray-500 mb-2" > <span class="font-medium text-green-600" > 재고: 20 개 </span> <span class="ml-2 font-medium text-blue-600" > 최대 15 % 할인 </span> </div> <ul class="list-disc list-inside text-sm text-gray-500 mb-2" > <li> 10 개 이상: 15 % 할인 </li> </ul> <button class="w-full px-3 py-1 rounded bg-blue-500 text-white hover:bg-blue-600" > 장바구니에 추가 </button> </div> <div class="bg-white p-3 rounded shadow" data-testid="product-p3" > <div class="flex justify-between items-center mb-2" > <span class="font-semibold" > 상품3 </span> <span class="text-gray-600" > 30,000 원 </span> </div>

// 2. 기본 상태에서 상품 목록이 모두 표시되는지 확인

expect(await screen.findByTestId('product-p1')).toBeInTheDocument();
expect(await screen.findByTestId('product-p2')).toBeInTheDocument();
expect(await screen.findByTestId('product-p3')).toBeInTheDocument();

// 3. 검색어 입력 후 필터링 결과 확인
await act(async () => {
fireEvent.change(searchInput, { target: { value: '상품1' } }); // 검색어 입력: "상품1"
});

expect(await screen.findByTestId('product-p1')).toBeInTheDocument();
expect(screen.queryByTestId('product-p2')).not.toBeInTheDocument();
expect(screen.queryByTestId('product-p3')).not.toBeInTheDocument();

// 4. 검색어 변경 후 필터링 결과 확인
await act(async () => {
fireEvent.change(searchInput, { target: { value: '' } }); // 검색어 초기화
fireEvent.change(searchInput, { target: { value: '상품2' } }); // 검색어 입력: "상품2"
});

expect(screen.queryByTestId('product-p1')).not.toBeInTheDocument();
expect(await screen.findByTestId('product-p2')).toBeInTheDocument();
expect(screen.queryByTestId('product-p3')).not.toBeInTheDocument();

// 5. 검색어가 없을 때 전체 목록이 다시 표시되는지 확인
await act(async () => {
fireEvent.change(searchInput, { target: { value: '' } }); // 검색어 초기화
});

expect(await screen.findByTestId('product-p1')).toBeInTheDocument();
expect(await screen.findByTestId('product-p2')).toBeInTheDocument();
expect(await screen.findByTestId('product-p3')).toBeInTheDocument();
})
})
})
Expand Down
2 changes: 1 addition & 1 deletion src/basic/__tests__/basic.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -515,4 +515,4 @@ describe("basic > ", () => {
expect(total.totalDiscount).toBe(20);
});
});
});
});
41 changes: 23 additions & 18 deletions src/refactoring/App.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { useState } from 'react';
import { CartPage } from './components/CartPage.tsx';
import { AdminPage } from './components/AdminPage.tsx';
import { Coupon, Product } from '../types.ts';
import { useState } from "react";
import { CartPage } from "./components/CartPage.tsx";
import { AdminPage } from "./components/AdminPage.tsx";
import { Coupon, Product } from "../types.ts";
import { useCoupons, useProducts } from "./hooks";

const initialProducts: Product[] = [
{
id: 'p1',
name: '상품1',
id: "p1",
name: "상품1",
price: 10000,
stock: 20,
discounts: [{ quantity: 10, rate: 0.1 }, { quantity: 20, rate: 0.2 }]
},
{
id: 'p2',
name: '상품2',
id: "p2",
name: "상품2",
price: 20000,
stock: 20,
discounts: [{ quantity: 10, rate: 0.15 }]
},
{
id: 'p3',
name: '상품3',
id: "p3",
name: "상품3",
price: 30000,
stock: 20,
discounts: [{ quantity: 10, rate: 0.2 }]
Expand All @@ -30,15 +30,15 @@ const initialProducts: Product[] = [

const initialCoupons: Coupon[] = [
{
name: '5000원 할인 쿠폰',
code: 'AMOUNT5000',
discountType: 'amount',
name: "5000원 할인 쿠폰",
code: "AMOUNT5000",
discountType: "amount",
discountValue: 5000
},
{
name: '10% 할인 쿠폰',
code: 'PERCENT10',
discountType: 'percentage',
name: "10% 할인 쿠폰",
code: "PERCENT10",
discountType: "percentage",
discountValue: 10
}
];
Expand All @@ -47,6 +47,7 @@ const App = () => {
const { products, updateProduct, addProduct } = useProducts(initialProducts);
const { coupons, addCoupon } = useCoupons(initialCoupons);
const [isAdmin, setIsAdmin] = useState(false);
const [selectedCoupon, setSelectedCoupon] = useState<Coupon | null>(null);

return (
<div className="min-h-screen bg-gray-100">
Expand All @@ -57,7 +58,7 @@ const App = () => {
onClick={() => setIsAdmin(!isAdmin)}
className="bg-white text-blue-600 px-4 py-2 rounded hover:bg-blue-100"
>
{isAdmin ? '장바구니 페이지로' : '관리자 페이지로'}
{isAdmin ? "장바구니 페이지로" : "관리자 페이지로"}
</button>
</div>
</nav>
Expand All @@ -71,7 +72,11 @@ const App = () => {
onCouponAdd={addCoupon}
/>
) : (
<CartPage products={products} coupons={coupons}/>
<CartPage
products={products}
coupons={coupons}
selectedCoupon={selectedCoupon}
setSelectedCoupon={setSelectedCoupon} />
)}
</main>
</div>
Expand Down
Loading
Loading