-
Notifications
You must be signed in to change notification settings - Fork 0
PushNotification·WebPage 삭제 리팩토링과 Swift Testing 적용
최윤진 edited this page Apr 6, 2026
·
1 revision
Note
PushNotification과 WebPage의 삭제 방식을 Todo와 동일한 즉시 soft delete + undo 복구 구조로 통일하고, Swift Testing 기반 테스트 적용 과정에서 확인한 Emulator credential 이슈까지 함께 정리했습니다.
해결 PR
- 개선 전 코드에서 테스트 코드가 실패한 이유는
Try 5확인
|
|
| 기존 코드의 테스트 결과 | 개선 코드의 테스트 결과 |
-
Todo는 삭제 요청 시 즉시 soft delete 상태로 전환되고,undo는 그 상태를 바로 복구하는 구조 - 반면
PushNotification,WebPage는deletingAt기록 후 task queue로 지연 삭제를 수행하는 2단계 구조를 사용하고 있었음 - 이로 인해 삭제 도메인 간 구현 방식이 달랐고, 로컬 Emulator 환경에서는
taskQueue().enqueue(...)과정에서 credential 이슈가 발생해 integration test가 안정적으로 동작하지 않음 - 리팩토링 목표
-
PushNotification,WebPage의 삭제 방식을Todo와 동일한 방향으로 통일 -
undo이후 다시 보이는 사용자 결과를 기준으로 테스트 가능하게 구성 - 더 이상 사용하지 않는 queue 기반 함수와 설정 의존을 제거
-
- 우선
PushNotification,WebPage에 대해 Swift Testing 기반 테스트를 추가하고, 삭제 후 즉시 숨김 및undo흐름을 검증을 시도 -
Spy기반으로ViewModel -> UseCase호출 여부와 상태 변화를 검증하도록 구성 - 결과: 빠른 회귀 테스트로는 유효했지만, 서버 코드가 바뀌어도 결과가 달라지지 않는 한계 존재
- 실제 앱 서비스 계층을 그대로 타는 방식으로 integration test를 계획
-
ViewModel -> UseCase -> Repository -> Service -> Firebase경로를 테스트에서 직접 재현 시도 -
결과: hosted/hostless test 환경 차이, Firestore 초기화 타이밍,
useEmulator(...)제약 때문에 안정적으로 유지하기 어려웠음
- Firebase iOS SDK 대신, Auth / Firestore / Functions Emulator를 REST로 직접 호출하는 테스트 helper 구성
- 삭제 요청,
undo, 재조회 흐름을 로컬 Emulator 기준으로 재현 -
결과: 서버 내부 구현이 실제로 테스트 결과에 반영되는 형태는 확보했지만, 초기에는
500 INTERNAL이 발생하여 원인 분석이 필요
- 초기 로그에는
FieldValue.delete()관련 예외만 보여 실제 실패 원인을 파악하기 어려웠음 -
catch내부 cleanup 로직에서 발생한 2차 예외가 원래 예외를 덮고 있음을 확인하고, 원본 오류와 cleanup 오류를 분리 로깅하도록 수정 - 결과: 실제 1차 오류가 queue enqueue 단계에서 발생한다는 점을 확인
-
requestPushNotificationDeletion,requestWebPageDeletion호출 시 callable auth 자체는VALID로 통과 - 하지만
taskQueue().enqueue(...)수행 시 Admin SDK가 Google access token을 가져오지 못해 실패 - 결과: 문제는 사용자 인증이 아니라, queue 기반 deletion 흐름이 로컬 Emulator에서 별도의 credential 요구를 만든다는 점이었음
-
PushNotification,WebPage모두 삭제 요청 시 바로isDeleted = true로 저장하고,undo는isDeleted = false로 즉시 복구하도록 변경 -
deletingAt, delayed task,completePushNotificationDeletion,completeWebPageDeletion같은 queue 기반 경로를 제거 - 클라이언트는
isDeleted == false만 기준으로 목록을 구성하도록 정리. -
최종 결과: 삭제 방식이
Todo와 동일한 구조로 통일되었고, queue credential 문제 없이 integration test로undo 후 다시 보임을 검증 가능
-
현상:
Spy기반 테스트는 서버 구현이 바뀌어도 여전히 통과 가능 - 해결: REST 기반 Emulator integration test를 별도로 추가해, 실제 서버 callable 결과가 테스트 성공/실패에 반영되도록 구성
-
현상:
taskQueue().enqueue(...)호출 시metadata.google.internalaccess token 조회 실패로500 INTERNAL발생 - 원인: callable auth와 별개로, Functions Emulator 내부의 Admin SDK가 queue enqueue에 필요한 Google credential을 요구
-
해결: queue 기반 삭제 자체를 제거하고,
Todo와 같은 즉시 soft delete 방식으로 변경하여 credential 의존 경로를 제거
-
현상: 처음에는
FieldValue.delete()관련 로그만 보여 해당 코드가 직접 원인으로 예상 -
원인: 실제 1차 오류는
try내부에서 먼저 발생했고,catchcleanup 중 2차 예외가 추가로 발생하며 로그를 오염 - 해결: 원본 오류와 cleanup 오류를 분리 로깅해 1차 실패 지점을 정확히 드러내도록 수정
-
현상:
Successful update operation,Deploy complete!이후에도Error: An unexpected error has occurred.가 출력 - 해결: 실제 성공 로그를 기준으로 배포/삭제 성공 여부를 판단했고, 수정된 함수는 개별 배포, obsolete function은 개별 삭제 방식으로 마무리
- 현상: 삭제 방식이 바뀌었으므로 Firestore index도 정리해야 하는지 검토가 필요
-
결과: 실제 변경은 write 방식과 로컬 후처리 필터 제거였고,
where/orderBy조합 자체는 바뀌지 않음 - 해결: 인덱스는 유지하고, queue/export/deletingAt 의존 코드만 제거
TagEditor에서 sheet의 detents 최적화(Deprecated)
PushNotificationView의 푸시 알람 기록 UNDO 과정-V1
PushNotificationView의 푸시 알람 기록 UNDO 과정-V2
PushNotificationView의 푸시 알람 기록 UNDO 과정-V3(최종)
Publishing 상태 변환에 따른 에러 해결하기
iOS 17 이하에서 모달의 isPresented 관리하기
LPMetadataProvider로 웹페이지 썸네일 가져오기
Todo-리마인더-구현-트러블슈팅
iOS 17 .searchable 포커싱 이슈 해결기
TodoListView 헤더 트러블슈팅-스크롤 조정
TodoListView 헤더 트러블슈팅-내비게이션바
Todo Response 트러블슈팅
Fastlane을 통한 배포 자동화 트러블슈팅
PushNotification·WebPage 삭제 리팩토링과 Swift Testing 적용
푸시 알림 리스트 데이터 최신화 개선하기