Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ fastlane/logs/
.tmp/
.spm/
Tuist/.build/

# drawio
*.drawio
*.drawio.bkp

# AI
.superpowers/
113 changes: 64 additions & 49 deletions Application/App/Sources/Resource/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -1,42 +1,6 @@
{
"sourceLanguage" : "ko",
"strings" : {
"" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : ""
}
}
},
"shouldTranslate" : false
},
"#%lld" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "#%lld"
}
}
},
"shouldTranslate" : false
},
"%lld" : {
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld"
}
}
},
"shouldTranslate" : false
},
"account_alert_already_linked_message" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -565,7 +529,7 @@
}
},
"https://" : {
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand Down Expand Up @@ -1119,6 +1083,57 @@
}
}
},
"push_notification_todo_due_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo Reminder"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "Todo 알림"
}
}
}
},
"push_notification_todo_due_tomorrow_format" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "%1$@ is due tomorrow."
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "'%1$@'의 마감일이 내일입니다."
}
}
}
},
"push_notification_todo_due_tomorrow_without_title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "An untitled Todo is due tomorrow."
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "제목 없는 Todo의 마감일이 내일입니다."
}
}
}
},
"push_notifications_empty" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -2480,7 +2495,7 @@
}
},
"TODO" : {
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand Down Expand Up @@ -2526,7 +2541,7 @@
},
"todo_category_doc" : {
"comment" : "Todo category: Documentation",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -2544,7 +2559,7 @@
},
"todo_category_etc" : {
"comment" : "Todo category: Etc",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -2562,7 +2577,7 @@
},
"todo_category_feature" : {
"comment" : "Todo category: Feature",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -2580,7 +2595,7 @@
},
"todo_category_improvement" : {
"comment" : "Todo category: Improvement",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -2598,7 +2613,7 @@
},
"todo_category_issue" : {
"comment" : "Todo category: Issue",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -2616,7 +2631,7 @@
},
"todo_category_research" : {
"comment" : "Todo category: Research",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -2634,7 +2649,7 @@
},
"todo_category_review" : {
"comment" : "Todo category: Review",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -2652,7 +2667,7 @@
},
"todo_category_test" : {
"comment" : "Todo category: Test",
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand Down Expand Up @@ -3485,7 +3500,7 @@
}
},
"Todos" : {
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -3496,7 +3511,7 @@
}
},
"Web Page" : {
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -3507,7 +3522,7 @@
}
},
"Web Pages" : {
"extractionState" : "stale",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
Expand Down
9 changes: 8 additions & 1 deletion Application/Data/Sources/DTO/PushNotificationResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ import Foundation
import Domain

public struct PushNotificationResponse {
public enum Content: Equatable {
case todoDueTomorrow(todoTitle: String?)
}

public let id: String
public let title: String
public let body: String
public let receivedAt: Date
public let isRead: Bool
public let todoId: String
public let todoCategory: TodoCategoryResponse
public let content: Content?

public init(
id: String,
Expand All @@ -24,7 +29,8 @@ public struct PushNotificationResponse {
receivedAt: Date,
isRead: Bool,
todoId: String,
todoCategory: TodoCategoryResponse
todoCategory: TodoCategoryResponse,
content: Content? = nil
) {
self.id = id
self.title = title
Expand All @@ -33,5 +39,6 @@ public struct PushNotificationResponse {
self.isRead = isRead
self.todoId = todoId
self.todoCategory = todoCategory
self.content = content
}
}
12 changes: 11 additions & 1 deletion Application/Data/Sources/Mapper/PushNotificationMapping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,21 @@ public extension PushNotificationResponse {
receivedAt: self.receivedAt,
isRead: self.isRead,
todoId: self.todoId,
todoCategory: todoCategory
todoCategory: todoCategory,
content: content?.toDomain()
)
}
}

public extension PushNotificationResponse.Content {
func toDomain() -> PushNotificationContent {
switch self {
case .todoDueTomorrow(let todoTitle):
return .todoDueTomorrow(todoTitle: todoTitle)
}
}
}

public extension PushNotificationCursorDTO {
func toDomain() -> PushNotificationCursor {
PushNotificationCursor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ private extension PushNotificationRepositoryImpl {
receivedAt: response.receivedAt,
isRead: response.isRead,
todoId: response.todoId,
todoCategory: .decoded(todoCategory)
todoCategory: .decoded(todoCategory),
content: response.content
)
}
}
52 changes: 52 additions & 0 deletions Application/Data/Tests/Mapper/PushNotificationMappingTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// PushNotificationMappingTests.swift
// DataTests
//
// Created by opfic on 7/19/26.
//

import Foundation
import Testing
import Domain
@testable import Data

struct PushNotificationMappingTests {
@Test("Todo 마감 알림 응답은 의미 기반 내용을 변환한다")
func Todo_마감_알림_응답은_의미_기반_내용을_변환한다() throws {
let response = makeResponse(
content: .todoDueTomorrow(todoTitle: "테스트 작성")
)

let notification = try response.toDomain()

#expect(notification.content == .todoDueTomorrow(todoTitle: "테스트 작성"))
#expect(notification.title == "fallback-title")
#expect(notification.body == "fallback-body")
}

@Test("기존 푸시 알림 응답은 의미 기반 내용 없이 변환한다")
func 기존_푸시_알림_응답은_의미_기반_내용_없이_변환한다() throws {
let response = makeResponse()

let notification = try response.toDomain()

#expect(notification.content == nil)
#expect(notification.title == "fallback-title")
#expect(notification.body == "fallback-body")
}

private func makeResponse(
content: PushNotificationResponse.Content? = nil
) -> PushNotificationResponse {
PushNotificationResponse(
id: "notification-id",
title: "fallback-title",
body: "fallback-body",
receivedAt: Date(timeIntervalSince1970: 1),
isRead: false,
todoId: "todo-id",
todoCategory: .decoded(.system(.feature)),
content: content
)
}
}
Loading
Loading