Files
MatchLiveTv/native/ios/MatchLiveTvTests/ScoreControllerTests.swift
Emiliano Frascaro 793cfaaaf1 Fix avanzamento quarto basket e regia senza cronometro.
Normalizza il periodo nel backend quando l'app invia "Q1" via cable, così advance_period aggiorna regia e overlay; rimuove i controlli cronometro dalla regia e rende più tollerante il decode iOS al resume sessione.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-20 16:15:44 +02:00

124 lines
4.8 KiB
Swift

import XCTest
@testable import MatchLiveTv
@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()),
sessionCable: SessionCableService()
)
controller.bind(sessionId: "session-1", initial: ScoreState())
controller.incrementHome()
XCTAssertEqual(controller.score.homePoints, 1)
}
func testApplyBoardActionOptimisticThenConfirm() async {
let api = MatchLiveAPI()
let controller = ScoreController(
scoreRepository: ScoreRepository(api: api),
sessionCable: SessionCableService()
)
controller.bind(sessionId: "session-1", initial: ScoreState())
// Senza backend: fallisce e ripristina ma l'ottimistico deve almeno scattare durante la chiamata.
// Verifichiamo solo che applyOptimistic funzioni via applyAction locale.
controller.applyAction("home_point")
XCTAssertEqual(controller.score.homePoints, 1)
}
func testAdvancePeriodOptimisticUpdatesQuarter() {
let controller = ScoreController(
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
sessionCable: SessionCableService()
)
var initial = ScoreState()
initial.boardType = "basket"
initial.period = 1
initial.periodLabel = "Q1"
controller.bind(sessionId: "session-1", initial: initial)
controller.applyAction("advance_period")
XCTAssertEqual(controller.score.period, 2)
XCTAssertEqual(controller.score.periodLabel, "Q2")
XCTAssertFalse(controller.score.clockRunning)
}
func testProgressKeyChangesWhenPeriodAdvances() {
var q1 = ScoreState(boardType: "basket", period: 1, periodLabel: "Q1", clockSecs: 600)
var q2 = ScoreState(boardType: "basket", period: 2, periodLabel: "Q2", clockSecs: 600)
q1.homePoints = 10
q1.awayPoints = 8
q2.homePoints = 10
q2.awayPoints = 8
XCTAssertGreaterThan(q2.progressKey(), q1.progressKey())
}
func testCableRemoteCancelsStaleLocalSync() {
let controller = ScoreController(
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
sessionCable: SessionCableService()
)
var local = ScoreState(boardType: "basket", period: 1, periodLabel: "Q1")
local.homePoints = 5
local.awayPoints = 4
controller.bind(sessionId: "session-1", initial: local)
controller.applyAction("home_point")
var remote = ScoreState(boardType: "basket", period: 1, periodLabel: "Q1")
remote.homePoints = 6
remote.awayPoints = 7
controller.applyRemote(remote, source: .cable)
XCTAssertEqual(controller.score.homePoints, 6)
XCTAssertEqual(controller.score.awayPoints, 7)
}
func testCableAdvancePeriodUpdatesOverlayState() {
let controller = ScoreController(
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
sessionCable: SessionCableService()
)
var local = ScoreState(boardType: "basket", period: 1, periodLabel: "Q1")
local.homePoints = 0
local.awayPoints = 4
controller.bind(sessionId: "session-1", initial: local)
var remote = ScoreState(boardType: "basket", period: 2, periodLabel: "Q2")
remote.homePoints = 0
remote.awayPoints = 4
controller.applyRemote(remote, source: .cable)
XCTAssertEqual(controller.score.periodLabel, "Q2")
XCTAssertEqual(controller.score.period, 2)
}
}