Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
ca38bae
관리자 페이지 수정
hafskjfha Jun 2, 2025
3bcdc31
Merge pull request #54 from hafskjfha/bug/issue52
hafskjfha Jun 2, 2025
779e1b1
#59 일부 처리
hafskjfha Jun 11, 2025
6d1d499
#65 긴급
hafskjfha Jun 11, 2025
e8e9cf7
Merge pull request #67 from hafskjfha/refactor/words-docs
hafskjfha Jun 11, 2025
f863a1b
Merge pull request #69 from hafskjfha/main
hafskjfha Jun 14, 2025
a9ed410
관리자 페이지 리펙토링 - 승인 부분 수정
hafskjfha Jun 14, 2025
b0d4b7b
lint 수정
hafskjfha Jun 14, 2025
fe8d7fd
f
hafskjfha Jun 14, 2025
588aa1c
Merge pull request #70 from hafskjfha/refactor/words-docs
hafskjfha Jun 14, 2025
ac2b959
DI 패턴 적용 해보기
hafskjfha Jun 15, 2025
90ac684
유저 페이지 수정 - 불필요한 코드 삭제
hafskjfha Jun 15, 2025
1eb656d
관리자 페이지 - 거절 처리 만들기
hafskjfha Jun 15, 2025
86d24df
오픈 DB - 로그 페이지 최적화
hafskjfha Jun 15, 2025
a498964
관리자 페이지 - 추가 요청 처리 자동화
hafskjfha Jun 15, 2025
fcdc0ce
관리자 페이지 - 대량 삭제 일부
hafskjfha Jun 15, 2025
bcfddff
fuck
hafskjfha Jun 15, 2025
1820ac2
Merge pull request #71 from hafskjfha/refactor/words-docs
hafskjfha Jun 15, 2025
a532a89
관리자 페이지 - 논리적 오류 수정
hafskjfha Jun 15, 2025
ae2b733
Merge pull request #72 from hafskjfha/refactor/words-docs
hafskjfha Jun 15, 2025
0cf68f6
관리자 페이지 - 버그 수정
hafskjfha Jun 16, 2025
048f6d2
Merge pull request #73 from hafskjfha/refactor/words-docs
hafskjfha Jun 16, 2025
ce1a46b
관리자 페이지 - 오류 수정
hafskjfha Jun 17, 2025
76aa887
관리자 페이지 - 오류 수정
hafskjfha Jun 17, 2025
30304d9
Merge pull request #74 from hafskjfha/refactor/words-docs
hafskjfha Jun 17, 2025
8291330
관리자 페이지 - 버그 수정
hafskjfha Jun 17, 2025
4eb689a
관리자 페이지 - 버그 수정
hafskjfha Jun 17, 2025
14599fa
Merge pull request #75 from hafskjfha/refactor/words-docs
hafskjfha Jun 17, 2025
fc7c838
테스트 - 기본 설정
hafskjfha Jun 19, 2025
cd586b1
테스트 - 파일업로드 부분 테스트
hafskjfha Jun 19, 2025
9ee6f73
테스트 - 기본 설정 업데이트
hafskjfha Jun 20, 2025
7f5b583
테스트 - endx 테스트
hafskjfha Jun 20, 2025
8f17f05
테스트 - LenX 테스트
hafskjfha Jun 20, 2025
545b0b0
테스트 - 설정 수정
hafskjfha Jun 20, 2025
306c8f8
테스트 - 테스트코드 약간 수정
hafskjfha Jun 20, 2025
39a4c77
필요없는 파일 삭제
hafskjfha Jun 20, 2025
dc9be40
테스트 - StartX 테스트
hafskjfha Jun 20, 2025
6f1965b
DB매니저 수정
hafskjfha Jun 22, 2025
135e299
단어장 공유 - 정보 표시 주석 작업
hafskjfha Jun 22, 2025
f579f31
단어장 공유 - 로그 주석 추가
hafskjfha Jun 22, 2025
c419153
단어장 공유 - 자잘한것 주석 추가
hafskjfha Jun 22, 2025
09e9922
단어장 공유 - 문서 단어 정보 가져오기 일부 수정
hafskjfha Jun 22, 2025
d2f494b
Merge branch 'refactor/words-docs' of https://github.com/hafskjfha/kk…
hafskjfha Jun 22, 2025
ce22d61
테스트 merge 테스트, 근데 왜 pass이지만 에러?
hafskjfha Jun 25, 2025
c04ea0f
merge테스트 - 코드 수정
hafskjfha Jun 25, 2025
5bcfcad
테스트 - __tests__디렉토리 구조 변경
hafskjfha Jun 25, 2025
7bdfd85
테스트 - 코드 수정
hafskjfha Jun 25, 2025
0ad1c22
테스트 - Loop 테스트
hafskjfha Jun 25, 2025
c5e4a23
테스트 - main푸시전 테스트 자동화
hafskjfha Jun 28, 2025
4c8787e
단어장 공유 - 문서 단어 정보 가져오기 수정
hafskjfha Jun 28, 2025
ef4e9c5
단어장 공유 - 파일 이름 변경 (혼동 줄이기 위해)
hafskjfha Jun 28, 2025
8d00eb2
단어장 공유 - 기타 문서 부분 삭제 자세한건 #76 확인
hafskjfha Jun 29, 2025
c6e3f91
오픈 DB - 필요없는 문서 추가요청 삭제
hafskjfha Jun 29, 2025
ebd65d4
단어장 공유 - Table 리펙토링
hafskjfha Jun 29, 2025
2ac900a
단어장 공유 - Home에서 SCM사용 및 주석 약간 추가
hafskjfha Jun 29, 2025
43bcbd7
단어장 공유 - SCM교체, 필요없는 함수 제거
hafskjfha Jun 29, 2025
c881059
단어장 공유 - 대기큐 추가 함수 수정
hafskjfha Jun 29, 2025
e2c12b2
오픈 DB = 단어 추가 도움말 추가 + SCM적용
hafskjfha Jun 29, 2025
3d10175
단어조합기 - 도움말 모달 추가, 단어 다운로드 함수 + 캐싱 추가
hafskjfha Jun 29, 2025
b49bbd4
오픈 DB - 캐싱 추가
hafskjfha Jun 29, 2025
00f4480
오픈 DB - 단어 대량 추가 밑작업
hafskjfha Jun 29, 2025
de3b2be
단어장 관리 - 길이순정렬 추가
hafskjfha Jun 29, 2025
33f43eb
lint 수정
hafskjfha Jun 29, 2025
be6dd95
관리자 페이지 - SCM 관련 수정
hafskjfha Jun 29, 2025
d90c37e
Merge pull request #78 from hafskjfha/refactor/words-docs
hafskjfha Jun 29, 2025
b1f34ea
Assistant checkpoint: Create EnglishMission test file based on EndX test
hafskjfha Jul 3, 2025
976275e
Restored to 'c5e4a234dc9799dfb11f73209c234f9e3d5a19f6'
hafskjfha Jul 3, 2025
0f1cb27
테스트 - eng미션
hafskjfha Jul 3, 2025
d3c86e4
테스트- eng미션 수정
hafskjfha Jul 4, 2025
e5e4577
테스트 - kor미션B
hafskjfha Jul 4, 2025
14f6286
기타기능, 오픈DB - 홈부분 디자인 변경
hafskjfha Jul 6, 2025
83d6b1b
공통 - 다크모드 on/off추가
hafskjfha Jul 6, 2025
4cb6d03
단어장 관리 - 에디터 다크모드 적용 및 정렬 v3추가
hafskjfha Jul 6, 2025
bb23427
다크모드 - 공용 컴포넌트
hafskjfha Jul 6, 2025
bfd5558
오픈DB - 다크모드 적용
hafskjfha Jul 6, 2025
2954530
오픈DB - 다크모드 적용
hafskjfha Jul 6, 2025
a034a74
공통 - next-theme사용
hafskjfha Jul 6, 2025
3551cfe
단어장 관리 - 다크모드 지원
hafskjfha Jul 6, 2025
360f10b
테스트 - kor미션A
hafskjfha Jul 7, 2025
885e61d
깃허브 자동테스트 업데이트
hafskjfha Jul 7, 2025
6f8e616
깃허브 자동테스트 업데이트
hafskjfha Jul 7, 2025
dd1a057
Merge pull request #79 from hafskjfha/test
hafskjfha Jul 7, 2025
920eb70
오픈 DB - 다크모드 지원 완료
hafskjfha Jul 8, 2025
ef49be0
프로필 페이지 - 다크 모드 지원
hafskjfha Jul 8, 2025
a81624c
관리자 페이지 - 다크모드 지원
hafskjfha Jul 8, 2025
a2e53ff
단어장 공유 - 홈, 문서 일반 다크모드 적용
hafskjfha Jul 8, 2025
45f901d
단어장 공유 - 문서 로그 / 정보 다크모드 적용
hafskjfha Jul 8, 2025
ba14fc8
오픈 DB - 단어 삭제 요청 or 요청 취소시 완료모달에 잘못된 글자 표시 수정
hafskjfha Jul 8, 2025
66029e4
단어장 공유 - 글자 문서 추가 요청 버튼 추가
hafskjfha Jul 8, 2025
3e65c3d
관리자 페이지 - 문서 추가 요청 처리 추가
hafskjfha Jul 8, 2025
0cf4a3f
릴리즈 노트 - scm사용
hafskjfha Jul 8, 2025
b5db9fc
auth - scm적용
hafskjfha Jul 8, 2025
5f2ef6e
프로필 - scm사용
hafskjfha Jul 8, 2025
2a0b412
닉네임 변경 처리 api 엔드 포인트 수정
hafskjfha Jul 8, 2025
71f8ff6
오픈 DB - 오버플포우 버그 수정
hafskjfha Jul 8, 2025
8497cbe
hotfix
hafskjfha Jul 8, 2025
cfae110
hotfix/2 #81
hafskjfha Jul 8, 2025
55dbe7b
hotfix
hafskjfha Jul 8, 2025
34c91b6
오픈 DB - 임시 (단삭 요청시 추가요청큐에 word_id넣기)
hafskjfha Jul 8, 2025
f830cbc
관리자 페이지 - scm사용 > 홈, 요청목록
hafskjfha Jul 8, 2025
ef3d0e5
관리자 페이지 - 추가, 삭제
hafskjfha Jul 8, 2025
bf7583e
로그아웃 scm적용
hafskjfha Jul 8, 2025
a2a9b15
오픈 DB - scm사용
hafskjfha Jul 8, 2025
4b4f15d
문서 정리
hafskjfha Jul 9, 2025
af6acc1
오픈 DB - 검색 부분 scm적용
hafskjfha Jul 9, 2025
e86ef5d
오픈 DB - 남은것 scm적용
hafskjfha Jul 9, 2025
49f5740
오픈 DB - 검색 부분 오타 수정
hafskjfha Jul 9, 2025
0a70206
함수 네이밍 규칙에 맞게 수정
hafskjfha Jul 9, 2025
580fe7a
오픈DB - 단어정보 표시하는 곳에 단어 검색 바 추가
hafskjfha Jul 9, 2025
33b84dd
오픈 DB - 단어 추가 폼 컴포넌트로 분리
hafskjfha Jul 9, 2025
9ef9342
단어장 공유 - lint 수정
hafskjfha Jul 10, 2025
4c5d271
오픈 DB - 단어 대량 추가 추가
hafskjfha Jul 10, 2025
9faf13a
Merge remote-tracking branch 'origin/main' into refactor/words-docs
hafskjfha Jul 10, 2025
5cf6d32
xlsx버전 수정
hafskjfha Jul 10, 2025
40dfb50
Merge pull request #83 from hafskjfha/refactor/words-docs
hafskjfha Jul 10, 2025
793a270
단어장 관리 도구 - sortv3 버그 수정
hafskjfha Jul 11, 2025
ba7154f
Merge pull request #85 from hafskjfha/bug/84
hafskjfha Jul 11, 2025
96ff7dc
버그 수정 + 관리자 페이지 요청수 표시 수정
hafskjfha Jul 15, 2025
d56d969
Update SupabaseClientManager.ts
hafskjfha Jul 15, 2025
a1b49ef
Merge pull request #87 from hafskjfha/bug/86
hafskjfha Jul 15, 2025
19ea64a
익스텐션 릴리즈 최신버전 확인 엔드포인트
hafskjfha Aug 12, 2025
87fef0d
Merge pull request #88 from hafskjfha/feature/extension-api
hafskjfha Aug 12, 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
22 changes: 22 additions & 0 deletions .github/scripts/gen-summary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const fs = require('fs');

const data = JSON.parse(fs.readFileSync('jest-results.json', 'utf-8'));
const { numTotalTests, numPassedTests, numFailedTests, testResults } = data;

let summary = `## ✅ Jest Test Summary\n`;
summary += `- Total: **${numTotalTests}**\n`;
summary += `- Passed: ✅ ${numPassedTests}\n`;
summary += `- Failed: ❌ ${numFailedTests}\n\n`;

if (numFailedTests > 0) {
summary += `### ❌ Failed Tests\n`;
testResults.forEach(file => {
file.assertionResults
.filter(test => test.status === 'failed')
.forEach(test => {
summary += `- ${test.fullName} (${file.name})\n`;
});
});
}

fs.writeFileSync('summary.md', summary);
41 changes: 41 additions & 0 deletions .github/workflows/pr-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Jest Test with Sticky Comment (Internal)

on:
pull_request:
branches: [main]

permissions:
pull-requests: write
issues: write

jobs:
test:
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest

steps:
- name: Checkout PR Code
uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18

- name: Install dependencies
run: npm ci

- name: Run Jest
run: npx jest --json --outputFile=jest-results.json
continue-on-error: true

- name: Generate Markdown Summary
run: node .github/scripts/gen-summary.js > summary.md

- name: Sticky PR Comment
uses: marocchino/sticky-pull-request-comment@v2
with:
header: jest-summary
path: summary.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ yarn-error.log*
next-env.d.ts

# Test
test/
app/test/
app/api/test
12 changes: 12 additions & 0 deletions .replit
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
modules = ["nodejs-20", "web"]
run = "npm run dev"

[nix]
channel = "stable-24_05"

[deployment]
run = ["sh", "-c", "npm run dev"]

[[ports]]
localPort = 3000
externalPort = 80
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno"
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"deno.enablePaths": [
"supabase/functions"
Expand Down
216 changes: 216 additions & 0 deletions __tests__/manager-tool/extract/EndX.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import WordExtractorApp from "@/app/manager-tool/extract/endx/EndX";
import { getOutsideHelpModal } from "@/test/utils/dom";

jest.mock("@/app/manager-tool/extract/components/FileContentDisplay", () => {
return ({ onFileUpload, fileContent, resultData, resultTitle }: any) => (
<div data-testid="file-content-display">
<div>File Content: {fileContent || "No content"}</div>
<div>Result Title: {resultTitle}</div>
<div>Result Count: {resultData?.length || 0}</div>
<button onClick={() => onFileUpload?.("test\ncontent\ndata\ntest")}>
Mock File Upload
</button>
<div data-testid="result-word">{fileContent}</div>
</div>
);
});

describe("EndX", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("초기 렌더링이 정상적으로 되는지 확인", () => {
render(<WordExtractorApp />);

expect(screen.getByText("X로 끝나는 단어 추출")).toBeInTheDocument();
expect(screen.getAllByText("설정")).toHaveLength(2);
expect(screen.getAllByText("실행")).toHaveLength(2);
});

it("끝글자 입력이 정상적으로 동작하는지 확인", async () => {
const user = userEvent.setup();
render(<WordExtractorApp />);

const wordEndInput = screen
.getAllByPlaceholderText("끝글자를 입력하세요")
.find((el) => !el.closest('[data-testid="help-modal"]'));
expect(wordEndInput).toBeDefined();
await user.type(wordEndInput!, "다");

expect(wordEndInput).toHaveValue("다");
});

it("정렬 체크박스가 정상적으로 동작하는지 확인", async () => {
const user = userEvent.setup();
render(<WordExtractorApp />);

const checkboxes = screen.getAllByTestId("checkbox");
const sortCheckbox = checkboxes.find(
(el) => !el.closest('[data-testid="help-modal"]'),
);

expect(sortCheckbox).toBeDefined(); // 혹시 못 찾을 때 대비
expect(sortCheckbox).toBeChecked();

await user.click(sortCheckbox!);
expect(sortCheckbox).not.toBeChecked();
});

it("파일 내용이 없을 때 단어 추출 버튼이 비활성화되는지 확인", () => {
render(<WordExtractorApp />);

const extractButton = getOutsideHelpModal(() =>
screen.getAllByText("단어 추출"),
);
expect(extractButton).toBeDisabled();
});

it("파일 업로드 후 단어 추출이 정상적으로 동작하는지 확인", async () => {
const user = userEvent.setup();
render(<WordExtractorApp />);

// Mock 파일 업로드
const mockUploadButton = screen.getByText("Mock File Upload");
await user.click(mockUploadButton);

// 끝글자 입력
const wordEndInput = getOutsideHelpModal(() =>
screen.getAllByPlaceholderText("끝글자를 입력하세요"),
);
await user.type(wordEndInput, "st");

// 단어 추출 실행
const extractButton = getOutsideHelpModal(() =>
screen.getAllByText("단어 추출"),
);
expect(extractButton).not.toBeDisabled();

await user.click(extractButton);

// 결과 확인 (test로 끝나는 단어가 추출되어야 함)
await waitFor(() => {
const resultDisplay = screen.getByTestId("file-content-display");
expect(resultDisplay).toHaveTextContent("Result Count: 1");
const resultWord = screen.getByTestId("result-word");
expect(resultWord).toBeInTheDocument();
expect(resultWord).toHaveTextContent("test");
});
});

it("단어 추출 결과에 따라 다운로드 버튼이 활성화되는지 확인", async () => {
const user = userEvent.setup();
render(<WordExtractorApp />);

const downloadButton = getOutsideHelpModal(() =>
screen.getAllByText("결과 다운로드"),
);
expect(downloadButton).toBeDisabled();

// Mock 파일 업로드 및 단어 추출
const mockUploadButton = screen.getByText("Mock File Upload");
await user.click(mockUploadButton);

const wordEndInput = getOutsideHelpModal(() =>
screen.getAllByPlaceholderText("끝글자를 입력하세요"),
);
await user.type(wordEndInput, "st");

const extractButton = getOutsideHelpModal(() =>
screen.getAllByText("단어 추출"),
);
await user.click(extractButton);

await waitFor(() => {
expect(downloadButton).not.toBeDisabled();
});
});

it("정렬 옵션이 제대로 적용되는지 확인", async () => {
const user = userEvent.setup();
render(<WordExtractorApp />);

// 정렬 해제
const sortCheckbox = getOutsideHelpModal(() =>
screen.getAllByTestId("checkbox"),
);
await user.click(sortCheckbox);

// Mock 파일 업로드
const mockUploadButton = screen.getByText("Mock File Upload");
await user.click(mockUploadButton);

const wordEndInput = getOutsideHelpModal(() =>
screen.getAllByPlaceholderText("끝글자를 입력하세요"),
);
await user.type(wordEndInput, "st");

const extractButton = getOutsideHelpModal(() =>
screen.getAllByText("단어 추출"),
);
await user.click(extractButton);

// 정렬이 해제된 상태에서도 단어 추출이 동작해야 함
await waitFor(() => {
expect(screen.getByText(/Result Count: 1/)).toBeInTheDocument();
});
});

it("다운로드 기능이 정상적으로 동작하는지 확인", async () => {
const user = userEvent.setup();

// URL.createObjectURL mock 설정
const createObjectURLSpy = jest.spyOn(URL, "createObjectURL");

// createElement mock 설정
const realCreateElement = document.createElement.bind(document);

const mockLink = document.createElement("a");
mockLink.click = jest.fn();

const createElementSpy = jest
.spyOn(document, "createElement")
.mockImplementation((tagName) => {
if (tagName === "a") return mockLink;
return realCreateElement(tagName);
});

render(<WordExtractorApp />);

// 단어 추출까지 완료
const mockUploadButton = screen.getByText("Mock File Upload");
await user.click(mockUploadButton);

const wordEndInput = getOutsideHelpModal(() =>
screen.getAllByPlaceholderText("끝글자를 입력하세요"),
);
await user.type(wordEndInput, "st");

const extractButton = getOutsideHelpModal(() =>
screen.getAllByText("단어 추출"),
);
await user.click(extractButton);

await waitFor(() => {
const downloadButton = getOutsideHelpModal(() =>
screen.getAllByText("결과 다운로드"),
);
expect(downloadButton).not.toBeDisabled();
});

// 다운로드 실행
const downloadButton = getOutsideHelpModal(() =>
screen.getAllByText("결과 다운로드"),
);
await user.click(downloadButton);

expect(createElementSpy).toHaveBeenCalledWith("a");
expect(createObjectURLSpy).toHaveBeenCalled();
expect(mockLink.click).toHaveBeenCalled();

createElementSpy.mockRestore();
createObjectURLSpy.mockRestore();
});
});
Loading