applyRemote ignorava aggiornamenti Action Cable con progressKey più basso, quindi il meno in regia non aggiornava il tabellone sullo stream. Co-authored-by: Cursor <cursoragent@cursor.com>
162 lines
6.2 KiB
Swift
162 lines
6.2 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)
|
|
}
|
|
|
|
func testCableUndoFromRegiaAppliesLowerScore() {
|
|
let controller = ScoreController(
|
|
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
|
|
sessionCable: SessionCableService()
|
|
)
|
|
var local = ScoreState(boardType: "basket", period: 2, periodLabel: "Q2")
|
|
local.homePoints = 6
|
|
local.awayPoints = 4
|
|
controller.bind(sessionId: "session-1", initial: local)
|
|
|
|
var remote = ScoreState(boardType: "basket", period: 2, periodLabel: "Q2")
|
|
remote.homePoints = 5
|
|
remote.awayPoints = 4
|
|
controller.applyRemote(remote, source: .cable)
|
|
|
|
XCTAssertEqual(controller.score.homePoints, 5)
|
|
XCTAssertEqual(controller.score.awayPoints, 4)
|
|
}
|
|
|
|
func testPollingUndoFromRegiaAppliesWhenNotSuppressing() {
|
|
let controller = ScoreController(
|
|
scoreRepository: ScoreRepository(api: MatchLiveAPI()),
|
|
sessionCable: SessionCableService()
|
|
)
|
|
var local = ScoreState(boardType: "basket")
|
|
local.homePoints = 6
|
|
local.awayPoints = 4
|
|
controller.bind(sessionId: "session-1", initial: local)
|
|
|
|
var remote = ScoreState(boardType: "basket")
|
|
remote.homePoints = 5
|
|
remote.awayPoints = 3
|
|
controller.applyRemote(remote, source: .polling)
|
|
|
|
XCTAssertEqual(controller.score.homePoints, 5)
|
|
XCTAssertEqual(controller.score.awayPoints, 3)
|
|
}
|
|
}
|