Stabilizza diretta iOS e aggiunge test simulatore pre-release.
Corregge lifecycle RTMP/preview tra partite, reset tabellone, orientamento con debounce, condivisione su iPad e script test_ios_simulator per CI locale. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import AVFoundation
|
||||
import XCTest
|
||||
@testable import MatchLiveTv
|
||||
|
||||
final class BroadcastOrientationPolicyTests: XCTestCase {
|
||||
func testAppliesFirstLandscapeOrientation() {
|
||||
XCTAssertTrue(
|
||||
BroadcastOrientationPolicy.shouldApplyMixerOrientation(
|
||||
new: .landscapeRight,
|
||||
previous: nil,
|
||||
landscapeLocked: true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func testSkipsDuplicateLandscapeOrientation() {
|
||||
XCTAssertFalse(
|
||||
BroadcastOrientationPolicy.shouldApplyMixerOrientation(
|
||||
new: .landscapeRight,
|
||||
previous: .landscapeRight,
|
||||
landscapeLocked: true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func testAppliesLandscapeFlip() {
|
||||
XCTAssertTrue(
|
||||
BroadcastOrientationPolicy.shouldApplyMixerOrientation(
|
||||
new: .landscapeLeft,
|
||||
previous: .landscapeRight,
|
||||
landscapeLocked: true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func testIgnoresPortraitWhenLandscapeLocked() {
|
||||
XCTAssertFalse(
|
||||
BroadcastOrientationPolicy.isApplicableForBroadcast(.portrait, landscapeLocked: true)
|
||||
)
|
||||
XCTAssertFalse(
|
||||
BroadcastOrientationPolicy.shouldApplyMixerOrientation(
|
||||
new: .portrait,
|
||||
previous: .landscapeRight,
|
||||
landscapeLocked: true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func testAllowsPortraitWhenNotLandscapeLocked() {
|
||||
XCTAssertTrue(
|
||||
BroadcastOrientationPolicy.isApplicableForBroadcast(.portrait, landscapeLocked: false)
|
||||
)
|
||||
}
|
||||
|
||||
func testDebounceAndSuppressWindowsArePositive() {
|
||||
XCTAssertGreaterThan(BroadcastOrientationPolicy.debounceNanoseconds, 0)
|
||||
XCTAssertGreaterThan(BroadcastOrientationPolicy.suppressDisconnectSeconds, 0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import XCTest
|
||||
@testable import MatchLiveTv
|
||||
|
||||
final class LiveBroadcastCoordinatorTests: XCTestCase {
|
||||
func testShouldStopPreviousSessionFalseOnFirstLaunch() {
|
||||
XCTAssertFalse(LiveBroadcastCoordinator.shouldStopPreviousSession(active: nil, incoming: "session-a"))
|
||||
}
|
||||
|
||||
func testShouldStopPreviousSessionFalseForSameSession() {
|
||||
XCTAssertFalse(LiveBroadcastCoordinator.shouldStopPreviousSession(active: "session-a", incoming: "session-a"))
|
||||
}
|
||||
|
||||
func testShouldStopPreviousSessionTrueWhenSwitching() {
|
||||
XCTAssertTrue(LiveBroadcastCoordinator.shouldStopPreviousSession(active: "session-a", incoming: "session-b"))
|
||||
}
|
||||
}
|
||||
@@ -33,4 +33,36 @@ final class ScoreActionDecodeTests: XCTestCase {
|
||||
XCTAssertEqual(score.homePoints, 1)
|
||||
XCTAssertEqual(score.boardType, "volley")
|
||||
}
|
||||
|
||||
func testDecodesCloseSetResponseWithPartials() throws {
|
||||
let json = """
|
||||
{
|
||||
"id": "821ddb81-9dc2-466a-9ad5-2555e78f4653",
|
||||
"match_id": "e887ce1d-10ee-4680-8323-79bb8f11e0aa",
|
||||
"status": "live",
|
||||
"platform": "matchlivetv",
|
||||
"score": {
|
||||
"type": "score_update",
|
||||
"board_type": "volley",
|
||||
"home_sets": 1,
|
||||
"away_sets": 0,
|
||||
"home_points": 0,
|
||||
"away_points": 0,
|
||||
"current_set": 2,
|
||||
"set_partials": [{ "set": 1, "home": 25, "away": 18 }],
|
||||
"timeout_home": false,
|
||||
"timeout_away": false
|
||||
},
|
||||
"set_won": true,
|
||||
"match_won": false,
|
||||
"winner": "home"
|
||||
}
|
||||
""".data(using: .utf8)!
|
||||
let dto = try ApiInstant.decoder.decode(StreamSessionDto.self, from: json)
|
||||
let score = try XCTUnwrap(dto.score?.toDomain())
|
||||
XCTAssertEqual(score.currentSet, 2)
|
||||
XCTAssertEqual(score.setPartials.count, 1)
|
||||
XCTAssertEqual(score.setPartials[0].home, 25)
|
||||
XCTAssertEqual(score.setPartials[0].away, 18)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,36 @@ import XCTest
|
||||
|
||||
@MainActor
|
||||
final class ScoreControllerTests: XCTestCase {
|
||||
func testBindNewSessionResetsScoreToZero() {
|
||||
let controller = ScoreController(
|
||||
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
|
||||
sessionCable: SessionCableService()
|
||||
)
|
||||
var previous = ScoreState()
|
||||
previous.homePoints = 3
|
||||
previous.awayPoints = 3
|
||||
controller.bind(sessionId: "session-1", initial: previous)
|
||||
XCTAssertEqual(controller.score.homePoints, 3)
|
||||
|
||||
controller.bind(sessionId: "session-2", initial: nil)
|
||||
XCTAssertEqual(controller.score.homePoints, 0)
|
||||
XCTAssertEqual(controller.score.awayPoints, 0)
|
||||
}
|
||||
|
||||
func testBindNewSessionUsesServerInitialState() {
|
||||
let controller = ScoreController(
|
||||
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
|
||||
sessionCable: SessionCableService()
|
||||
)
|
||||
controller.bind(sessionId: "session-1", initial: ScoreState(homePoints: 2, awayPoints: 1))
|
||||
var fresh = ScoreState()
|
||||
fresh.homePoints = 1
|
||||
fresh.awayPoints = 0
|
||||
controller.bind(sessionId: "session-2", initial: fresh)
|
||||
XCTAssertEqual(controller.score.homePoints, 1)
|
||||
XCTAssertEqual(controller.score.awayPoints, 0)
|
||||
}
|
||||
|
||||
func testIncrementHomeUpdatesPublishedScore() {
|
||||
let controller = ScoreController(
|
||||
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
|
||||
|
||||
Reference in New Issue
Block a user