Форвард: Telegram-parity UI — правильный размер бабла, текст/таймстамп, аватарка с инициалами, отступы

This commit is contained in:
2026-03-31 16:36:58 +05:00
parent e5179b11ea
commit 464fae37a9
11 changed files with 1037 additions and 53 deletions

View File

@@ -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")
}
}