Фикс: пуш-уведомления — убраны кастомные in-app баннеры, Desktop-active suppression, NSE timeout safety
This commit is contained in:
@@ -4,10 +4,8 @@ import UserNotifications
|
||||
|
||||
// MARK: - Foreground Notification Suppression Tests
|
||||
|
||||
/// Tests for the in-app notification banner suppression logic (Telegram parity).
|
||||
/// System banners are always suppressed (`willPresent` returns `[]`).
|
||||
/// `InAppNotificationManager.shouldSuppress()` decides whether the
|
||||
/// custom in-app banner should be shown or hidden.
|
||||
/// Tests for foreground notification suppression logic.
|
||||
/// `willPresent` returns `[.banner, .sound]` by default, `[]` for active/muted chats.
|
||||
@MainActor
|
||||
struct ForegroundNotificationTests {
|
||||
|
||||
@@ -17,21 +15,23 @@ struct ForegroundNotificationTests {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - System Banner Always Suppressed
|
||||
// MARK: - System Banner Presentation
|
||||
|
||||
@Test("System banner always suppressed — foregroundPresentationOptions returns []")
|
||||
func systemBannerAlwaysSuppressed() {
|
||||
@Test("Non-suppressed chat shows system banner with sound")
|
||||
func nonSuppressedShowsBanner() {
|
||||
clearActiveDialogs()
|
||||
let userInfo: [AnyHashable: Any] = ["dialog": "02aaa", "title": "Alice"]
|
||||
let options = AppDelegate.foregroundPresentationOptions(for: userInfo)
|
||||
#expect(options == [])
|
||||
#expect(options == [.banner, .sound])
|
||||
}
|
||||
|
||||
@Test("System banner suppressed even for inactive chats")
|
||||
func systemBannerSuppressedInactive() {
|
||||
@Test("Active chat suppresses system banner")
|
||||
func activeChatSuppressesBanner() {
|
||||
clearActiveDialogs()
|
||||
MessageRepository.shared.setDialogActive("02bbb", isActive: true)
|
||||
let userInfo: [AnyHashable: Any] = ["dialog": "02bbb"]
|
||||
#expect(AppDelegate.foregroundPresentationOptions(for: userInfo) == [])
|
||||
MessageRepository.shared.setDialogActive("02bbb", isActive: false)
|
||||
}
|
||||
|
||||
// MARK: - In-App Banner: Active Chat → Suppress
|
||||
|
||||
@@ -297,6 +297,39 @@ struct PushNotificationDesktopSuppressionTests {
|
||||
let shouldSuppress = recentlyRead[senderKey].map { now - $0 < Self.recentlyReadWindow } ?? false
|
||||
#expect(shouldSuppress == false)
|
||||
}
|
||||
|
||||
// MARK: - AppDelegate → App Group flag (READ push writes nse_recently_read_dialogs)
|
||||
|
||||
@Test("handleReadPush stores recently-read flag in App Group for NSE")
|
||||
func readPushStoresRecentlyReadFlagInAppGroup() {
|
||||
let shared = UserDefaults(suiteName: "group.com.rosetta.dev")
|
||||
let key = "nse_recently_read_dialogs"
|
||||
let originalData = shared?.dictionary(forKey: key)
|
||||
|
||||
// Simulate what handleReadPush now does: write the recently-read flag.
|
||||
let dialogKey = "02test_desktop_read_flag"
|
||||
let now = Date().timeIntervalSince1970
|
||||
var recentlyRead = shared?.dictionary(forKey: key) as? [String: Double] ?? [:]
|
||||
recentlyRead[dialogKey] = now
|
||||
recentlyRead = recentlyRead.filter { now - $0.value < 60 }
|
||||
shared?.set(recentlyRead, forKey: key)
|
||||
|
||||
// Verify flag exists and is recent.
|
||||
let stored = shared?.dictionary(forKey: key) as? [String: Double] ?? [:]
|
||||
#expect(stored[dialogKey] != nil)
|
||||
if let ts = stored[dialogKey] {
|
||||
#expect(abs(ts - now) < 2)
|
||||
}
|
||||
|
||||
// Verify NSE suppression logic would fire for this dialog.
|
||||
if let lastReadTime = stored[dialogKey] {
|
||||
let elapsed = now - lastReadTime
|
||||
#expect(elapsed < Self.recentlyReadWindow)
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
shared?.set(originalData, forKey: key)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Read Push Group Key Normalization Tests
|
||||
@@ -657,13 +690,11 @@ struct PushInAppBannerSuppressionExtendedTests {
|
||||
#expect(InAppNotificationManager.shouldSuppress(senderKey: "02normal") == false)
|
||||
}
|
||||
|
||||
@Test("System presentation options always return empty set")
|
||||
func systemPresentationAlwaysEmpty() {
|
||||
@Test("System presentation returns banner+sound for non-suppressed chats")
|
||||
func systemPresentationShowsBanner() {
|
||||
clearState()
|
||||
// Even for non-suppressed chats, system banner is always suppressed
|
||||
// (custom in-app banner shown instead)
|
||||
let options = AppDelegate.foregroundPresentationOptions(for: ["dialog": "02any_user"])
|
||||
#expect(options == [])
|
||||
#expect(options == [.banner, .sound])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user