Skip to content

Conversation

@Chiman2937
Copy link
Member

@Chiman2937 Chiman2937 commented Dec 23, 2025

📝 변경 사항

마이페이지 - 프로필 수정 모달 테스트 코드를 작성하였습니다.
ImageInput 관련 테스트는 추후 진행 예정입니다.

    폼 제출 테스트                                                                                                                                                                                                   
      닉네임 중복 검사 테스트                                                                                                                                                                                        
        √ 닉네임 수정 시 닉네임 중복 검사가 실행된다. (357 ms)                                                                                                                                                       
        √ 중복된 닉네임일 경우 에러 메시지가 표시된다. (263 ms)                                                                                                                                                      
        √ 닉네임이 변경되지 않으면 중복 검사를 하지 않는다. (248 ms)                                                                                                                                                 
      MBTI 제출 테스트                                                                                                                                                                                               
        √ MBTI가 대문자로 변환되어 전송된다. (215 ms)                                                                                                                                                                
      API 호출 테스트                                                                                                                                                                                                
        √ 이미지가 변경되지 않으면 updateMyImage API가 호출되지 않는다. (602 ms)                                                                                                                                     
      제출 버튼 상태 테스트                                                                                                                                                                                          
        √ 제출 중일 때 버튼이 "수정 중..."으로 변경되며 비활성화 된다 (228 ms)

🔗 관련 이슈

Closes #


🧪 테스트 방법

  • 수동 테스트 검증(로컬 환경)
  • 유닛 테스트 검증
  • 통합 테스트 검증

📸 스크린샷 (선택)


📋 체크리스트

  • 관련 문서를 업데이트했습니다 (필요한 경우)
  • 테스트를 추가/수정했습니다 (필요한 경우)
  • Breaking change가 있다면 명시했습니다

💬 추가 코멘트


CodeRabbit Review는 자동으로 실행되지 않습니다.

Review를 실행하려면 comment에 아래와 같이 작성해주세요

@coderabbitai review

Summary by CodeRabbit

릴리스 노트

  • Bug Fixes

    • 닉네임 중복 오류 메시지의 텍스트 표기 방식을 수정했습니다.
  • Tests

    • 사용자 프로필 관련 테스트 케이스를 확장했습니다.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

API 요청 파라미터 전달 방식을 쿼리 문자열에서 요청 본문 객체로 변경하고, 사용자 팔로우/언팔로우, 알림 설정, 닉네임 및 이메일 가용성 확인을 위한 MSW 모킹을 추가했으며, 프로필 편집 모달 테스트를 확장했습니다.

Changes

코호트 / 파일(s) 변경 요약
API 서비스 수정
src/api/service/user-service/index.ts
updateMyNotification 메서드가 PATCH 요청 시 쿼리 문자열 대신 params 객체를 통해 모든 파라미터 전달
getNicknameAvailability 메서드가 스프레드 연산자로 전체 queryParams 객체 전달
프로필 편집 모달 테스트
src/components/pages/user/profile/profile-edit-modal/index.test.tsx
msw, 모킹 유틸리티 임포트 추가
폼 제출 테스트 블록 중복 추가 (닉네임 중복 검사, MBTI 정규화, API 호출, 제출 버튼 상태 관련 동일 테스트 2회 반복)
프로필 편집 모달 UI
src/components/pages/user/profile/profile-edit-modal/index.tsx
닉네임 중복 검증 에러 메시지 텍스트 변경 ("이미 사용 중인 닉네임 입니다" → "이미 사용중인 닉네임 입니다")
사용자 관련 MSW 모킹
src/mock/service/user/user-handler.ts
5개 신규 모킹 추가: followUserMock (팔로우), unfollowUserMock (언팔로우), updateMyNotificationMock (알림 토글), getNicknameAvailabilityMock (닉네임 가용성), getEmailAvailabilityMock (이메일 가용성)
getUserItemMock에 404 응답 경로 추가
userHandlers 내보내기 확장

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 분

Possibly related PRs

Suggested reviewers

  • wooktori
  • yoorli

Poem

🐰 팔로우 버튼이 쏙, 언팔로우도 쏙,
닉네임 체크는 민첩하게 쌕,
알림은 토글, 모킹은 완벽,
API 파라미터는 깔끔하게 정렬,
이제 사용자 기능은 톡톡 튀어! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 마이페이지 프로필 수정 모달의 폼 제출 테스트 코드 작성이라는 주요 변경사항을 명확하게 설명하고 있습니다.
Description check ✅ Passed PR 설명은 변경사항 섹션에서 테스트 코드 작성 내용을 설명하고 있으며, 테스트 방법에서 통합 테스트 검증을 완료했음을 표시했습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot requested a review from wooktori December 23, 2025 08:53
@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🎭 Playwright Report

E2E Test가 성공적으로 완료되었습니다.

Test 요약 내용을 확인해주세요.

Status Build Log Updated (UTC)
✅ Ready View Build 2025-12-23 12:43:30

📊 Test Summary

  • ✅ Passed: 3
  • ❌ Failed: 0
  • ⏱️ Duration: 34.5s

📜 Test Details

✅ Passed Tests (3)
  • profile.test.ts (3)
    • [chromium] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트
    • [firefox] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트
    • [webkit] 존재하지 않는 프로필 페이지로 접속 시 404 redirect 되는 지 테스트

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

📊 Coverage Report

Status Build Log Updated (UTC)
✅ Ready View Build 2025-12-23 12:42:19

📈 #230main에 병합하면 coverage가 0.60% 증가합니다.

Coverage 요약

@@             Coverage Diff             @@
##             main     #230       +/-   ##
===========================================
+ Coverage   38.32%   38.92%    +0.60%     
===========================================
  Files         165      165         0     
  Lines        7266     7357       +91     
  Branches      301      325       +24     
===========================================
+ Hits         2785     2864       +79     
+ Misses       4481     4493       +12     

영향받은 파일

파일 Coverage 변화
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/api/core/index.ts 49.13% (+2.58%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/api/service/user-service/index.ts 70.66% (+8.00%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/components/pages/user/profile/profile-edit-modal/index.tsx 95.71% (+27.14%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/hooks/use-user/use-user-update/index.ts 100.00% (+11.77%) ⬆️
/home/runner/work/WeGo_FrontEnd/WeGo_FrontEnd/src/mock/service/user/user-handler.ts 42.10% (-13.63%) ⬇️

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🎨 Storybook Report

변경 사항이 없습니다

모든 Story가 이전 빌드와 동일합니다.

Status Storybook Build Log Updated (UTC)
✅ Unchanged View Storybook View Build 2025-12-23 12:44:14

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🚀 PR Preview Report

Build가 성공적으로 완료되었습니다.

Preview에서 변경사항을 확인하세요.

Status Preview Build Log Updated (UTC)
✅ Ready Visit Preview View Logs 2025-12-23 12:43:25

@Chiman2937 Chiman2937 added the Ready For Review! 리뷰 받을 준비가 되었습니다. label Dec 23, 2025
@Chiman2937
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
src/components/pages/user/profile/profile-edit-modal/index.test.tsx (1)

262-408: 테스트 구조의 명확성을 개선해주세요.

"폼 제출 테스트"라는 새로운 describe 블록이 추가되었지만, 기존 테스트와의 관계가 명확하지 않습니다:

  1. "제출 버튼 상태 테스트"가 중복됩니다:

    • 기존: Lines 224-259 (유효성 검사 기반 버튼 상태)
    • 신규: Lines 379-408 (제출 중 버튼 상태)
    • 동일한 describe 이름이지만 다른 시나리오를 테스트하고 있어 혼란을 줄 수 있습니다.
  2. 테스트 조직화 개선 제안:

    • 최상위 레벨에 "폼 제출 테스트"를 추가하는 대신, 관련 테스트들을 기존 구조에 통합하는 것을 고려해보세요.
    • 예: "제출 버튼 상태 테스트"를 "제출 버튼 - 유효성 검사 상태"와 "제출 버튼 - 제출 중 상태"로 구분
🔎 제안: 테스트 구조 개선안

다음과 같이 재구성을 고려해보세요:

  describe('유효성 검사 테스트', () => {
    // ... 기존 유효성 검사 테스트들 ...
    
-   describe('제출 버튼 상태 테스트', () => {
+   describe('제출 버튼 - 유효성 검사 상태', () => {
      test('유효성 검사 성공 시 제출 버튼이 활성화 된다.', ...);
      test('유효성 검사 실패 시 제출 버튼이 비활성화 된다.', ...);
    });
  });
  
  describe('폼 제출 테스트', () => {
    describe('닉네임 중복 검사 테스트', () => { ... });
    describe('MBTI 제출 테스트', () => { ... });
    describe('API 호출 테스트', () => { ... });
-   describe('제출 버튼 상태 테스트', () => {
+   describe('제출 버튼 - 제출 중 상태', () => {
      test('제출 중일 때 버튼이 "수정 중..."으로 변경되며 비활성화 된다', ...);
    });
  });
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c47b196 and 74cea58.

📒 Files selected for processing (4)
  • src/api/service/user-service/index.ts
  • src/components/pages/user/profile/profile-edit-modal/index.test.tsx
  • src/components/pages/user/profile/profile-edit-modal/index.tsx
  • src/mock/service/user/user-handler.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-17T09:40:37.733Z
Learnt from: HopeFullee
Repo: WeGo-Together/WeGo_FrontEnd PR: 205
File: src/components/pages/post-meetup/fields/cap-field/index.tsx:47-47
Timestamp: 2025-12-17T09:40:37.733Z
Learning: In TanStack Form with Zod validation, when field.state.meta.isValid is false, field.state.meta.errors is guaranteed to have at least one entry. Therefore, in an isInvalid check defined as field.state.meta.isTouched && !field.state.meta.isValid, safely access field.state.meta.errors[0] without extra null/empty checks. This guideline applies to TSX form fields under src/components/pages (and similar forms using the same pattern).

Applied to files:

  • src/components/pages/user/profile/profile-edit-modal/index.test.tsx
  • src/components/pages/user/profile/profile-edit-modal/index.tsx
🧬 Code graph analysis (3)
src/components/pages/user/profile/profile-edit-modal/index.test.tsx (6)
src/api/index.ts (1)
  • API (22-22)
src/components/pages/user/profile/profile-edit-modal/index.tsx (1)
  • ProfileEditModal (30-140)
src/mock/server.ts (1)
  • server (5-5)
src/types/service/user.ts (1)
  • User (1-15)
src/mock/service/common/common-mock.ts (1)
  • createMockSuccessResponse (3-7)
src/mock/service/user/user-mock.ts (1)
  • mockUserItems (3-52)
src/api/service/user-service/index.ts (2)
src/api/core/index.ts (1)
  • apiV1 (115-115)
src/types/service/user.ts (1)
  • User (1-15)
src/mock/service/user/user-handler.ts (3)
src/mock/service/user/user-mock.ts (1)
  • mockUserItems (3-52)
src/mock/service/common/common-mock.ts (2)
  • createMockSuccessResponse (3-7)
  • createMockErrorResponse (15-26)
src/types/service/user.ts (1)
  • User (1-15)
🔇 Additional comments (5)
src/components/pages/user/profile/profile-edit-modal/index.tsx (1)

53-53: LGTM! 에러 메시지 텍스트가 일관성 있게 수정되었습니다.

띄어쓰기와 마침표가 조정되어 일관된 형식을 유지합니다. 테스트 코드의 기대값과도 일치합니다.

src/components/pages/user/profile/profile-edit-modal/index.test.tsx (1)

4-11: 새로운 테스트 유틸리티 import가 추가되었습니다.

MSW를 활용한 API 모킹과 타입 안전성을 위한 import들이 적절히 추가되었습니다.

src/api/service/user-service/index.ts (2)

37-39: LGTM! 쿼리 파라미터 전달 방식이 일관되게 개선되었습니다.

params 객체를 사용한 쿼리 파라미터 전달 방식으로 변경되어 다른 API 메서드들과 일관성을 유지합니다.


52-54: LGTM! 쿼리 파라미터 구조가 개선되었습니다.

spread 연산자를 사용하여 queryParams 전체를 전달하는 방식으로 변경되어 더 유연하고 유지보수가 용이합니다.

src/mock/service/user/user-handler.ts (1)

45-54: LGTM! 프로필 업데이트 모킹이 적절히 구현되었습니다.

요청 본문을 기존 사용자 데이터와 병합하여 반환하는 로직이 올바르게 구현되었습니다.

Comment on lines 8 to 43
// 1. 팔로우 등록 모킹
const followUserMock = http.post(`*/users/follow`, async ({ request }) => {
const url = new URL(request.url);
const followNickname = url.searchParams.get('followNickname');
const user = mockUserItems.find((v) => v.nickName === followNickname);

if (user?.isFollow === false) {
return HttpResponse.json(
createMockSuccessResponse({
...user,
status: 201,
data: '팔로우 성공',
}),
);
}

if (user?.isFollow === null) {
return HttpResponse.json(
createMockErrorResponse({
status: 400,
detail: '회원 : 자기 자신을 팔로우할 수 없습니다.',
errorCode: 'NOT_SAME_FOLLOW',
}),
);
}

if (user?.isFollow === true) {
return HttpResponse.json(
createMockErrorResponse({
status: 400,
detail: '회원 : 이미 팔로우 중입니다.',
errorCode: 'ALREADY_EXIST_FOLLOW',
}),
);
}
});
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

팔로우 상태 로직이 반대로 구현되어 있습니다.

현재 구현에서 isFollow === false일 때 "팔로우 성공"을 반환하고 있지만, 이는 반대입니다:

  • isFollow === false: 이미 팔로우하지 않은 상태 → 팔로우를 추가해야 함 ✅
  • isFollow === true: 이미 팔로우 중 → 에러를 반환해야 함 ✅

하지만 실제 팔로우 로직과 상태 업데이트가 누락되어 있습니다. 현재는 단순히 기존 user 객체를 반환만 하고, isFollow 상태를 true로 변경하지 않습니다.

🔎 수정 제안
 const followUserMock = http.post(`*/users/follow`, async ({ request }) => {
   const url = new URL(request.url);
   const followNickname = url.searchParams.get('followNickname');
   const user = mockUserItems.find((v) => v.nickName === followNickname);
+
+  if (!user) {
+    return HttpResponse.json(
+      createMockErrorResponse({
+        status: 404,
+        detail: '존재하지 않는 사용자입니다.',
+        errorCode: 'USER_NOT_FOUND',
+      }),
+      { status: 404 },
+    );
+  }

-  if (user?.isFollow === false) {
+  if (user.isFollow === false) {
+    // 팔로우 상태 업데이트 (실제로는 mockUserItems 업데이트 필요)
     return HttpResponse.json(
-      createMockSuccessResponse({
-        ...user,
-        status: 201,
-        data: '팔로우 성공',
-      }),
+      createMockSuccessResponse('팔로우 성공'),
+      { status: 201 },
     );
   }

-  if (user?.isFollow === null) {
+  if (user.nickName === mockUserItems[0].nickName) {
     return HttpResponse.json(
       createMockErrorResponse({
         status: 400,
         detail: '회원 : 자기 자신을 팔로우할 수 없습니다.',
         errorCode: 'NOT_SAME_FOLLOW',
       }),
+      { status: 400 },
     );
   }

-  if (user?.isFollow === true) {
+  if (user.isFollow === true) {
     return HttpResponse.json(
       createMockErrorResponse({
         status: 400,
         detail: '회원 : 이미 팔로우 중입니다.',
         errorCode: 'ALREADY_EXIST_FOLLOW',
       }),
+      { status: 400 },
     );
   }
 });

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 로직에 오류가 있었습니다.

기존 createMockSuccessReponse 함수가 아래와 같이 구성되어있기 때문에,

export const createMockSuccessResponse = <T>(data: T): CommonSuccessResponse<T> => ({
  status: 200,
  success: true,
  data,
});

아래와 같이 팔로우 성공 응답을 수정하려고 합니다.
실제 api에서 팔로우를 성공할 때 user data를 반환하지 않습니다.

  if (user?.isFollow === false) {
    return HttpResponse.json(createMockSuccessResponse('팔로우 성공'));
  }

또한, isFollow가 false일때만 팔로우 요청이 성공해야하기 때문에 이 방식이 맞습니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Chiman2937, 설명해주셔서 감사합니다! isFollow === false가 "현재 팔로우하지 않은 상태"를 의미한다는 점과 실제 API가 팔로우 성공 시 사용자 데이터를 반환하지 않는다는 점을 이해했습니다.

제안하신 방식이 실제 API 동작과 일치하므로 적절합니다:

if (user?.isFollow === false) {
  return HttpResponse.json(createMockSuccessResponse('팔로우 성공'));
}

한 가지 추가로 고려할 점은, 현재 mock은 mockUserItems 배열의 isFollow 상태를 업데이트하지 않기 때문에, 동일 테스트 내에서 연속적으로 팔로우 상태를 확인하는 경우 이전 상태가 유지됩니다. 테스트 시나리오에서 상태 지속성이 필요하지 않다면 현재 구현으로 충분합니다.


✏️ Learnings added
Learnt from: Chiman2937
Repo: WeGo-Together/WeGo_FrontEnd PR: 230
File: src/mock/service/user/user-handler.ts:8-43
Timestamp: 2025-12-23T09:36:26.773Z
Learning: In the WeGo_FrontEnd repository's user mock handlers (src/mock/service/user/user-handler.ts), the follow API mock should return only a success message without user data using createMockSuccessResponse('팔로우 성공'), as the actual API doesn't return user data on successful follow.

Learnt from: Chiman2937
Repo: WeGo-Together/WeGo_FrontEnd PR: 230
File: src/mock/service/user/user-handler.ts:8-43
Timestamp: 2025-12-23T09:36:26.774Z
Learning: In the WeGo_FrontEnd repository, isFollow === false represents "not currently following" state, meaning a follow action is allowed and should succeed.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines 56 to 67
// 4. 알림 설정 변경 모킹
const updateMyNotificationMock = http.patch(`*/users/notification`, async ({ request }) => {
const url = new URL(request.url);
const isNotificationEnabled = url.searchParams.get('isNotificationEnabled');

return HttpResponse.json(
createMockSuccessResponse({
...mockUserItems[0],
isNotificationEnabled,
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

쿼리 파라미터의 타입 변환이 필요합니다.

Line 59에서 url.searchParams.get('isNotificationEnabled')string | null을 반환하지만, User 타입의 isNotificationEnabledboolean이어야 합니다. 이로 인해 타입 불일치가 발생합니다.

🔎 수정 제안
 const updateMyNotificationMock = http.patch(`*/users/notification`, async ({ request }) => {
   const url = new URL(request.url);
-  const isNotificationEnabled = url.searchParams.get('isNotificationEnabled');
+  const isNotificationEnabled = url.searchParams.get('isNotificationEnabled') === 'true';

   return HttpResponse.json(
     createMockSuccessResponse({
       ...mockUserItems[0],
       isNotificationEnabled,
     }),
   );
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 4. 알림 설정 변경 모킹
const updateMyNotificationMock = http.patch(`*/users/notification`, async ({ request }) => {
const url = new URL(request.url);
const isNotificationEnabled = url.searchParams.get('isNotificationEnabled');
return HttpResponse.json(
createMockSuccessResponse({
...mockUserItems[0],
isNotificationEnabled,
}),
);
});
// 4. 알림 설정 변경 모킹
const updateMyNotificationMock = http.patch(`*/users/notification`, async ({ request }) => {
const url = new URL(request.url);
const isNotificationEnabled = url.searchParams.get('isNotificationEnabled') === 'true';
return HttpResponse.json(
createMockSuccessResponse({
...mockUserItems[0],
isNotificationEnabled,
}),
);
});
🤖 Prompt for AI Agents
In src/mock/service/user/user-handler.ts around lines 56 to 67, the handler
reads isNotificationEnabled with url.searchParams.get which returns string|null
but the User type expects a boolean; convert the query value to a boolean
(handle null/default) before merging into the mock user. Parse the string
explicitly (e.g., compare to 'true' or use a safe boolean parse), provide a
sensible default when null, and assign the resulting boolean to
isNotificationEnabled so the response matches the User type.

Comment on lines +88 to +98
// 7. 닉네임 중복 검사 모킹
const getNicknameAvailabilityMock = http.get(`*/users/nickname/availability`, ({ request }) => {
const url = new URL(request.url);
const nickname = url.searchParams.get('nickname');
const user = mockUserItems.find((item) => item.nickName === nickname);
return HttpResponse.json(
createMockSuccessResponse({
data: { available: !user },
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

응답 구조가 API 타입 정의와 일치하지 않습니다.

Line 94-96에서 { data: { available: !user } } 형태로 중첩된 객체를 반환하고 있지만, createMockSuccessResponse는 이미 { status, success, data } 구조를 생성합니다. 이로 인해 최종 응답이 { status: 200, success: true, data: { data: { available: boolean } } } 형태가 되어 불필요한 중첩이 발생합니다.

🔎 수정 제안
 const getNicknameAvailabilityMock = http.get(`*/users/nickname/availability`, ({ request }) => {
   const url = new URL(request.url);
-  const nickname = url.searchParams.get('nickname');
+  const nickName = url.searchParams.get('nickName');
-  const user = mockUserItems.find((item) => item.nickName === nickname);
+  const user = mockUserItems.find((item) => item.nickName === nickName);
   return HttpResponse.json(
-    createMockSuccessResponse({
-      data: { available: !user },
-    }),
+    createMockSuccessResponse({ available: !user }),
   );
 });

참고: 파라미터 이름도 nickname에서 nickName으로 변경하여 API 서비스 코드(Line 48 in src/api/service/user-service/index.ts)와 일치시켰습니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 7. 닉네임 중복 검사 모킹
const getNicknameAvailabilityMock = http.get(`*/users/nickname/availability`, ({ request }) => {
const url = new URL(request.url);
const nickname = url.searchParams.get('nickname');
const user = mockUserItems.find((item) => item.nickName === nickname);
return HttpResponse.json(
createMockSuccessResponse({
data: { available: !user },
}),
);
});
// 7. 닉네임 중복 검사 모킹
const getNicknameAvailabilityMock = http.get(`*/users/nickname/availability`, ({ request }) => {
const url = new URL(request.url);
const nickName = url.searchParams.get('nickName');
const user = mockUserItems.find((item) => item.nickName === nickName);
return HttpResponse.json(
createMockSuccessResponse({ available: !user }),
);
});
🤖 Prompt for AI Agents
In src/mock/service/user/user-handler.ts around lines 88 to 98, the mock handler
returns an extra nested "data" object and uses the wrong query param name;
change the search param from 'nickname' to 'nickName' and pass the availability
boolean directly to createMockSuccessResponse (i.e., call
createMockSuccessResponse({ data: { available: !user } }) should be replaced so
createMockSuccessResponse receives data: { available: !user } without adding
another data wrapper), ensuring the final response shape matches { status,
success, data: { available: boolean } }.

Comment on lines +107 to 117
// 7. 닉네임 중복 검사 모킹
const getEmailAvailabilityMock = http.get(`*/users/email/availability`, ({ request }) => {
const url = new URL(request.url);
const email = url.searchParams.get('email');
const user = mockUserItems.find((item) => item.email === email);
return HttpResponse.json(
createMockSuccessResponse({
...mockUserItems[0],
...body,
data: { available: !user },
}),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

응답 구조가 일관되지 않습니다.

Line 113-115에서 getNicknameAvailabilityMock과 동일한 불필요한 중첩 구조 문제가 있습니다.

🔎 수정 제안
-const getEmailAvailabilityMock = http.get(`*/users/email/availability`, ({ request }) => {
+const getEmailAvailabilityMock = http.get(`*/users/email/availability`, ({ request }) => {
   const url = new URL(request.url);
   const email = url.searchParams.get('email');
   const user = mockUserItems.find((item) => item.email === email);
   return HttpResponse.json(
-    createMockSuccessResponse({
-      data: { available: !user },
-    }),
+    createMockSuccessResponse({ available: !user }),
   );
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 7. 닉네임 중복 검사 모킹
const getEmailAvailabilityMock = http.get(`*/users/email/availability`, ({ request }) => {
const url = new URL(request.url);
const email = url.searchParams.get('email');
const user = mockUserItems.find((item) => item.email === email);
return HttpResponse.json(
createMockSuccessResponse({
...mockUserItems[0],
...body,
data: { available: !user },
}),
);
});
// 7. 닉네임 중복 검사 모킹
const getEmailAvailabilityMock = http.get(`*/users/email/availability`, ({ request }) => {
const url = new URL(request.url);
const email = url.searchParams.get('email');
const user = mockUserItems.find((item) => item.email === email);
return HttpResponse.json(
createMockSuccessResponse({ available: !user }),
);
});
🤖 Prompt for AI Agents
In src/mock/service/user/user-handler.ts around lines 107 to 117, the JSON
response for getEmailAvailabilityMock uses an extra/unnecessary nested structure
inconsistent with getNicknameAvailabilityMock; modify the response so the
success payload shape matches the nickname availability handler (i.e., return
createMockSuccessResponse({ data: { available: !user } }) without additional
nesting or wrappers), ensuring the final HttpResponse.json contains the same
top-level keys and structure as other availability endpoints.

Comment on lines 119 to 153
const unfollowUserMock = http.delete(`*/users/unfollow`, ({ request }) => {
const url = new URL(request.url);
const unFollowNickname = url.searchParams.get('unFollowNickname');
const user = mockUserItems.find((v) => v.nickName === unFollowNickname);

const followUserItemMock = http.post(`*/follows`, async () => {
return HttpResponse.json(createMockSuccessResponse(null));
});
if (user?.isFollow === false) {
return HttpResponse.json(
createMockSuccessResponse({
...user,
status: 200,
data: '팔로우 취소 성공',
}),
);
}

const unfollowUserItemMock = http.delete(`*/follows/:followId`, async () => {
return HttpResponse.json(createMockSuccessResponse(null));
if (user?.isFollow === null) {
return HttpResponse.json(
createMockErrorResponse({
status: 400,
detail: '회원 : 팔로우 취소 대상은 본인 될 수 없습니다.',
errorCode: 'NOT_SAME_FOLLOW',
}),
);
}

if (user?.isFollow === true) {
return HttpResponse.json(
createMockErrorResponse({
status: 400,
detail: '회원 : 팔로우 관계를 찾을 수 없습니다.',
errorCode: 'NOT_FOUND_FOLLOW',
}),
);
}
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

언팔로우 상태 로직이 반대로 구현되어 있습니다.

Line 124에서 isFollow === false일 때 "팔로우 취소 성공"을 반환하지만, isFollow === false는 이미 팔로우하지 않은 상태를 의미하므로 언팔로우할 수 없습니다. 로직이 반대로 되어 있습니다:

  • isFollow === true: 현재 팔로우 중 → 언팔로우 가능 ✅
  • isFollow === false: 팔로우하지 않음 → 언팔로우 불가능 (에러)
🔎 수정 제안
 const unfollowUserMock = http.delete(`*/users/unfollow`, ({ request }) => {
   const url = new URL(request.url);
   const unFollowNickname = url.searchParams.get('unFollowNickname');
   const user = mockUserItems.find((v) => v.nickName === unFollowNickname);
+
+  if (!user) {
+    return HttpResponse.json(
+      createMockErrorResponse({
+        status: 404,
+        detail: '존재하지 않는 사용자입니다.',
+        errorCode: 'USER_NOT_FOUND',
+      }),
+      { status: 404 },
+    );
+  }

-  if (user?.isFollow === false) {
+  if (user.nickName === mockUserItems[0].nickName) {
+    return HttpResponse.json(
+      createMockErrorResponse({
+        status: 400,
+        detail: '회원 : 팔로우 취소 대상은 본인이 될 수 없습니다.',
+        errorCode: 'NOT_SAME_FOLLOW',
+      }),
+      { status: 400 },
+    );
+  }
+
+  if (user.isFollow === true) {
+    // 언팔로우 상태 업데이트 (실제로는 mockUserItems 업데이트 필요)
     return HttpResponse.json(
-      createMockSuccessResponse({
-        ...user,
-        status: 200,
-        data: '팔로우 취소 성공',
-      }),
+      createMockSuccessResponse('팔로우 취소 성공'),
     );
   }

-  if (user?.isFollow === null) {
-    return HttpResponse.json(
-      createMockErrorResponse({
-        status: 400,
-        detail: '회원 : 팔로우 취소 대상은 본인 될 수 없습니다.',
-        errorCode: 'NOT_SAME_FOLLOW',
-      }),
-    );
-  }
-
-  if (user?.isFollow === true) {
+  if (user.isFollow === false) {
     return HttpResponse.json(
       createMockErrorResponse({
         status: 400,
         detail: '회원 : 팔로우 관계를 찾을 수 없습니다.',
         errorCode: 'NOT_FOUND_FOLLOW',
       }),
+      { status: 400 },
     );
   }
 });

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/mock/service/user/user-handler.ts around lines 119 to 153, the unfollow
logic is inverted: currently it treats isFollow === false as a successful
unfollow; change it so isFollow === true returns the success response ("팔로우 취소
성공", status 200) and isFollow === false returns the appropriate error (status
400, errorCode 'NOT_FOUND_FOLLOW' with detail '회원 : 팔로우 관계를 찾을 수 없습니다.'); keep
the isFollow === null branch as the self-unfollow error (status 400, errorCode
'NOT_SAME_FOLLOW') and ensure response shapes and status codes remain
consistent.

Copy link
Contributor

@wooktori wooktori left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

@Chiman2937 Chiman2937 merged commit 4b2aba5 into main Dec 23, 2025
7 checks passed
@Chiman2937 Chiman2937 deleted the chiyoung-feat/mypage-edit-test branch December 23, 2025 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready For Review! 리뷰 받을 준비가 되었습니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants