fix(deeplink): 커뮤니티 링크를 게시글 상세에 연결한다

This commit is contained in:
Yu Sung
2026-10-13 13:57:44 +09:00
parent 1b50f559bd
commit 4b5fa133f5
2 changed files with 83 additions and 28 deletions
+67 -3
View File
@@ -7,6 +7,7 @@ enum AppStep: Equatable {
case contentDetail(contentId: Int)
case seriesDetail(seriesId: Int)
case creatorCommunityAll(creatorId: Int)
case creatorChannelCommunityPostDetail(postId: Int)
case message
case audition
case giftDetail(applicationNo: String)
@@ -14,7 +15,8 @@ enum AppStep: Equatable {
enum UserDefaultsKey { case userId }
enum UserDefaults {
static func int(forKey: UserDefaultsKey) -> Int { 0 }
static var userId = 0
static func int(forKey: UserDefaultsKey) -> Int { userId }
}
final class AppState {
@@ -24,9 +26,10 @@ final class AppState {
var appliedStep: AppStep?
var isPushRoomFromDeepLink = false
var pushRoomId = 0
var pendingCommentPostId: Int?
func setAppStep(step: AppStep) { appliedStep = step }
func setPendingCommunityCommentDeepLink(creatorId: Int, postId: Int) {}
func clearPendingCommunityCommentDeepLink() {}
func setPendingCommunityCommentDeepLink(creatorId: Int, postId: Int) { pendingCommentPostId = postId }
func clearPendingCommunityCommentDeepLink() { pendingCommentPostId = nil }
}
let APPSCHEME = "soda"
@@ -104,6 +107,67 @@ enum GiftDetailDeepLinkCheck {
check(AppDeepLinkHandler.handle(urlString: "voiceon://?content_id=42&deepLinkValue=GIFT_DETAIL&deepLinkId=GIFT-2026-007"), "existing content route accepted")
settle()
check(AppState.shared.appliedStep == .contentDetail(contentId: 42), "existing content route still applies")
checkCommunityLinks()
print("PASS AppDeepLinkGiftDetailCheck assertions=\(assertions)")
}
static func checkCommunityLinks() {
for userId in [0, 42] {
UserDefaults.userId = userId
for source in [AppDeepLinkSource.external, .notificationList] {
for url in [
"voiceon://community?postId=12345",
"voiceon-test://community?post_id=12345",
"voiceon:///community?POSTID=12345",
"voiceon://community/77?postId=12345",
"voiceon://?community_id=77&postId=12345"
] {
AppState.shared.appliedStep = nil
AppState.shared.pendingCommentPostId = nil
check(AppDeepLinkHandler.handle(urlString: url, source: source), "community link accepted: \(url), userId=\(userId)")
settle()
check(AppState.shared.appliedStep == .creatorChannelCommunityPostDetail(postId: 12345), "community link opens requested post detail: \(url)")
check(AppState.shared.pendingCommentPostId == nil, "detail link does not queue legacy comment sheet")
}
}
}
for rootStep in [AppStep.main, .splash] {
AppState.shared.rootStep = rootStep
for route in ["voiceon://community", "voiceon:///community", "voiceon://community/77", "voiceon://?community_id=77"] {
for parameter in ["", "postId=", "postId=abc", "postId=0", "postId=-1", "postId=1.5", "postId=999999999999999999999999", "post_id=0"] {
let separator = route.contains("?") ? "&" : "?"
let url = route + separator + parameter
AppState.shared.appliedStep = .contentDetail(contentId: 42)
AppState.shared.pendingDeepLinkAction = .content(contentId: 99)
check(!AppDeepLinkHandler.handle(urlString: url), "invalid community link rejected: \(url)")
settle()
check(AppState.shared.appliedStep == .contentDetail(contentId: 42), "invalid postId leaves current route unchanged")
if case .content(let contentId)? = AppState.shared.pendingDeepLinkAction {
check(contentId == 99, "invalid postId preserves existing deferred action")
} else {
check(false, "invalid postId preserves existing deferred action")
}
}
}
}
check(!AppDeepLinkHandler.handle(urlString: "voiceon://community?postId=bad&content_id=42"), "invalid community route does not fall through to content")
check(!AppDeepLinkHandler.handle(urlString: "voiceon:///community?message_id=42"), "missing postId does not fall through to message")
AppState.shared.rootStep = .splash
AppState.shared.appliedStep = nil
AppState.shared.pendingDeepLinkAction = nil
check(AppDeepLinkHandler.handle(urlString: "voiceon://community?postId=12345"), "splash accepts community detail")
settle()
check(AppState.shared.appliedStep == nil, "splash defers detail navigation")
guard let action = AppState.shared.pendingDeepLinkAction else {
check(false, "splash stores community detail action")
return
}
AppState.shared.rootStep = .main
AppState.shared.pendingDeepLinkAction = nil
AppDeepLinkHandler.apply(action: action)
check(AppState.shared.appliedStep == .creatorChannelCommunityPostDetail(postId: 12345), "deferred community link opens requested post detail")
}
}