10bc457c72
Unify PiP recovery across startup and foreground transitions, surface actionable status, and add privacy-safe analytics plus the refreshed onboarding and account experience. Update documentation assets and advance the release build to 84.
150 lines
4.2 KiB
Swift
150 lines
4.2 KiB
Swift
// FlowPiPRecoveryPolicyTests.swift
|
|
// OSGKeyboardTests
|
|
|
|
@testable import OSGKeyboard
|
|
import XCTest
|
|
|
|
final class FlowPiPRecoveryPolicyTests: XCTestCase {
|
|
|
|
// MARK: - Reconciliation
|
|
|
|
func testNoSessionIntentNeverStartsRecovery() {
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.reconciliationDecision(
|
|
wantsActiveSession: false,
|
|
isAppForeground: true,
|
|
isPictureInPictureActive: false
|
|
),
|
|
.noSessionIntent
|
|
)
|
|
}
|
|
|
|
func testActivePiPIsIdempotent() {
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.reconciliationDecision(
|
|
wantsActiveSession: true,
|
|
isAppForeground: true,
|
|
isPictureInPictureActive: true
|
|
),
|
|
.alreadyActive
|
|
)
|
|
}
|
|
|
|
func testTakeoverWaitsWhileAppIsInBackground() {
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.reconciliationDecision(
|
|
wantsActiveSession: true,
|
|
isAppForeground: false,
|
|
isPictureInPictureActive: false
|
|
),
|
|
.waitForForeground
|
|
)
|
|
}
|
|
|
|
func testReturningToForegroundStartsRecovery() {
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.reconciliationDecision(
|
|
wantsActiveSession: true,
|
|
isAppForeground: true,
|
|
isPictureInPictureActive: false
|
|
),
|
|
.startRecovery
|
|
)
|
|
}
|
|
|
|
// MARK: - Bounded retry
|
|
|
|
func testRetryPolicyUsesThreeIncreasingBoundedAttempts() {
|
|
XCTAssertEqual(FlowPiPRecoveryPolicy.maxAttempts, 3)
|
|
XCTAssertEqual(
|
|
(1...FlowPiPRecoveryPolicy.maxAttempts).map {
|
|
FlowPiPRecoveryPolicy.retryDelay(beforeAttempt: $0)
|
|
},
|
|
[0, 0.25, 0.6]
|
|
)
|
|
XCTAssertEqual(FlowPiPRecoveryPolicy.totalBudget, 5)
|
|
}
|
|
|
|
func testRetryTimeoutsNeverExceedRemainingBudget() {
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.hostTimeout(attempt: 1, remainingBudget: 0.4),
|
|
0.4
|
|
)
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.hostTimeout(attempt: 2, remainingBudget: 4),
|
|
0.25
|
|
)
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.activeTimeout(remainingBudget: 0.3),
|
|
0.3
|
|
)
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.activeTimeout(remainingBudget: 4),
|
|
1.4
|
|
)
|
|
XCTAssertEqual(
|
|
FlowPiPRecoveryPolicy.activeTimeout(remainingBudget: 0.01),
|
|
0.01
|
|
)
|
|
}
|
|
|
|
// MARK: - Late completion safety
|
|
|
|
func testCurrentForegroundOperationCanContinue() {
|
|
XCTAssertTrue(
|
|
FlowPiPRecoveryPolicy.canContinue(
|
|
operation: 7,
|
|
currentOperation: 7,
|
|
wantsActiveSession: true,
|
|
isAppForeground: true,
|
|
taskIsCancelled: false
|
|
)
|
|
)
|
|
}
|
|
|
|
func testOldGenerationCannotOverwriteNewRecovery() {
|
|
XCTAssertFalse(
|
|
FlowPiPRecoveryPolicy.canContinue(
|
|
operation: 6,
|
|
currentOperation: 7,
|
|
wantsActiveSession: true,
|
|
isAppForeground: true,
|
|
taskIsCancelled: false
|
|
)
|
|
)
|
|
}
|
|
|
|
func testExplicitEndPreventsLateRecovery() {
|
|
XCTAssertFalse(
|
|
FlowPiPRecoveryPolicy.canContinue(
|
|
operation: 7,
|
|
currentOperation: 8,
|
|
wantsActiveSession: false,
|
|
isAppForeground: true,
|
|
taskIsCancelled: true
|
|
)
|
|
)
|
|
}
|
|
|
|
func testBackgroundAndCancellationBothStopRecovery() {
|
|
XCTAssertFalse(
|
|
FlowPiPRecoveryPolicy.canContinue(
|
|
operation: 7,
|
|
currentOperation: 7,
|
|
wantsActiveSession: true,
|
|
isAppForeground: false,
|
|
taskIsCancelled: false
|
|
)
|
|
)
|
|
XCTAssertFalse(
|
|
FlowPiPRecoveryPolicy.canContinue(
|
|
operation: 7,
|
|
currentOperation: 7,
|
|
wantsActiveSession: true,
|
|
isAppForeground: true,
|
|
taskIsCancelled: true
|
|
)
|
|
)
|
|
}
|
|
}
|