import XCTest @testable import AIStudyApp final class RuntimeRecoveryServiceTests: XCTestCase { // MARK: - Recovery does not crash func test_recovery_run_with_noop_adapter_does_not_crash() { let adapter = NoopReadingRuntimeAdapter() // Must not crash even with a noop adapter RuntimeRecoveryService.run(adapter: adapter) // If we reach here, test passes XCTAssertTrue(true) } func test_recovery_run_calls_reloadStaleEvents() { let adapter = NoopReadingRuntimeAdapter() // Noop returns 0, but the call should succeed let reloaded = adapter.reloadStaleEvents() XCTAssertEqual(reloaded, 0, "Noop adapter should return 0 from reloadStaleEvents") } func test_recovery_cleanup_sessions_returns_zero_for_noop() { let adapter = NoopReadingRuntimeAdapter() let nowMs = Int64(Date().timeIntervalSince1970 * 1000) let cleaned = adapter.cleanupStaleSessions(nowMs: nowMs, maxAgeMs: 86_400_000) XCTAssertEqual(cleaned, 0) } // MARK: - Stale session max age func test_stale_session_max_age_is_24_hours() { // 24 * 60 * 60 * 1000 = 86_400_000 ms // This is the internal constant; verify via behavior let adapter = NoopReadingRuntimeAdapter() let nowMs = Int64(Date().timeIntervalSince1970 * 1000) // Call with various max ages — none should crash let r1 = adapter.cleanupStaleSessions(nowMs: nowMs, maxAgeMs: 0) let r2 = adapter.cleanupStaleSessions(nowMs: nowMs, maxAgeMs: 86_400_000) let r3 = adapter.cleanupStaleSessions(nowMs: nowMs, maxAgeMs: 1_000_000_000) XCTAssertEqual(r1, 0) XCTAssertEqual(r2, 0) XCTAssertEqual(r3, 0) } }