macsync/@packages/imessage/Tests/IMessageSyncTests/SendServiceRoutingTests.swift
Natalie 42b9229a9f feat(@applications/@mac-sync): add async actor-based iMessage sender with timeout guard
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-22 01:56:05 -07:00

67 lines
2.6 KiB
Swift

import Foundation
import Testing
@testable import IMessageSync
/// Covers the two pure/bounded primitives introduced by the send-pipeline
/// async-hardening refactor: the iMessage-vs-SMS routing decision, and the
/// `bounded` timeout wrapper that guarantees no blocking operation can stall
/// the send-queue poller.
@Suite("SendService routing & bounded primitive")
struct SendServiceRoutingTests {
// MARK: - decideService (pure routing logic)
@Test("SMS-only history routes to SMS")
func decideServiceSMSOnly() {
#expect(SendService.decideService(imessageCount: 0, smsCount: 5) == .sms)
#expect(SendService.decideService(imessageCount: 0, smsCount: 1) == .sms)
}
@Test("any iMessage history routes to iMessage")
func decideServiceHasIMessage() {
#expect(SendService.decideService(imessageCount: 3, smsCount: 0) == .iMessage)
// iMessage history wins even when SMS messages also exist.
#expect(SendService.decideService(imessageCount: 1, smsCount: 20) == .iMessage)
}
@Test("a brand-new number with no history defaults to iMessage")
func decideServiceNoHistory() {
#expect(SendService.decideService(imessageCount: 0, smsCount: 0) == .iMessage)
}
// MARK: - bounded (timeout wrapper)
@Test("bounded returns the work's value when it finishes within the deadline")
func boundedReturnsValue() async {
let result = await SendService.bounded(5, fallback: "fallback") { "real" }
#expect(result == "real")
}
@Test("bounded returns the fallback when the work exceeds the deadline")
func boundedTimesOut() async {
let start = Date()
let result = await SendService.bounded(0.2, fallback: "fallback") {
Thread.sleep(forTimeInterval: 3) // deliberately exceeds the 0.2s cap
return "real"
}
let elapsed = Date().timeIntervalSince(start)
#expect(result == "fallback")
// The caller is released at the deadline it does NOT wait out the
// 3s of blocking work.
#expect(elapsed < 2.0)
}
@Test("bounded resumes exactly once even when work and timeout race")
func boundedRacesCleanly() async {
// Work finishes right around the deadline the ResumeOnce guard must
// prevent a double-resume crash regardless of which path wins.
for _ in 0..<20 {
_ = await SendService.bounded(0.05, fallback: -1) {
Thread.sleep(forTimeInterval: 0.05)
return 1
}
}
// Reaching here without a crash is the assertion.
#expect(Bool(true))
}
}