Форвард: Telegram-parity UI — правильный размер бабла, текст/таймстамп, аватарка с инициалами, отступы
This commit is contained in:
@@ -301,4 +301,71 @@ final class ReadEligibilityTests: XCTestCase {
|
||||
|
||||
XCTAssertFalse(MessageRepository.shared.isDialogReadEligible(peer))
|
||||
}
|
||||
|
||||
// MARK: - Idle detection (Desktop/Android parity: 20s)
|
||||
|
||||
func testIdleTimer_clearsEligibilityAfterTimeout() async throws {
|
||||
try await ctx.bootstrap()
|
||||
|
||||
MessageRepository.shared.setDialogActive(peer, isActive: true)
|
||||
MessageRepository.shared.setDialogReadEligible(peer, isEligible: true)
|
||||
XCTAssertTrue(MessageRepository.shared.isDialogReadEligible(peer))
|
||||
|
||||
// Simulate idle timeout (call clearAllReadEligibility directly,
|
||||
// since we can't wait 20s in a unit test)
|
||||
SessionManager.shared.resetIdleTimer()
|
||||
XCTAssertFalse(SessionManager.shared.isUserIdle, "User should not be idle right after reset")
|
||||
|
||||
// Simulate what the idle timer callback does
|
||||
MessageRepository.shared.clearAllReadEligibility()
|
||||
|
||||
XCTAssertFalse(MessageRepository.shared.isDialogReadEligible(peer),
|
||||
"After idle timeout, eligibility must be cleared")
|
||||
|
||||
// Messages arriving during idle should be unread
|
||||
try await ctx.runScenario(FixtureScenario(name: "idle msg", events: [
|
||||
.incoming(opponent: peer, messageId: "idle-1", timestamp: 7000, text: "idle msg"),
|
||||
]))
|
||||
|
||||
let snapshot = try ctx.normalizedSnapshot()
|
||||
let msg = snapshot.messages.first(where: { $0.messageId == "idle-1" })
|
||||
XCTAssertEqual(msg?.read, false, "Message during idle must be unread")
|
||||
|
||||
let dialog = snapshot.dialogs.first(where: { $0.opponentKey == peer })
|
||||
XCTAssertEqual(dialog?.unreadCount, 1, "Unread count must be 1 during idle")
|
||||
|
||||
// Cleanup
|
||||
SessionManager.shared.stopIdleTimer()
|
||||
}
|
||||
|
||||
func testIdleTimer_resetRestoresEligibility() async throws {
|
||||
try await ctx.bootstrap()
|
||||
|
||||
MessageRepository.shared.setDialogActive(peer, isActive: true)
|
||||
MessageRepository.shared.setDialogReadEligible(peer, isEligible: true)
|
||||
|
||||
// Simulate idle → clear eligibility
|
||||
MessageRepository.shared.clearAllReadEligibility()
|
||||
XCTAssertFalse(MessageRepository.shared.isDialogReadEligible(peer))
|
||||
|
||||
// Simulate user interaction → reset timer + re-enable eligibility
|
||||
SessionManager.shared.resetIdleTimer()
|
||||
MessageRepository.shared.setDialogReadEligible(peer, isEligible: true)
|
||||
|
||||
XCTAssertTrue(MessageRepository.shared.isDialogReadEligible(peer),
|
||||
"After user interaction, eligibility must be restored")
|
||||
|
||||
// Cleanup
|
||||
SessionManager.shared.stopIdleTimer()
|
||||
}
|
||||
|
||||
func testStopIdleTimer_resetsIdleState() async throws {
|
||||
try await ctx.bootstrap()
|
||||
|
||||
SessionManager.shared.resetIdleTimer()
|
||||
XCTAssertFalse(SessionManager.shared.isUserIdle)
|
||||
|
||||
SessionManager.shared.stopIdleTimer()
|
||||
XCTAssertFalse(SessionManager.shared.isUserIdle, "stopIdleTimer must clear idle state")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user