1
0
mirror of https://github.com/jcwimer/wrestlingApp synced 2026-04-11 16:01:56 +00:00
Files
wrestlingdev.com/test/javascript/match_state/scoreboard_presenters.test.js

228 lines
6.5 KiB
JavaScript

import { describe, expect, it } from "vitest"
import { getMatchStateConfig } from "match-state-config"
import { buildInitialState } from "match-state-engine"
import {
boardColors,
buildRunningTimerSnapshot,
emptyBoardViewModel,
currentClockText,
detectRecentlyStoppedTimer,
mainClockRunning,
nextTimerBannerState,
participantDisplayLabel,
participantForColor,
populatedBoardViewModel,
timerBannerRenderState,
timerBannerViewModel,
timerIndicatorLabel
} from "match-state-scoreboard-presenters"
describe("match state scoreboard presenters", () => {
it("maps colors to participants and labels", () => {
const state = {
assignment: { w1: "red", w2: "green" },
metadata: { w1Name: "Alpha", w2Name: "Bravo" }
}
expect(participantForColor(state, "red")).toBe("w1")
expect(participantForColor(state, "green")).toBe("w2")
expect(participantDisplayLabel(state, "w1")).toBe("Red Alpha")
expect(participantDisplayLabel(state, "w2")).toBe("Green Bravo")
})
it("formats the current clock from running phase state", () => {
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
const state = buildInitialState(config)
state.phaseIndex = 0
state.clocksByPhase.period_1.running = true
state.clocksByPhase.period_1.startedAt = 1_000
state.clocksByPhase.period_1.remainingSeconds = 120
expect(currentClockText(config, state, (seconds) => `F-${seconds}`, 11_000)).toBe("F-110")
expect(mainClockRunning(config, state)).toBe(true)
})
it("builds timer indicator and banner view models from running timers", () => {
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
const state = buildInitialState(config)
state.metadata = { w1Name: "Alpha", w2Name: "Bravo" }
state.timers.w1.blood.running = true
state.timers.w1.blood.startedAt = 1_000
state.timers.w1.blood.remainingSeconds = 300
expect(timerIndicatorLabel(config, state, "w1", (seconds) => `F-${seconds}`, 21_000)).toBe("Blood: F-20")
const banner = timerBannerViewModel(config, state, { participantKey: "w1", timerKey: "blood", expiresAt: null }, (seconds) => `F-${seconds}`, 21_000)
expect(banner).toEqual({
color: "green",
label: "Green Alpha Blood Running",
clockText: "F-20"
})
})
it("detects recently stopped timers from the snapshot", () => {
const state = {
timers: {
w1: { blood: { running: false } },
w2: { injury: { running: true } }
}
}
const snapshot = {
"w1:blood": true,
"w2:injury": true
}
expect(detectRecentlyStoppedTimer(state, snapshot)).toEqual({ participantKey: "w1", timerKey: "blood" })
expect(buildRunningTimerSnapshot(state)).toEqual({
"w1:blood": false,
"w2:injury": true
})
})
it("builds populated and empty board view models", () => {
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
const state = buildInitialState(config)
state.metadata = {
w1Name: "Alpha",
w2Name: "Bravo",
w1School: "School A",
w2School: "School B",
weightLabel: "106"
}
state.participantScores = { w1: 4, w2: 1 }
state.assignment = { w1: "green", w2: "red" }
const populated = populatedBoardViewModel(
config,
state,
{ w1_stat: "T3", w2_stat: "E1" },
1001,
(seconds) => `F-${seconds}`
)
expect(populated).toMatchObject({
isEmpty: false,
redName: "Bravo",
redSchool: "School B",
redScore: "1",
greenName: "Alpha",
greenSchool: "School A",
greenScore: "4",
weightLabel: "Weight 106",
boutLabel: "Bout 1001",
redStats: "E1",
greenStats: "T3"
})
expect(emptyBoardViewModel(1002, "Last result")).toEqual({
isEmpty: true,
redName: "NO MATCH",
redSchool: "",
redScore: "0",
redTimerIndicator: "",
greenName: "NO MATCH",
greenSchool: "",
greenScore: "0",
greenTimerIndicator: "",
clockText: "-",
phaseLabel: "No Match",
weightLabel: "Weight -",
boutLabel: "Bout 1002",
redStats: "",
greenStats: "",
lastMatchResult: "Last result"
})
})
it("builds next timer banner state for running and recently stopped timers", () => {
const runningState = {
timers: {
w1: { blood: { running: true } },
w2: {}
}
}
expect(nextTimerBannerState(runningState, {})).toEqual({
timerBannerState: {
participantKey: "w1",
timerKey: "blood",
expiresAt: null
},
previousTimerSnapshot: {
"w1:blood": true
}
})
const stoppedState = {
timers: {
w1: { blood: { running: false } },
w2: {}
}
}
const stoppedResult = nextTimerBannerState(stoppedState, { "w1:blood": true }, 5_000)
expect(stoppedResult).toEqual({
timerBannerState: {
participantKey: "w1",
timerKey: "blood",
expiresAt: 15_000
},
previousTimerSnapshot: {
"w1:blood": false
}
})
})
it("builds board colors and timer banner render decisions", () => {
expect(boardColors(true)).toEqual({
red: "#000",
center: "#000",
green: "#000"
})
expect(boardColors(false)).toEqual({
red: "#c91f1f",
center: "#050505",
green: "#1cab2d"
})
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
const state = buildInitialState(config)
state.metadata = { w1Name: "Alpha", w2Name: "Bravo" }
state.timers.w1.blood.running = true
state.timers.w1.blood.startedAt = 1_000
state.timers.w1.blood.remainingSeconds = 300
expect(timerBannerRenderState(
config,
state,
{ participantKey: "w1", timerKey: "blood", expiresAt: null },
(seconds) => `F-${seconds}`,
11_000
)).toEqual({
timerBannerState: { participantKey: "w1", timerKey: "blood", expiresAt: null },
visible: true,
viewModel: {
color: "green",
label: "Green Alpha Blood Running",
clockText: "F-10"
}
})
state.clocksByPhase.period_1.running = true
state.clocksByPhase.period_1.startedAt = 1_000
state.clocksByPhase.period_1.remainingSeconds = 120
expect(timerBannerRenderState(
config,
state,
{ participantKey: "w1", timerKey: "blood", expiresAt: 20_000 },
(seconds) => `F-${seconds}`,
11_000
)).toEqual({
timerBannerState: null,
visible: false,
viewModel: null
})
})
})